如何使用MITM_Intercept攔截和修改非HTTP協議的數據
關于MITM_Intercept
MITM_Intercept是一款功能強大的數據包編輯工具,MITM_Intercept可以通過Burp或其他具備SSL和TLS攔截功能的工具來攔截和修改非HTTP協議的數據包。該工具基于mitm_relay項目的理念實現,適用于客戶端安全評估領域的滲透測試人員和安全研究專家。
工具運行機制
首先,我們需要配置偵聽器的地址和端口。對于每個偵聽器,還需要配置一個目標(地址和端口)。從偵聽器接收到的每個數據都將打包到HTTP POST請求的Body中,其中的URL將包含“CLIENT_REQUEST”。從目標接收到的每個數據都將打包到HTTP POST請求的Body中,其中的URL將包含“SERVER_RESPONSE”。隨后,這些請求都將被發送到本地HTTP攔截服務器。
我們可以選擇配置HTTP代理,使用Burp Suite等工具作為HTTP攔截工具,并在那里查看消息。這樣一來,我們就可以使用Burp的各種擴展來手動修改數據包消息了。
修改數據包的另一種方法就是使用一個Python腳本,HTTP攔截服務器在接收消息時將運行該腳本。
發送到HTTP攔截服務器的消息Body將打印到shell。如果給出修改腳本,修改后將打印消息。在所有修改操作完成之后,攔截服務器還將作為HTTP響應Body進行回顯。
如需解密SSL/TLS通信,則需要向MITM_Intercept提供一個證書和一個密鑰,客戶端在啟動與偵聽器的握手時將使用該證書和密鑰。如果目標服務器需要特定的證書進行握手,則可以選擇提供指定的證書和密鑰。
下圖顯示的是該工具的工作流程:

工具要求
1、Python 3.9
2、requests庫:$ python -m pip install requests
工具下載
廣大研究人員可以使用下列命令將該項目源碼克隆至本地:
git clone https://github.com/cyberark/MITM_Intercept.git
工具使用
usage: mitm_intercept.py [-h] [-m] -l [u|t:]<interface>:<port> [[u|t:]<interface>:<port> ...] -t
[u|t:]<addr>:<port> [[u|t:]<addr>:<port> ...] [-lc <cert_path>]
[-lk <key_path>] [-tc <cert_path>] [-tk <key_path>] [-w <interface>:<port>]
[-p <addr>:<port>] [-s <script_path>] [--sni <server_name>]
[-tv <defualt|tls12|tls11|ssl3|tls1|ssl2>] [-ci <ciphers>]
mitm_intercept version 1.6
options:
-h, --help show this help message and exit
-m, --mix-connection Perform TCP relay without SSL handshake. If one of the relay sides starts an
SSL handshake, wrap the connection with SSL, and intercept the
communication. A listener certificate and private key must be provided.
-l [u|t:]<interface>:<port> [[u|t:]<interface>:<port> ...], --listen [u|t:]<interface>:<port> [[u|t:]<interface>:<port> ...]
Creates SSLInterceptServer listener that listens on the specified interface
and port. Can create multiple listeners with a space between the parameters.
Adding "u:" before the address will make the listener listen in UDP
protocol. TCP protocol is the default but adding "t:" for cleanliness is
possible. The number of listeners must match the number of targets. The i-th
listener will relay to the i-th target.
-t [u|t:]<addr>:<port> [[u|t:]<addr>:<port> ...], --target [u|t:]<addr>:<port> [[u|t:]<addr>:<port> ...]
Directs each SSLInterceptServer listener to forward the communication to a
target address and port. Can create multiple targets with a space between
the parameters. Adding "u:" before the address will make the target
communicate in UDP protocol.TCP protocol is the default but adding "t:" for
cleanliness is possible. The number of listeners must match the number of
targets. The i-th listener will relay to the i-th target.
-lc <cert_path>, --listener-cert <cert_path>
The certificate that the listener uses when a client contacts him. Can be a
self-sign certificate if the client will accept it.
-lk <key_path>, --listener-key <key_path>
The private key path for the listener certificate.
-tc <cert_path>, --target-cert <cert_path>
The certificate that used to create a connection with the target. Can be a
self-sign certificate if the target will accept it. Doesn't necessary if the
target doesn't require a specific certificate.
-tk <key_path>, --target-key <key_path>
The private key path for the target certificate.
-w <interface>:<port>, --webserver <interface>:<port>
Specifies the interface and the port the InterceptionServer webserver will
listens on. If omitted the default is 127.0.0.1:49999
-p <addr>:<port>, --proxy <addr>:<port>
Specifies the address and the port of a proxy between the InterceptionServer
webserver and the SSLInterceptServer. Can be configured so the communication
will go through a local proxy like Burp. If omitted, the communication will
be printed in the shell only.
-s <script_path>, --script <script_path>
A path to a script that the InterceptionServer webserver executes. Must
contain the function handle_request(message) that will run before sending it
to the target or handle_response(message) after receiving a message from the
target. Can be omitted if doesn't necessary.
--sni <server_name> If there is a need to change the server name in the SSL handshake with the
target. If omitted, it will be the server name from the handshake with the
listener.
-tv <defualt|tls12|tls11|ssl3|tls1|ssl2>, --tls-version <defualt|tls12|tls11|ssl3|tls1|ssl2>
If needed can be specified a specific TLS version.
-ci <ciphers>, --ciphers <ciphers>
Sets different ciphers than the python defaults for the TLS handshake. It
should be a string in the OpenSSL cipher list format
(https://www.openssl.org/docs/manmaster/man1/ciphers.html).
For dumping SSL (pre-)master secrets to a file, set the environment variable SSLKEYLOGFILE with a
file path. Useful for Wireshark.
通信數據需要被定向到偵聽器,以便攔截任意協議。這樣做的方式取決于客戶機的操作方式。有時它使用DNS地址,更改主機文件就足以解析偵聽器地址。如果地址是硬編碼的,則需要應用更具創造性的方法,通常涉及到對路由表進行一些修改。
修改腳本
我們可以通過-s選項來染HTTP攔截服務器運行一個Python腳本,但服務器接收到HTTP請求的時候便會運行這個腳本,腳本運行完成后HTTP攔截服務器便會回傳響應信息。
配置代理時(如Burp),請求的修改將在腳本運行之前進行,響應的修改將在腳本運行之后進行。
腳本中必須包含handle_request(message)和handle_response(message)這兩個函數,當消息從客戶端發送到服務器時,HTTP攔截服務器將調用handle_request(message),當消息從服務器發送到客戶端時,HTTP攔截服務器將調用handle_response(message)。
下面的樣例腳本中,我們將會在消息的結尾添加一個空字節:
def handle_request(message): return message + b"\x00" def handle_response(message): # Both functions must return a message. return message
證書
該工具需要一個服務器證書和一個私鑰來實現SSL攔截。關于如何生成自簽名證書或Burp證書,可以參考這篇【文檔】。
工具使用演示一-攔截MSSQL連接
演示視頻
https://user-images.githubusercontent.com/28649672/162933166-21c1f37d-ee6c-4162-8c00-2bc724cc10a7.mp4
腳本示例
下面給出的兩個腳本支持攔截TLS協議消息:
demo_script.py
from time import time
from struct import pack
from pathlib import Path
def handle_request(message):
if message.startswith(b"\x17\x03"):
return message
with open("msg_req" + str(time()), "wb") as f:
f.write(message[:8])
return message[8:]
def handle_response(message):
if message.startswith(b"\x17\x03"):
return message
path = Path(".")
try:
msg_res = min(i for i in path.iterdir() if i.name.startswith("msg_res"))
data = msg_res.read_bytes()
msg_res.unlink()
except ValueError:
data = b'\x12\x01\x00\x00\x00\x00\x01\x00'
return data[:2] + pack(">h", len(message)+8) + data[4:] + message
demo_script2.py
from time import time
from struct import pack
from pathlib import Path
def handle_request(message):
if message.startswith(b"\x17\x03"):
return message
path = Path(".")
try:
msg_req = min(i for i in path.iterdir() if i.name.startswith("msg_req"))
data = msg_req.read_bytes()
msg_req.unlink()
except ValueError:
data = b'\x12\x01\x00\x00\x00\x00\x01\x00'
return data[:2] + pack(">h", len(message)+8) + data[4:] + message
def handle_response(message):
if message.startswith(b"\x17\x03"):
return message
with open("msg_res" + str(time()), "wb") as f:
f.write(message[:8])
return message[8:]
工具使用演示二-攔截MSSQL連接(TLS)
演示視頻
https://user-images.githubusercontent.com/28649672/162976250-75f2e3c5-f328-4bcc-ad49-a9561d493cb1.mp4
許可證協議
本項目的開發與發布遵循Apache-2.0開源許可證協議。
項目地址
https://github.com/cyberark/MITM_Intercept
參考資料
https://github.com/jrmdev/mitm_relay
https://portswigger.net/bappstore/12e84399d46a408dbe970f181391f781
https://portswigger.net/burp
https://en.wiki*pedia.org/wiki/Server_Name_Indication
https://docs.python.org/3/library/socketserver.html
https://docs.python.org/3/library/http.server.html#http.server.ThreadingHTTPServer
https://www.openssl.org/docs/manmaster/man1/ciphers.html
https://docs.python-requests.org/en/latest/
https://github.com/jrmdev/mitm_relay#host-configuration
https://github.com/jrmdev/mitm_relay#certificates
https://github.com/srini0x00/dvta
https://en.wik*ipedia.org/wiki/Tabular_Data_Stream