文章首发于先知社区
地址 http://xz.aliyun.com/t/12652
0x1 前言
在对一次小程序的测试过程中,发现返回的数据部分是加密的,目前一般通过burpsuite的插件和mitmproxy模块来对数据进行加密解密。今天就来介绍一下这两种方法,当然这两种方法都需要用到python,不得不说python是世界上最好的语言(php:? 你小子在说什么)
0x2 burpy
咋们进入正题,在对小程序的某个接口进行测试时,发现会返回当前用户的个人信息,通过将电话号码置空,返回了所有用户的信息,可惜的是关键敏感信息如姓名、电话号码、身份证号等信息都是加密的

得尽量解密数据将它升级为高危漏洞
通过逆向小程序找到了加密算法和key,就差解密了,解密使用的是github上的一个项目burpy
地址:http://github.com/mr-m0nst3r/Burpy
这个插件可以很方便地对通过bp的数据进行加密和解密,项目也给出了示例脚本,我们一般情况下只需要编写encrytp和decrypt两个函数就可以。
对于全数据包加密的数据处理起来更方便一点,而这种局部加密的数据就得多加几行代码。
因为这里我只需解密返回数据,只编写decrypt函数就可以
1 | def decrypt(self, header, body): |
方法传递的header和body就是burp拦截到的原始header和body,包括请求包和响应包,脚本拿到这些数据包,处理好return一下就行了。
完整代码
1 | import json |
通过设置好插件的python路径和脚本路径,启动插件,就可以邮件解密数据了,原谅我码较厚。


通过右键解密会弹出一个窗口来显示解密数据,如果想在bp的原始窗口显示解密数据你可以开启自动加密解密功能


0x3 mitmproxy
还有一种便是通过python的mitmproxy来编写代理拦截脚本,对数据进行加密和解密。
想必这也是大家的老朋友了,中间人攻击的居家旅行必备良药。
3.1 响应包解密
这里拿有道翻译举个例子
有道翻译的返回数据都是经过加密的,如图

通过分析加密代码发现加密方式为aes加密,找到了加密的key和IV就可以编写脚本了
这里只处理返回数据,编写response函数即可
我们可以编写一个类,通过类方法来处理加密数据,使用flow.response.get_text函数可获取响应包,然后将响应包进行解密,通过response.set_text函数将解密后的数据替换掉响应数据
完整代码
1 | from Crypto.Cipher import AES |
启动mitm
mitmdump -p 9090 -s .\test.py --ssl-insecure
我们再将burpsuite的上游代理设置为9090端口,这样就能看到明文数据了

3.2 请求体和响应体解密
网上找了几个没发现请求体和响应体都同时加密的站,索性简单的写了一个测试站
可以看到数据都是加密过的

想要在bp里看到明文的请求数据和响应数据,就需要结合bp的上游代理和下游代理了
加密数据发送到下游代理,再解密数据发送到bp,bp便能看到明文的请求数据
服务器返回的数据到bp的上游代理,再解密数据,bp便能看到明文的返回数据
这其中有个小问题

从请求方向看,下游代理解密数据后,数据一直以明文的形式发送到服务器,服务器肯定要按照设定的程序对数据进行解密,解密必定是失败的,所以无法返回正常数据。
从响应方向看,响应数据在上游代理被解密为明文后,数据一直以明文的形式返回到浏览器,前端代码对数据解密也必然是失败的,也会报错。
所以我们需要在上游代理对明文数据进行加密后发送给服务器,在下游代理将数据加密发送给浏览器客户端,如下图

这样就可以正常查看明文数据了,同样的可以结合xray来使用这种方法。
另外,遇到的一种情况有些接口是明文发送,不用加密,为了防止二次加密,编写一个函数来识别数据是否需要解密和加密,由于本站是使用json来传输数据,可以使用json.loads()来识别数据是否是明文和密文。
下游代理代码
1 | from mitmproxy import flowfilter,ctx |
上游代理代码
1 | from mitmproxy import flowfilter,ctx |
启动下游代理,将数据发送到bp的8080端口
mitmdump -p 7070 -s .\test.py --mode upstream:http://127.0.0.1:8080 --ssl-insecure
启动上游代理
mitmdump -p 9090 -s .\test.py --ssl-insecure
bp设置上游代理到9090端口,这样就可以查看请求和响应的明文了

0x4 工具结合
4.1 sqlmap
在使用sqlmap配合加密数据时,只需要设置一层上游代理即可,代码可以上面的bp上游代码共用,但前提是你需要将解密好的playload给sqlmap,sqlmap将数据发送给上游代理,上游代理加密后发送给服务器,服务器返回数据给上游代理,解密后明文还给sqlmap。但如果你要将原始密文数据给sqlmap,就需要再来一层下游代理了,后面讲xray的时候会将。
代码
1 | from mitmproxy import flowfilter,ctx |
启动代理
mitmdump -p 9090 -s .\test.py --ssl-insecure
sqlmap
sqlmap -r sql.txt -proxy http://192.168.1.5:9090

4.2 xray
xray的话还是需要设置2层代理,我们在浏览器点击一个链接时发送的数据是密文的,需要经过一次解密再发送给xray。
但这个第一层代理就只管解密一次,可以简单点
1 | from mitmproxy import flowfilter,ctx |
上游代理
1 | from mitmproxy import flowfilter,ctx |
启动下游代理,将数据转发到xray的端口
mitmdump -p 7070 -s .\test.py --mode upstream:http://127.0.0.1:8090 --ssl-insecure
启动上游代理
mitmdump -p 9090 -s .\test.py --ssl-insecure
配置xray的代理,修改config文件

启动xray
xray.exe -ws --listen 127.0.0.1:8090
接下来配置浏览器代理端口为7777即可
但xray这里没能跑出来sql注入,应该是xray对json的解析有问题,无法解析json的值,将payload直接拼接在了后面,不是json传输的站点应该没问题。

测试代码
index.html
1 |
|
query.php
1 |
|
0x4 总结
其实对于数据全加密的站点还好,要是部分接口加密,部分接口又不加密,这种就比较恼火,还要判断数据是否为明文,json格式传输的站点还好判断,其他的貌似就不好判断是否是明文还是密文了。另外就是要对算法的逆向和调试了,只有先找到了算法和相关信息,才能编写解密脚本。
0x5 参考链接
http://mp.weixin.qq.com/s/C0RoOau5Twc9Pkyggi98hw