背景
记得之前遇到使用SHA256withRSA对请求体进行签名附加到自定义head中的web应用,当时是使用python编写了签名脚本,然后就开始了痛苦的burp与命令行的不断切换与复制粘贴工作……这效率,真是往事不堪回首啊。
最近又遇上了使用自定义js对请求体进行加密编码处理的web渗透测试任务,这一瞧,我的额头又渐渐出现了小笼包……
问题来了:
1.使用了js自定义的加密编码算法
用其他语言重写算法的成本急剧上升,项目给的时间不够。
2.请求体进行加密编码
burp里看到的是编码后的请求体,改包也成了大问题啊,难道要使用firebug大法了吗?这效率想想就恐怖。
目标
这种事以前有,现在有,以后还会有的!那么想办法解决它。
作为一位标准的“懒人”,至少要满足以下几点吧:
1.不需要其他语言重写js加密编码算法
2.burp中可以直接查看和修改明文数据,最好能支持下intruder
3.为其他漏洞利用工具提供支持(如sqlmap)
方案
语言:python
工具:mitmproxy,burpsuite,pyexecjs
说明:
pyexecjs:使用python调用js加密编码函数,避免js编码算法的重写
burpsuite:一级代理,修改response中js,去除发送请求前的编码动作使请求以明文形式发送
mitmproxy:二级代理,在addon中加载pyexec完成对请求体的加密编码
(ps:看到这里Java大佬们应该默默关上了浏览器,心里想着这不是一个burp插件就解决的事情吗!菜鸡瑟瑟发抖:”Java我是真的菜啊……“)
实施
工具安装:
pyexecjs:pip3 install pyexecjs
mitmproxy:pip3 Install mitmproxy
burpsuite:只用到最基础功能,community版本也可以,傻瓜式安装就行
开始工作:
1.找到自定义加密的js方法
这个需要具体问题具体分析了,不过顺藤摸瓜总是能找到的。
尝试在js文件中检查关键字:encode,encrypt
寻找ajax请求,js中搜索post,检查发送请求前执行的操作
2.验证找到的js是否有语法错误,能否正常执行
这里推荐Thinkoaa编写的burp插件jsrainbow
GITHUB: https://github.com/thinkoaa/JSRainbow
相关文章:https://www.freebuf.com/sectool/242363.html
使用非常简单,指定需要加载的js文件,指定需要执行的方法名:
检查console输出:
在repeater或者interceptor中选中字符右键发送到jsrainbow就可以对指定字符串执行对应的操作了。(ps:如果实在嫌弃后边的步骤麻烦,也可以使用这种方法,做到第三步就可以了,但是就得结合interceptor,每个请求手动执行jsrainbow了。)
或者:
直接使用pyexecjs模块,测试demo:
需要修改的部分均已注释说明
import execjs data='{"NAME":"xxx","ID":"xxx","_DATA":"{}"}' #示例数据 def myencoder(data): jsstr = get_js() loader = execjs.compile(jsstr) #加载JS文件 return (loader.call('xxx', data)) #调用js方法 第一个参数是js的方法名,后面的data是js方法的参数 def get_js(): f = open("C:\\xxx.js", 'r', encoding='utf-8') # 打开JS文件 line = f.readline() htmlstr = '' while line: htmlstr = htmlstr+line line = f.readline() return htmlstr if __name__ == '__main__': print(myencoder(data))
这个代码部分参考的是博客园的文章,PYTHON调用JS:
https://www.cnblogs.com/linlang781/p/8868496.html
(ps:懒人的日常操作,/*羞涩*/)
3.修改response中的js请求代码,使得报文以明文形式传输到burpsuite中
结合第一步找的自定义js加密方法,去掉加密函数的调用即可,举例:
proxy–> options –>match & replace
ps:修改后注意清除浏览器缓存,确保js文件被重新请求和加载。
现在我们已经完成了前半段(如果你使用的是jsrainbow方式):
可以做到burp抓取明文数据包,结合jsrainbow进行数据包修改重放等操作了。
4.编写mitmproxy的addon脚本,实现请求自动加密代理
addon脚本的基本demo:
from mitmproxy import ctx, http class Modify: #在request时执行 def request(self, flow): #筛选针对某个域名下的请求 if flow.request.url.startswith("http://www.xxx.com/"): #检查是否存在请求体数据,urlencoded_form是MultiDictView[]对象也支持字典索引的方式 if flow.request.urlencoded_form: #做自定义的修改 flow.request.urlencoded_form["NAME"]="xxx" addons = [ Modify(), ]
还有关于如何使用addon脚本处理head,cookie,以及response处理脚本的相关内容,可以参考 CSDN上上的文章。
mitmproxy使用(二)-自定义脚本编写:https://blog.csdn.net/qianwenjun_19930314/article/details/88227335
很简洁明了。
我们离目标又近了一步啊,接着只要把请求体的js加密编码部分整合到addon脚本中在处理请求时调用就可以了,看看:
from mitmproxy import ctx, http import execjs def myencoder(data): jsstr = get_js() loader = execjs.compile(jsstr) #加载JS文件 return (loader.call('xxx', data)) #调用js方法 第一个参数是JS的方法名,后面的data和key是js方法的参数 def get_js(): f = open("C:\\xxx.js", 'r', encoding='utf-8') # 打开JS文件 line = f.readline() htmlstr = '' while line: htmlstr = htmlstr+line line = f.readline() return htmlstr class Modify: def request(self, flow): if flow.request.url.startswith("https://www.xxx.com/"): if flow.request.urlencoded_form: print(flow.request.urlencoded_form["PASSWD"]) flow.request.urlencoded_form["PASSWD"]=myencoder(flow.request.urlencoded_form["PASSWD"]) addons = [ Modify() ]
没什么难度吧!
5.启动我们的mitmdump,配置burp将请求转发至二级代理
mitmdump启动参数:
.\mitmdump.exe -p 8081 -s addon_jsenc.py –quiet
-p指定端口 -s指定addon脚本 –quiet 静默执行(调试的时候可以不用)
burp配置上游代理:
User options –> Connections –>Upstream Proxy Servers
我们的目标达成了,可以直接查看和修改明文数据包,SQLmap什么的也可以直接指向代理,加密过程完全透明化了,后续就可以愉快地玩耍啦!
参考材料:
FREEBUF–BurpSuite调用JavaScript处理Payload,通过JS完全自定义处理逻辑:
https://www.freebuf.com/sectool/242363.html
博客园–PYTHON调用JS:
https://www.cnblogs.com/linlang781/p/8868496.html
CSDN–mitmproxy使用(二)-自定义脚本编写:https://blog.csdn.net/qianwenjun_19930314/article/details/88227335
来源:freebuf.com 2020-07-14 18:07:59 by: ShawnDing
请登录后发表评论
注册