之前虽然开了一个·frida-all-in-one的仓库,但最近一直在研究一些自动化分析方向的内容,所以gayhub也没怎么更新,不过加星球加群吹水聊天的倒是不少 (。・∀・)ノ゙ヾ(・ω・。)。
·frida-all-in-one:
https://github.com/hookmaster/frida-all-in-one
不得不说Frida真的是一个好东西,以前搞iOS的时候就想着Cycript和Theos真的是太方便了,Cycript就不用说了,Frida百分之两百足够替代它,LogOS语法和Java API也各有千秋,js有时候还是挺香的。
我现在工作中Android端基本已经用Frida代替了Xposed & Debugger,Dwarf真的很香,墙裂推荐。(虽然现在很少调试就是了…)
言归正传
大家如果经常做APP安全测试的话,抓包应该经常会遇到加密或者需要sign的请求,然后这个时候就很麻烦,一般的做法可能就是需要自己去逆算法扣代码解包拼包来写fuzzer。
再坑爹一点的,APP加个固,算法混个淆,鬼才看得懂,但是老板分配的任务又不能shift+del,然后就花了两天(像我这种拖延症,不重要的事情一般其实是两周)时间撸一遍算法,最后用5分钟来发包发现0高0中0低,内心:wtm….
Brida就是用来解决这个问题的,仅需20分钟,加密、解密、Fuzz、Scan一条龙服务。
简单介绍
- Brida是一个Burp的插件,BurpSuite不用说了吧,大家懂的。
- Brida是一座连接Burp和Frida的桥,Frida也不用说了吧,我记得@roysue写过好几次了。
- 人家是有官方手把手教程的,就是这个,但是我相信你们很多人都懒得看英文,所以就有了这篇文章。
- github上好像没有0.3的release,所以之前我是自己编译的,后来我发现Burp里原来可以直接装…..
开始操作
Python
我一般就用Python2.7,py3应该也没啥问题。多版本管理用星球里介绍过的pyenv。
- 装Frida:pip install frida&pip install frida-tools
- 装Pyro4: pip install Pyro4
Frida
这个不多说了,手机上装好APP,最好关掉selinux,开起frida-server,转发Frida的端口出来:
adbforwardtcp:27042tcp:27042
adbforwardtcp:27043tcp:27043
即可。
BurpSuite
首先,打开你的免费版/破解版BurpSuite(别装了我知道你的正版BurpSuite肯定不是自己出钱买的),点击Extender找到Brida把它装上。然后你就会发现你多了一张同款选项卡。
- 填好你的Python路径。
- Start server: 这个会调用Python的Pyro4库起一个套接字,host和端口也可以自己配置,后面写Proxy就是在这个端口上拿数据。
- JS file可以选择点default ,然后随便找个地方存,待会再用编辑器写RPC脚本。
- Application ID写上APP的包名。
- Spwan application,这个时候就会打开你手机上的APP了。
找算法
相比较算法还原,相信算法在哪里这个问题对各位大黑阔来说应该不是什么多大的问题。不过,Brida提供了一个很方便的操作:插桩。
切换到Analyze Binary,点击Load tree,然后可能会卡一会,因为在加载类列表,加载完点开Java,可以看到这个进程里的所有类,一般我在这就直接搜crypt,然后就会卡更久,因为它把SO里的导出导入函数也搜了一个遍,最后可以右键->Inspect,把可疑的给hook住。
然后让它发包,如果方法被调用了就会打出日志,运气好的话直接就找到加解密函数了,运气不好的话….不存在的,我运气一直很好。(大部分情况下还是得自己看代码找算法位置,配合着来。)
调用算法
这里就是编辑那个js脚本了,可以看到代码里的rpc.exports里帮你写了四个contextcustom,这四个是给右键菜单预留的,contextcustom1、contextcustom2会出现在repeater等模块中request的右键菜单,contextcustom2、contextcustom3则会出现在response的右键菜单。主要就是为了实现手动加解密的功能,就是这样:
(GIF过大无法上传,请阅读原文查看)
值得注意的是,这四个函数接收的参数都是hex形式的,所以返回的时候也要转成hex再传出去。
当然你可以自己在rpc.exports添加函数,然后再contextcustom里调就可以了,只要是在这里面的,后面都可以在API中被调用到。
具体代码可以看github,上次跟着PPT一起发过了。
Proxy
作为一名资深的老 湿 基(其实连驾照都没拿到..),不能做到自动驾驶自己都说不过去。既然上面都说需要一条龙服务了,有现成的Intruder和Scanner不用白不用,所以这个时候就需要Proxy+Pyro4了。
Jython
在开始之前,你需要先装一个Jython,因为BurpSuite全是Java写的,所以不支持CPython,就用了这个Java实现的Python来作为代替品。 当然你也可以选择使用Java来写插件。
如果你有pyenv的话直接。
pyenvinstalljython-2.7.1
没有的话就自己去看官网Guide自己装一个。
装完你还需要pip,CPython的get-pip.py在Jython上是用不了的,
you need this :
https://github.com/jythontools/pip
jython setup.py install
然后你就拥有一个Jython的pip了,最后安装一个Pyro4即可:
pip installpyro4
Extender
到这就是看BurpAPI然后开发扩展了,Burp的API不多,文档也还算友好,所以并没有多难。
申明一个类,继承于IBurpExtender和IHttpListener:
classBurpExtender(IBurpExtender, IHttpListener)
重写registerExtenderCallbacks和processHttpMessage:
defregisterExtenderCallbacks(self, callbacks):
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
self._callbacks.setExtensionName( “fuck encrypt!”)
callbacks.registerHttpListener( self)
defprocessHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
# tool https://portswigger.net/burp/extender/api/constant-values.html#burp.IBurpExtenderCallbacks
iftoolFlag == 64ortoolFlag == 16ortoolFlag == 32: # TOOL_REPEATER TOOL_SCANNER TOOL_INTRUDER
request = messageInfo.getRequest()
analyzedRequest = self._helpers.analyzeRequest(request)
headers = analyzedRequest.getHeaders()
ifnotmessageIsRequest:
response = messageInfo.getResponse()
analyzedResponse = self._helpers.analyzeResponse(response)
messageInfo.setResponse( self.decrypt(analyzedResponse, response))
# elif toolFlag != 4:
else:
messageInfo.setRequest( self.encrypt(analyzedRequest, request))
对着toolFlag一顿if是为了过滤Burp的模块,判断他是从哪过来的,这里是过滤了三个:reperter、scanner、intruder,抓包过来的无需处理,如果你处理了那APP就不能正常收发数据了。
self.decrypt和self.encrypt就是去跟Brida开的端口交换数据,处理加解密:
uri = ‘PYRO:BridaServicePyro@localhost:9999’
pp= Pyro4.Proxy(uri)
…
def decrypt(self, RequestOrResponse,raw):
body = raw[RequestOrResponse.getBodyOffset():]
newbody = body.tostring()
args= []
args. append(newbody.encode( ‘hex’))
ret= pp.callexportfunction( ‘contextcustom3’, args)
ret= self._helpers.bytesToString( ret).decode( ‘hex’)
returnself._helpers.buildHttpMessage(RequestOrResponse.getHeaders(), ret)
def encrypt(self, RequestOrResponse,raw):
body = raw[RequestOrResponse.getBodyOffset():]
newbody = body.tostring()
args= []
args. append(newbody.encode( ‘hex’))
ret= pp.callexportfunction( ‘contextcustom2’, args)
ret= self._helpers.bytesToString( ret).decode( ‘hex’)
returnself._helpers.buildHttpMessage(RequestOrResponse.getHeaders(), ret)
用callexportfunction来调用你刚才js脚本里rpc.exports里的函数,参数是函数名和参数列表。
好了代码到这就写完了,完整代码看github,复制粘贴两分钟搞定。
然后去:
Burp -> Extender -> Options -> Python Environment -> Location Of Jython standalone JAR file
把你Jython的jar包扔进去,pyenv可以用。
pyenv whichjython
看到你的bin路径,这个jar包就在bin往上一级的安装目录里。
最后把你的py加进去,就可以使用Scanner等功能了