文章目录
-
- 前言
- 一、HOST碰撞是什么
-
- [1. HOST碰撞的核心原理](#1. HOST碰撞的核心原理)
- [2. Nginx配置错误](#2. Nginx配置错误)
- 二、测试工具
- 三、实操步骤
- 四、手动验证:用curl命令确认
- 五、防御方案
-
- [1. 严格校验Host头,只允许合法域名](#1. 严格校验Host头,只允许合法域名)
- [2. 及时清理残留配置](#2. 及时清理残留配置)
- [3. 内网服务添加访问控制,即使Host碰撞成功也无法访问](#3. 内网服务添加访问控制,即使Host碰撞成功也无法访问)
- [4. 禁止通过IP直接访问Nginx,仅允许域名访问](#4. 禁止通过IP直接访问Nginx,仅允许域名访问)
- 六、总结
前言
在渗透测试中,Nginx作为主流的反向代理和Web服务器,其域名与IP的映射配置错误是高频的安全隐患,而HOST碰撞技术正是挖掘这类问题的核心手段。很多小白会疑惑,明明能ping通服务器IP,却无法访问站点,或是部分内网服务藏在Nginx后无法直接探测,这背后大概率是Nginx的host配置规则导致,而HOST碰撞就能帮我们突破这种访问限制,找到配置漏洞。本文从基础原理讲起,全程聚焦实操,教你用两款工具快速检测Nginx是否存在映射配置错误。
一、HOST碰撞是什么
1. HOST碰撞的核心原理
简单说,HTTP请求里有个Host请求头 ,作用是告诉服务器"我要访问你身上的哪个域名站点"。因为一台服务器(一个公网IP)能通过Nginx托管多个域名的站点(虚拟主机),Nginx全靠Host头里的域名,来把请求转发到对应的后台服务。
HOST碰撞,就是我们手动修改请求里的Host头,用不同的域名和服务器IP做"配对测试",看是否能匹配到Nginx中配置但未对外公开的站点,或是因配置疏漏暴露的内网服务。
2. Nginx配置错误
Nginx通过server_name指令绑定域名和服务,以下两种配置错误是渗透中最易遇到的:
- 配置残留 :域名服务已下线、DNS解析已删除,但Nginx里的
server_name和转发规则没清理,这些"废弃域名"能通过HOST碰撞访问到后台服务; - 未限制Host头 :Nginx未对Host头做校验,或默认虚拟主机(
default_server)配置宽松,攻击者随便构造域名就能匹配到未授权的内网服务; - IP直访禁止但Host校验缺失:Nginx配置了"禁止直接通过IP访问站点",但只要传对正确的Host头,就能绕过限制,甚至访问到内网的测试服务、管理后台。
举个简单的Nginx错误配置示例:
nginx
# 配置了test.com的转发,但未限制其他Host头,且未清理旧的dev.test.com配置
server {
listen 80;
server_name test.com dev.test.com; # dev.test.com已下线但配置残留
location / {
proxy_pass http://127.0.0.1:8080; # 内网8080的服务,外网本应无法访问
}
}
此时直接访问服务器IPhttp://x.x.x.x会被拒绝,但用HOST碰撞给请求头加Host: dev.test.com,就能访问到内网8080的服务------这就是配置错误带来的漏洞。
二、测试工具
两款工具都是为HOST碰撞量身打造,Hosts_scan 轻量易上手,Python环境直接运行;hostscan基于Go开发,速度更快、支持多线程和批量扫描,适合大规模测试,二者互补,覆盖所有实操场景。
工具1:Hosts_scan
- 项目地址:https://github.com/fofapro/Hosts_scan
- 核心优势:Python编写,跨平台,配置简单,适合新手单台/小批量测试,支持多线程版本(带进度条)。
- 运行环境:Python2/Python3均可,无需复杂依赖。
工具2:hostscan
- 项目地址:https://github.com/cckuailong/hostscan
- 核心优势:Go语言编译,速度快,支持IP段扫描、自定义端口、过滤响应状态码,适合大规模批量测试,无环境依赖(直接下载编译好的二进制文件即可运行)。
- 支持平台:Windows、Linux、Mac,release页可直接下载对应系统的包。
三、实操步骤
前置准备:收集2类核心信息(缺一不可)
HOST碰撞的本质是域名和IP的配对测试,所以先收集目标的两类信息,放到本地文件中,方便工具读取:
- 目标IP列表 :Nginx服务器的公网IP、疑似的内网IP(如192.168/10/172段),放到
ip.txt,一行一个IP(可带端口,如x.x.x.x:8080); - 域名/子域名列表 :目标的主域名、子域名、废弃域名、疑似内网域名(如admin.test.com、dev.test.com),放到
hosts.txt,一行一个域名。
信息收集小技巧:
- IP:用nmap扫描目标端口(如80、443、8080),找到开放HTTP/HTTPS的Nginx服务器IP;
- 域名:用OneForAll、Layer子域名挖掘机等工具,收集目标的所有子域名,哪怕是已失效的也保留。
场景1:用Hosts_scan做快速测试
步骤1:下载工具
bash
# 克隆项目到本地
git clone https://github.com/fofapro/Hosts_scan.git
# 进入工具目录
cd Hosts_scan
步骤2:准备目标文件
在工具目录下,新建/编辑ip.txt和hosts.txt,填入前置收集的IP和域名,格式如下:
-
ip.txt:
192.168.1.100:80 1.1.1.1:8080 -
hosts.txt:
test.com dev.test.com admin.test.com
步骤3:运行扫描
bash
# 基础版(单线程)
python IP_hosts_scan.py
# 多线程版(推荐,速度更快,有进度条)
python IP_hosts_scan_multithreading.py
步骤4:解读结果
工具会自动遍历ip.txt和hosts.txt的所有组合,发起请求并返回结果,重点看这2种情况,代表Nginx存在配置错误:
- 显示访问成功+有页面标题/内容(如"后台管理系统""Welcome to nginx!"):说明该域名和IP匹配到了Nginx中配置的服务,若该服务本应对外隐藏,就是配置漏洞;
- 部分废弃域名(如dev.test.com)返回正常页面:说明Nginx配置残留,未清理下线域名的转发规则,属于典型的配置错误。
场景2:用hostscan做大规模批量扫描
该工具无需安装Go环境,直接下载编译好的二进制文件即可,以下以Linux系统为例,Windows/Mac操作同理。
步骤1:下载工具
进入项目release页(https://github.com/cckuailong/hostscan/releases),下载对应系统的包,如Linux_x64,解压后得到`hostscan`可执行文件。
步骤2:赋予执行权限
bash
chmod +x hostscan
步骤3:核心扫描命令
场景3.1:单域名+单IP测试
检测单个域名和单个Nginx IP是否匹配,适合快速验证配置错误:
bash
./hostscan -d test.com -i 192.168.1.100:80
- 参数说明:
-d指定单个域名,-i指定单个Nginx IP(可带端口)。
场景3.2:批量域名+批量IP测试
用本地的域名文件和IP文件做批量碰撞,结果输出到指定文件,方便后续分析:
bash
./hostscan -D ./hosts.txt -I ./ip.txt -O ./nginx_scan_result.txt -T 10 -t 5 -U
- 核心参数说明:
-D:指定域名文件路径;-I:指定IP文件路径;-O:指定结果输出文件;-T:设置线程数(网络好可调大,如10);-t:设置请求超时时间(单位:秒);-U:使用随机User-Agent,避免被Nginx拦截。
场景3.3:IP段+自定义端口扫描
扫描整个IP段(如192.168.1.0/24),并指定Nginx常用端口(80、443、8080),适合挖掘内网Nginx的配置错误:
bash
./hostscan -D ./hosts.txt -I 192.168.1.0/24 -p 80,443,8080 -F 200,302 -O ./inner_nginx_result.txt
- 新增参数说明:
-p:自定义扫描端口,多个端口用逗号分隔,端口段用-(如8000-8009);-F:过滤响应状态码,只保留200(成功)、302(跳转)的结果,减少无效信息。
步骤4:解读结果
运行后工具会实时输出结果,重点关注[NOTI]标识的内容,示例:
[NOTI] [15:03:52] Uri: http://192.168.1.100:80, Host: dev.test.com --> 后台管理系统
以上结果说明:dev.test.com和192.168.1.100:80匹配成功,且能访问到"后台管理系统"------若该域名已下线、该IP是内网IP,就证明Nginx存在配置残留/未限制内网服务的错误。
若出现400 Bad Request,则说明该域名和IP未匹配到Nginx的有效配置,无漏洞。
四、手动验证:用curl命令确认
若工具扫描到疑似漏洞,可用curl命令手动验证,避免工具误判,这也是渗透测试中最严谨的步骤,一行命令即可:
bash
# 核心命令:指定Host头,访问目标IP
curl -H "Host: dev.test.com" http://192.168.1.100:80
- 若返回正常的页面内容(如HTML代码、后台信息):确认Nginx配置错误,漏洞存在;
- 若返回400/403/500错误:无漏洞,工具结果为误判。
进阶:强制解析域名到目标IP
若目标做了DNS拦截,可在curl中指定域名解析,确保请求发往目标IP:
bash
curl --resolve dev.test.com:80:192.168.1.100 http://dev.test.com
- 含义:访问dev.test.com时,强制将其解析到192.168.1.100:80,再发起请求。
五、防御方案
可落地的防御方案,核心是限制Host头+清理配置+拦截未授权访问,以下是Nginx端的具体配置措施,直接可用:
1. 严格校验Host头,只允许合法域名
在Nginx配置中,明确指定允许的server_name,并设置默认虚拟主机返回400错误,拒绝所有非法Host头:
nginx
# 默认虚拟主机,匹配所有非法Host头,返回400
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _; # 匹配所有未指定的Host头
return 400; # 直接拒绝,无任何响应内容
}
# 合法域名的配置,仅允许test.com和www.test.com
server {
listen 80;
listen 443 ssl;
server_name test.com www.test.com;
# 后续的转发/站点配置
location / {
proxy_pass http://127.0.0.1:8080;
}
}
2. 及时清理残留配置
域名下线、服务迁移时,必须同步删除Nginx中对应的server_name和转发规则,并重启Nginx生效:
bash
# 重启Nginx命令(Linux)
systemctl restart nginx
3. 内网服务添加访问控制,即使Host碰撞成功也无法访问
对Nginx转发的内网服务(如127.0.0.1:8080),添加IP白名单,仅允许内网IP访问,即使攻击者通过HOST碰撞匹配成功,也无法突破:
nginx
server {
listen 80;
server_name test.com;
location / {
# 仅允许内网192.168.1.0/24段访问
allow 192.168.1.0/24;
deny all;
proxy_pass http://127.0.0.1:8080;
}
}
4. 禁止通过IP直接访问Nginx,仅允许域名访问
nginx
server {
listen 80;
server_name _;
if ($host ~* ^\d+\.\d+\.\d+\.\d+$) { # 匹配IP格式的Host头
return 403;
}
}
六、总结
HOST碰撞是渗透测试中检测Nginx映射配置错误的"必备技能",核心不是复杂的原理,而是精准的信息收集+合适的工具选择+严谨的手动验证。先从Hosts_scan开始,熟悉后用hostscan做大规模扫描,再配合curl命令兜底,就能快速找到Nginx的配置残留、未限制Host头、内网服务暴露等问题。
而防御的核心,本质是拒绝信任任意的Host头请求,Nginx端做到"合法域名白名单+默认主机拒绝+内网服务IP限制+及时清理配置",就能从根源上避免被HOST碰撞利用。
本文是「Web安全基础」系列内容,点击专栏导航查看全部系列内容。