渗透技巧:使用python结合mitmproxy定制HTTP流量
mitmproxy介绍
mitmproxy
是一个开源的中间人代理工具,用于拦截、修改、重播和保存HTTP/HTTPS
流量。其名称“Mitm”是“中间人”的缩写,表示它可以作为客户端和服务器之间的中介,允许用户查看和修改流经代理的网络通信。
它与BurpSuite
是同类型工具,mitmproxy
它具有Web界面和命令行界面,但它最强悍的特点是提供了一系列的Python API
,安全人员可以对HTTP/HTTPS
流量进行高度定制,并且可以使用Python
所具有生态库。
实现原理:mitmproxy
可以开启一个HTTP/HTTPS
代理,可以使用Python
修改经过代理的HTTP流量,实现流量的高度定制。
例如以下两种使用场景:
对请求加密较为复杂的登录表单进行爆破
目前前端的数据传输越来越安全,像诸如CryptJS
、JSEncrypt
等加密库使用的频率越来越高,主要用来对前端请求的数据进行加密以保护数据安全,有时也会携带诸如sign
值来保证请求不被篡改。
在对该类表单进行爆破时,传统的BurpSuite
加密暂时无法满足要求。当然也存在一些插件可以实现较为复杂的加解密,如jsEncrypter
插件,但对于熟悉Python
的小伙伴来说,mitmproxy
也许更加合适,可以使用mitmproxy
提供的Python API
对流量进行修改,将为未加密的参数通过使用Python
加密库来加密参数实现爆破,如果存在sign
值也可尝试查看前端JS
来分析是如何生成sign
的。
定制
Webshell
管理器的流量
WebShell
管理器的流量通常具有一定特征,部分特征是写死在管理器中的,如果要修改那必须对WebShell
管理器进行二开,通常情况下难度较大,使用mitmproxy
可以实现对Webshell
管理器发出的请求进行修改,让Webshell
管理器设置mitmproxy
所启用的代理例如将payload
放入请求头,这对于mitmproxy
是轻而易举的。
本篇文章将对mitmproxy
的基本使用教程进行介绍,并且列举常用的一些mitmproxy
提供的一些Python API
,同时也有对应案例介绍。
使用教程
安装mitmproxy
安装它非常简单,使用pip
即可快速安装:
pip install mitmproxy
作为纯python
脚本使用还需要安装asyncio
:
pip install asyncio
安装证书
mitmproxy
需要安装证书才能处理HTTPS
流量,使用pip
安装后,其证书位置在用户目录下的.mitmproxy
文件夹当中,安装.cer
后缀的证书即可。
基本使用
这是一个最简单的示例Python
脚本,只需修改注释部分即可
import asyncio
from mitmproxy.tools.dump import DumpMaster
from mitmproxy import http
from mitmproxy import options
# 监听IP
proxy_server = "0.0.0.0"
# 监听端口
proxy_port = 8082
# 上游代理, 例如走Clash
upstream = "http://127.0.0.1:7890"
# 自定义脚本
class Script:
# 处理请求
def request(self,flow: http.HTTPFlow):
return flow
# 处理响应
def response(self,flow: http.HTTPFlow):
return flow
async def main():
options_ = options.Options(listen_host=proxy_server,listen_port=proxy_port,mode=[f"upstream:{upstream}@{proxy_port}"],ssl_insecure=True)
m = DumpMaster(options_,with_dumper=False,with_termlog=True)
m.addons.add(Script())
print(f"代理服务器: http://{proxy_server}:{proxy_port}/\n上游代理: {upstream}")
await m.run()
# 入口
if __name__ == "__main__":
asyncio.run(main())
常见操作
HTTP流量的基本信息
class Script:
def request(self,flow: http.HTTPFlow):
req = flow.request # 从HTTP流中获取请求
req.url # 请求URL
req.method # 请求方法
req.host # 请求host, 例如www.baidu.com
req.path # 请求路径,例如/api/login
req.query['id'] = '1' # 请求路径中的参数
req.headers["name"] = "value" # 请求头
req.cookies["name"] = "value" # cookies
req.text # 获取请求body的文本数据
req.content # 获取请求body原始字节数据
return flow
修改
JSON
数据
class Script:
def request(self,flow: http.HTTPFlow):
# 从HTTP流中获取请求
req = flow.request
# 添加判断条件
if req.url == "http://example.com/api/login" and req.headers['Content-Type'] == "application/json":
json_data = req.json()
json_data['username'] = "admin"
return flow
修改表单数据
class Script:
def request(self,flow: http.HTTPFlow):
# 从HTTP流中获取请求
req = flow.request
# 添加判断条件
if req.url == "http://example.com/api/login" and req.headers['Content-Type'] == "application/www-form-urlencoded":
req.urlencoded_form['username'] = "admin"
return flow
修改上传的文件
class Script:
def request(self,flow: http.HTTPFlow):
req = flow.request # 从HTTP流中获取请求
if req.url == "http://example.com/api/login" and req.headers['Content-Type'] == "application/www-form-urlencoded":
req.multipart_form[b'username'] = open("filename","rb")
return flow
运行mitmproxy
打开命令行,运行脚本,并将需要的流量设置mitmproxy
监听的代理服务器。
python demo.py
案例
这一个基于mitmproxy
的nps
未授权利用脚本:
https://github.com/yinsel/nps_auth_key_bypass
原理是通过修改请求参数,达到访问正常nps能够未授权访问的效果。
nps未授权漏洞相关链接:
https://peiqi.wgpsec.org/wiki/webapp/NPS/NPS auth_key 未授权访问漏洞.html
总结
mitmproxy
是一个强大的代理工具,可以实现我们平时手工难以做到的事情,但是门槛是需要了解Python
的语法,学习Python
相对于其他语言来说比较简单,但是需要多动手,多实践,正所谓熟能生巧。
声明
本文所提供的信息仅供学习和研究网络安全技术之用途。读者在使用这些信息时应自行判断其适用性,并对其行为负全责。作者不对任何读者因使用本文中信息而导致的任何直接或间接损失负责。
转载须知:
如需转载本文,请务必保留本文末尾的免责声明,并标明文章出处为红细胞安全实验室,同时提供原文链接。未经许可,请勿对本文进行修改,以保持信息的完整性。
感谢各位师傅们的理解与支持。
本公众号不定期更新一些技术文章,还麻烦各位师傅们点点关注,这样才不会错过哦。
0