Host_Target

Host_Target
Att@ckxu问题
burp中的Repeater模块中,右上角有一个target,这个是表示请求的host和port,但是在http请求体中也有host,如果这两个不同的话,比如我一个对aaa.com:8000正常的请求,在http请求体的host:aaa.com:8000,并且target模块也是host:aaa.com,port:8000,但是当我修改http请求体中的host为bbb.com:8000在进行重放操作,不更改target,该请求请求的目标还是aaa.com;就相当于,一个http请求,我更改host,最后还是按照更改前进行的发送数据
但是host的介绍:HTTP Host 请求标头指定了接收请求的服务器的主机名和端口号。为什么我在更改host之后还是按照之前的请求呢
案例:
信呼OA的nickName注入通过修改host来绕过鉴权,形成前台注入
Host头注入
分析
- Target 决定了 TCP 连接发到哪台机器
- Repeater 右上角的 Target(host:port),表示的是 真正建立 TCP 连接的 IP/端口。
- 也就是说,Burp 会用
aaa.com:8000
做 DNS 解析,然后发起 TCP 连接。 - 这个值如果不改,底层连接就始终打到
aaa.com:8000
。
- Host 头部只是在 HTTP 协议层传递给服务器的一个字符串
- HTTP 协议中
Host
头部告诉服务器:
“我请求的是bbb.com:8000
这个虚拟主机的资源”。 - 但这只是 HTTP 报文内容,服务器怎么处理取决于配置(比如 Apache/Nginx 的虚拟主机根据 Host 做路由)。
- 它不会影响 TCP 连接真正打到哪台机器。
- 你的实验现象解释
- 你改了 HTTP 请求体里的
Host: bbb.com:8000
,但是 Repeater 的 Target 还是aaa.com:8000
。 - 所以:
- TCP 连接依旧打到
aaa.com:8000
; - 请求报文发给
aaa.com
服务器时,Host
头变成了bbb.com:8000
; - 如果
aaa.com
服务器没有配置bbb.com:8000
的虚拟主机,就会返回 404 或默认站点。
- TCP 连接依旧打到
这就是为什么即使改了 Host,Burp 还是“按之前的目标”去发送。
- 一个小比喻
- Target = 我拿快递送到哪栋楼(真实物理地址)
- Host 头 = 快递包裹上写的收件人名字/公司名
- 你可以把“收件人”随便改掉,但快递还是送到那栋楼。至于门口保安要不要收,就看楼里的规则了。
总结:
- Target 控制实际 TCP 连接目标(决定发到哪里)。
- Host 头只是报文内容(服务器内部逻辑是否识别由它决定)。
- 你遇到的情况是正常的,想真正把请求发到
bbb.com:8000
,必须改 Target,而不仅仅是改 Host。
+-----------------------------+ |
其他工具实现修改host
用 curl 演示(最直观)
- 连接到
aaa.com:8000
,但把 Host 改为bbb.com:8000
:
curl -v -H "Host: bbb.com:8000" http://aaa.com:8000/some/path |
解释:curl 会 DNS 解析 aaa.com
(或用 /etc/hosts),建立 TCP 到 aaa.com:8000
,但发出的 HTTP 报文里 Host:
是 bbb.com:8000
。
- 直接用 IP(绕过 DNS):
curl -v -H "Host: bbb.com:8000" http://1.2.3.4:8000/some/path |
说明:1.2.3.4 是 aaa.com
的 IP,Host 仍为 bbb.com:8000
。
Python:requests(HTTP)——最常用、简单
适用于 HTTP(非 TLS)请求,指定连接目标为 IP 或域名,然后单独传 Host 头。
import requests |
注意:requests 只决定 HTTP 报文里的 Host 值,不影响 TCP 目标(由 URL 决定)。
Python:http.client(更底层,适合展示原始请求)
import http.client |
Python:socket(最底层,能完全自定义原始报文)
import socket |
这个方式和 Burp 的工作原理最接近:你自己建立 TCP 连接(Target),把你构造的 HTTP 报文写过去(包含任意 Host)。
HTTPS 的特殊性(很重要)
- 对 HTTPS(TLS)站点,仅修改 HTTP Host 头 通常不足够:
- TLS 握手阶段会出现 SNI (Server Name Indication),客户端在 TLS 握手里会把想访问的主机名(比如
bbb.com
)放在 SNI;服务器据此选择证书/虚拟主机。 - 如果你建立 TLS 连接到
1.2.3.4
(Target),但 SNI 仍然是1.2.3.4
或其他,服务器可能返回与bbb.com
不匹配的证书,导致 TLS 握手失败或证书警告。
- TLS 握手阶段会出现 SNI (Server Name Indication),客户端在 TLS 握手里会把想访问的主机名(比如
- 在 Python 的
requests
中,如果你用requests.get("https://1.2.3.4", headers={"Host":"bbb.com"})
:- requests 会把 SNI 默认为 URL 里的 host(即
1.2.3.4
),不是bbb.com
,所以 SNI 与 Host 可能不一致。 - 解决办法(较复杂):在建立 TLS 时把
server_hostname
设为bbb.com
(例如手动用ssl
+socket
),或使用urllib3
/自定义 Adapter 指定server_hostname
。另外通常需要忽略证书校验(verify=False
)或使用正确证书/信任链。
- requests 会把 SNI 默认为 URL 里的 host(即
- 简单示例(绕过校验,仅供测试环境用):
import ssl, socket |
总结:HTTPS 需要同时处理 TCP 目标(Target)、Host 头和 TLS 的 SNI 与证书,少一步都会导致失败。
发送http请求到目标服务器,都要经过哪些步骤
发送一次 HTTP/HTTPS 请求,典型流程是:应用层准备报文 → 域名解析(DNS) → 建立传输层连接(TCP 三次握手)→(如果 HTTPS:TLS 握手,包含 SNI/ALPN/证书验证)→ 发送 HTTP 报文(包含 Host)→ 服务器处理并回复 → 客户端接收并可能复用/关闭连接。
详细步骤(HTTP,明文)
- 应用层准备请求
- 客户端构造请求行、请求头(包括
Host
)、请求体等(例如GET /path HTTP/1.1
+Host: bbb.com
)。 - 这里可以伪造
Host
字段,但这只是报文内容,不决定 TCP 去向。
- 客户端构造请求行、请求头(包括
- 域名解析(DNS)(如果 URL 使用域名而不是 IP)
- 客户端查询本地 DNS 缓存 → /etc/hosts → 递归/缓存 DNS 服务器,最终得到目标 IP(可能有多个 A/AAAA)。
- 如果你在脚本里直接用了 IP(或已在 hosts 映射),则跳过网络 DNS 查询。
- 路由选择 & 本地网络
- 操作系统决定出站接口、默认路由、可能经过 NAT、代理设置(HTTP_PROXY / system proxy)或 VPN。
- 若系统/程序配置了 HTTP 代理(或你用了 Burp 代理),客户端会把请求发到代理而非最终主机。代理有两种:HTTP(明文)代理或 CONNECT 隧道(用于 HTTPS)。
- 建立 TCP 连接(Target)
- 客户端向目标 IP:port 发起三次握手(SYN → SYN/ACK → ACK)。这一步决定了“数据包物理送到哪台机器/端口” —— 等同于 Burp Repeater 的 Target。
- 如果你用代理,三次握手在代理与客户端之间,代理再与目标服务器建立连接(或代理直接把你的报文再发出)。
- 发送 HTTP 报文
- TCP 连接建立后,客户端把构造好的 HTTP 报文(包含
Host
)写入连接并发送。 - 服务器收到后,根据
Host
(虚拟主机)选择哪个站点配置/处理该请求。
- TCP 连接建立后,客户端把构造好的 HTTP 报文(包含
- 服务器处理并返回响应
- 应用层处理请求,返回状态行、响应头、响应体。
- 服务器可能返回重定向、404、默认站点内容、或基于
Host
的特定站点内容。
- 连接复用或关闭
- 若
Connection: keep-alive
(HTTP/1.1 默认),TCP 连接可复用;否则会在请求/响应后关闭(FIN 四次挥手)。 - 客户端或服务器也可能在超时后关闭。
- 若
HTTPS(在上面基础上加的关键步骤)
在 TCP 三次握手成功之后,在真正发送 HTTP 报文前还要做 TLS(SSL)握手:
4.5 TLS 握手(客户端 Hello)
- 客户端发
ClientHello
,里面可能包含:- SNI(Server Name Indication):客户端告诉服务器“我想访问的主机名是什么”(例如
bbb.com
)。 - ALPN:协商协议(http/1.1 或 h2)。
- SNI(Server Name Indication):客户端告诉服务器“我想访问的主机名是什么”(例如
- SNI 很重要:服务器据此选择哪个证书/虚拟主机配置来响应握手。
4.6 服务器证书与验证
- 服务器返回证书链,客户端校验证书(域名匹配、CA、吊销等)。
- 若校验失败(证书不匹配 SNI/Host),客户端会报错(浏览器警告、requests 抛异常,除非关闭校验)。
4.7 完成握手并建立加密通道
- 双方生成会话密钥,之后的 HTTP 报文在 TLS 隧道内传输。
- 最终发送的 HTTP 报文依然包含
Host
,但这已被加密在 TLS 隧道内。
小结:对于 HTTPS,要让服务器“认为”是访问 bbb.com,必须同时:
- 在 TLS 握手中用
server_hostname=b b b.com
(SNI);- HTTP 报文里
Host: bbb.com
;- 目标 TCP 连接仍由 Target(IP:port)决定。
客户端应用 本地OS/DNS 网络/路由 目标服务器 |
常见问题 / 陷阱(排障清单)
- 修改
Host
但不改 Target:请求仍打到原目标 IP(正常)。 - HTTPS 报文证书不匹配:因为 SNI 没设为你想要的主机名或证书与 Host 不匹配。
- 通过 IP 访问并设置 Host:若服务器的虚拟主机按 Host 路由,这种方法常用于测试;但 HTTPS 需处理 SNI 与证书。
- 系统/环境代理(HTTP_PROXY)会拦截请求:确认是否走了代理(Burp 也会)。
- CDN / 负载均衡器:实际到达的后端主机可能不是你期望的那台,且 CDN 可能会忽略/覆盖 Host,或基于 Host 路由到不同后端。
- ALPN/HTTP2:HTTP/2 支持多路复用,报文格式不同(头部压缩),但 Host/SNI 原理相同。