一文看懂mitmdump加密对抗

admin 2025年2月28日21:10:34评论9 views字数 9626阅读32分5秒阅读模式
书接上文,上次的文章讲述了前端动态调试获取加密的方式,但是像上文那种采用对称加密后再次加盐进行编码,测试起来就很麻烦,所以为了便于测试,此次讲解如何利用mitmdump进行加密再对抗。
首先回顾一下上文的加密方法核心代码,如下图所示:
一文看懂mitmdump加密对抗
一文看懂mitmdump加密对抗
一文看懂mitmdump加密对抗
代码抠出来了,我们先不理会sign的生成;可以看到,实际上流程是很清晰的:
encryptParam(config.data.data) 方法为实际对请求体加密的方法,而跟进encryptParam(param)方法,首先截取token后六位与硬编码字符串进行拼接生成key,而后第一次使用encrypt()方法进行TripleDES加密,并将值赋值给des3Str;之后将des3Str与salt进行结合后,再次进行TripleDES加密,并输出
windows系统安装mitmdump请自行下载安装;
由于我们知道了加密方法,实际上response返回也一样是相同的加密,所以我们可以先写一个简单的脚本,将两次解密后的数据输出打印在控制台
首先我们需要获取token后六位,这个抓个包就能拿到;其次是我们需要知道待解密参数的格式、参数是什么
一文看懂mitmdump加密对抗
可以看到,请求和返回的格式都是json格式的,分别是data和bizContent,所以可以先写一个简单脚本,直接解密请求和返回
from mitmproxy import flowfilter, ctxfrom mitmproxy.http import HTTPFlowfrom Crypto.Cipher import DES3from Crypto.Util.Padding import unpadimport base64import jsonclassMimit:def_des3_decrypt(self, encrypted_str):"""统一的解密方法"""try:            hardcoded_part = "U2FsdGVkX18ng9Sdur"            salt_part = "IAhhsg"            combined_key = (hardcoded_part + salt_part).encode()            final_key = combined_key[:24]            encrypted_data = base64.b64decode(encrypted_str)            cipher = DES3.new(final_key, DES3.MODE_ECB)            decrypted_data = cipher.decrypt(encrypted_data)return unpad(decrypted_data, DES3.block_size).decode('utf-8')except Exception as e:            ctx.log.error(f"解密失败: {str(e)}")returnNonedefrequest(self, flow: HTTPFlow):"""处理请求"""try:            ctx.log.info("进入目标请求处理")# 处理可能非JSON格式的情况try:                req_data = json.loads(flow.request.content)except json.JSONDecodeError:                ctx.log.warn("非JSON格式请求数据")returnif'data'in req_data:                decrypted = self._des3_decrypt(req_data['data'])if decrypted:#ctx.log.info(f"解密后第一阶段数据: {decrypted}")                    decrypted2 = self._des3_decrypt(decrypted[:-6])                    ctx.log.info(f"解密后第二阶段数据: {decrypted2}")                    flow.request.content = json.dumps(req_data).encode()except Exception as e:            ctx.log.error(f"请求处理异常: {str(e)}")defresponse(self, flow: HTTPFlow):"""处理响应"""try:            salt_part = "IAhhsg"# 处理可能非JSON格式的情况try:                resp_data = json.loads(flow.response.content)except json.JSONDecodeError:                ctx.log.warn("非JSON格式响应数据")returnif'bizContent'in resp_data:#ctx.log.info(f"原始响应内容: {resp_data['bizContent']}")                decrypted = self._des3_decrypt(resp_data['bizContent'])                decrypted2 = self._des3_decrypt(decrypted[:-6])                ctx.log.info(f"解密响应内容: {decrypted2}")                flow.request.content = json.dumps(resp_data).encode()except Exception as e:            ctx.log.error(f"响应处理异常: {str(e)}")addons = [Mimit()] 
des3_decrypt其实是解密函数的封装;浅浅的运行一下,默认mitmdump的代理端口是8080,注意别和burpsuite的代理冲突
一文看懂mitmdump加密对抗
大家对付看一下,此时可以看到,请求和返回都解密成功了,最起码不需要复制粘贴去解密了不是,接下来做的就是继续修改脚本,将明文的请求和返回发送给burpsuite,可以先试一下单独将请求包发送给burpsuite看看效果,只需要在代码原有基础上加一句话就行
defrequest(self, flow: HTTPFlow):"""处理请求"""try:            ctx.log.info("进入目标请求处理")# 处理可能非JSON格式的情况try:                req_data = json.loads(flow.request.content)except json.JSONDecodeError:                ctx.log.warn("非JSON格式请求数据")returnif'data'in req_data:                decrypted = self._des3_decrypt(req_data['data'])if decrypted:                    decrypted2 = self._des3_decrypt(decrypted[:-6])                    ctx.log.info(f"解密后第二阶段数据: {decrypted2}")#将明文请求回传给burpsuite                    req_data['data'] = f"{decrypted2}"                    flow.request.content = json.dumps(req_data).encode()except Exception as e:            ctx.log.error(f"请求处理异常: {str(e)}")
而后将burpsuite作为下级代理,下级代理就是流量从客户端传入到mitmdump,mitmdump再将流量回传给burpsuite
执行命令
mitmdump -p7070 -s d3.py--mode upstream:http://127.0.0.1:8080 --ssl-insecure
设置浏览器代理为7070,这样流量就会先经过mitmdump ,然后经过burpsuite,我们可以先看一下效果
一文看懂mitmdump加密对抗
一文看懂mitmdump加密对抗
可以看到,请求包已经是明文了,但是发送数据包后,数据返回是异常的
一文看懂mitmdump加密对抗
请求正常返回异常,这是因为burpsuite发送请求是明文的,明文请求发送给服务端,服务端是没有办法解析的,因为传回的数据正常应该是密文的,所以导致响应时效,这个时候就引入了第二个知识点:上级代理
但是这里需要说明一下,mitmdump的下级代理是burpsuite,所以经过mitmdump的流量才能经过burpsuite;那么如果在burpsuite设置上游代理,那么经过burpsuite的流量就会重新经过mitmdump进行加密回传给服务器,从而实现burpsuite明文流量但是不影响web的响应过程
所以这里我们需要利用mitmdump编写一个加密明文request请求的脚本来实现这个功能
from mitmproxy import ctxfrom mitmproxy.http import HTTPFlowfrom Crypto.Cipher import DES3from Crypto.Util.Padding import pad, unpadimport base64import jsonclassEncryptAddon:def__init__(self):        self.combined_key = ("U2FsdGVkX18ng9Sdur" + "IAhhsg").encode()def_des3_encrypt(self, plaintext):try:            cipher = DES3.new(self.combined_key, DES3.MODE_ECB)            padded = pad(plaintext.encode(), DES3.block_size)            encrypted = cipher.encrypt(padded)return base64.b64encode(encrypted).decode()except Exception as e:            ctx.log.error(f"加密失败: {e}")returnNonedefrequest(self, flow: HTTPFlow):try:            req_data = json.loads(flow.request.content)if'data'in req_data:                plain_data = req_data['data']                encrypted_step2 = self._des3_encrypt(plain_data)                encrypted_step1 = self._des3_encrypt(encrypted_step2 + "IAhhsg")                req_data['data'] = encrypted_step1                flow.request.content = json.dumps(req_data).encode()except Exception as e:            ctx.log.error(f"请求加密错误: {e}")defresponse(self, flow: HTTPFlow):"""处理响应"""try:# 处理可能非JSON格式的情况try:                resp_data = json.loads(flow.response.content)except json.JSONDecodeError:                ctx.log.warn("非JSON格式响应数据")returnif'bizContent'in resp_data:                flow.request.content = json.dumps(resp_data).encode()except Exception as e:            ctx.log.error(f"响应处理异常: {str(e)}")addons = [EncryptAddon()] 
此时下游代理脚本d3.py保持不变,上游脚本en3.py如上所示,而后分别运行
mitmdump -p7070 -s d3.py--mode upstream:http://127.0.0.1:8080 --ssl-insecuremitmdump -p 9091 -s encrypt.py --ssl-insecure
此时浏览器依然设置7070代理,burpsuite设置8080代理,同时在burpsuite增加上级代理
一文看懂mitmdump加密对抗
运行后,重新触发功能点;需要注意的是,无论是上级代理脚本还是下级代理脚本,即使是暂时不处理返回包response请求,也需要进行单独请求,否则依然会报错
一文看懂mitmdump加密对抗
首先请求发现下级代理的请求和响应都是正常的,此时对burpsuite的数据包进行拦截、重放,发现请求正常
一文看懂mitmdump加密对抗

请求路径为:

客户端 -> mitmproxy:7070(解密) -> Burp:8080 -> mitmproxy:9071(加密) -> 服务器 

响应路径则应该为:

服务器 -> mitmproxy:9091(解密) -> Burp:8080 -> mitmproxy:7070(加密) -> 客户端  

所以我们只需要补充下游代理对返回包的加密流程补充,上游代理对返回包解密流程的补充,即可完成完整的请求链路,实现burpsuite的明文请求、明文响应

完整的下游代理d3.py脚本如下:
from mitmproxy import ctxfrom mitmproxy.http import HTTPFlowfrom Crypto.Cipher import DES3from Crypto.Util.Padding import unpad, padimport base64import jsonclassMimit:def__init__(self):        self.combined_key = ("U2FsdGVkX18ng9Sdur" + "IAhhsg").encode()def_des3_decrypt(self, encrypted_str):try:            encrypted_data = base64.b64decode(encrypted_str)            cipher = DES3.new(self.combined_key, DES3.MODE_ECB)            decrypted = cipher.decrypt(encrypted_data)return unpad(decrypted, DES3.block_size).decode()except Exception as e:            ctx.log.error(f"解密失败: {e}")returnNonedef_des3_encrypt(self, plaintext):try:            cipher = DES3.new(self.combined_key, DES3.MODE_ECB)            padded = pad(plaintext.encode(), DES3.block_size)            encrypted = cipher.encrypt(padded)return base64.b64encode(encrypted).decode()except Exception as e:            ctx.log.error(f"加密失败: {e}")returnNonedefrequest(self, flow: HTTPFlow):"""处理请求"""try:            ctx.log.info("进入目标请求处理")# 处理可能非JSON格式的情况try:                req_data = json.loads(flow.request.content)except json.JSONDecodeError:                ctx.log.warn("非JSON格式请求数据")returnif'data'in req_data:                decrypted = self._des3_decrypt(req_data['data'])if decrypted:                    decrypted2 = self._des3_decrypt(decrypted[:-6])                    ctx.log.info(f"解密后第二阶段数据: {decrypted2}")#将明文请求回传给burpsuite                    req_data['data'] = f"{decrypted2}"                    flow.request.content = json.dumps(req_data).encode()except Exception as e:            ctx.log.error(f"请求处理异常: {str(e)}")defresponse(self, flow: HTTPFlow):"""处理响应"""try:            salt_part = "IAhhsg"# 处理可能非JSON格式的情况try:                resp_data = json.loads(flow.response.content)except json.JSONDecodeError:                ctx.log.warn("非JSON格式响应数据")returnif'bizContent'in resp_data:                plain_resp = resp_data['bizContent']                encrypted_step2 = self._des3_encrypt(plain_resp)                encrypted_step1 = self._des3_encrypt(encrypted_step2 + "27Pskg")                resp_data['bizContent'] = encrypted_step1                flow.response.content = json.dumps(resp_data).encode()except Exception as e:            ctx.log.error(f"响应处理异常: {str(e)}")addons = [Mimit()] 
完整的上游代理en3.py脚本如下:
from mitmproxy import ctxfrom mitmproxy.http import HTTPFlowfrom Crypto.Cipher import DES3from Crypto.Util.Padding import pad, unpadimport base64import jsonclassEncryptAddon:def__init__(self):        self.combined_key = ("U2FsdGVkX18ng9Sdur" + "IAhhsg").encode()[:24]def_des3_encrypt(self, plaintext):try:            cipher = DES3.new(self.combined_key, DES3.MODE_ECB)            padded = pad(plaintext.encode(), DES3.block_size)            encrypted = cipher.encrypt(padded)return base64.b64encode(encrypted).decode()except Exception as e:            ctx.log.error(f"加密失败: {e}")returnNonedef_des3_decrypt(self, encrypted_str):try:            encrypted_data = base64.b64decode(encrypted_str)            cipher = DES3.new(self.combined_key, DES3.MODE_ECB)            decrypted = cipher.decrypt(encrypted_data)return unpad(decrypted, DES3.block_size).decode()except Exception as e:            ctx.log.error(f"解密失败: {e}")returnNonedefrequest(self, flow: HTTPFlow):try:            req_data = json.loads(flow.request.content)if'data'in req_data:                plain_data = req_data['data']                encrypted_step2 = self._des3_encrypt(plain_data)                encrypted_step1 = self._des3_encrypt(encrypted_step2 + "IAhhsg")                req_data['data'] = encrypted_step1                flow.request.content = json.dumps(req_data).encode()except Exception as e:            ctx.log.error(f"请求加密错误: {e}")defresponse(self, flow: HTTPFlow):"""处理响应"""try:            salt_part = "IAhhsg"# 处理可能非JSON格式的情况try:                resp_data = json.loads(flow.response.content)except json.JSONDecodeError:                ctx.log.warn("非JSON格式响应数据")returnif'bizContent'in resp_data:                encrypted = resp_data['bizContent']                decrypted_step1 = self._des3_decrypt(encrypted)                decrypted_step2 = self._des3_decrypt(decrypted_step1[:-6])                resp_data['bizContent'] = decrypted_step2                flow.response.content = json.dumps(resp_data).encode()except Exception as e:            ctx.log.error(f"响应处理异常: {str(e)}")addons = [EncryptAddon()] 
重新运行脚本
mitmdump -p7070 -s d3.py--mode upstream:http://127.0.0.1:8080 --ssl-insecuremitmdump -p 9091 -s encrypt.py --ssl-insecure
一文看懂mitmdump加密对抗
此时burpsuite发包正常
一文看懂mitmdump加密对抗
至此完成全部的解密加密流程
一文看懂mitmdump加密对抗

原文始发于微信公众号(我不懂安全):一文看懂mitmdump加密对抗

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月28日21:10:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   一文看懂mitmdump加密对抗https://cn-sec.com/archives/3781628.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息