android app抓包,会出现http包不走fiddler等代理的情况,譬如淘宝系、支付宝系app
etao app使用mtopsdk(https://help.aliyun.com/document_detail/69785.html),https://acs.m.taobao.com/下的请求都抓不到
本文分析了com.taobao.etao,最终可以通过fiddler、burp进行抓包
1、通过frida hook可以打印出所有请求及参数
//所有响应 var Response = Java.use('mtopsdk.network.domain.Response'); Response.$init.overload('mtopsdk.network.domain.Response$Builder').implementation = function(){ //PrintStack() console.log("\nResponse "+arguments[0].body) var ret = this.$init.apply(this, arguments); //all request console.log("\nResponse "+this.toString()) return ret } //所有请求 var RequestBuilder = Java.use('mtopsdk.network.domain.Request$Builder'); RequestBuilder.build.overload().implementation = function(){ //PrintStack() var ret = this.build.apply(this, arguments); //all request console.log("\nRequestBuilder "+ret.toString()) return ret } //所有请求 var ANetworkCallImpl = Java.use('mtopsdk.network.impl.ANetworkCallImpl'); ANetworkCallImpl.$init.overload('mtopsdk.network.domain.Request', 'android.content.Context').implementation = function(){ //PrintStack() console.log("\nANetworkCallImpl "+arguments[0]) var ret = this.$init.apply(this, arguments); return ret } //所有请求url var AbstractNetworkConverter = Java.use('mtopsdk.mtop.protocol.converter.impl.AbstractNetworkConverter'); AbstractNetworkConverter.buildBaseUrl.overload('mtopsdk.framework.domain.MtopContext','java.lang.String', 'java.lang.String').implementation = function(){ //console.log("buildBaseUrl "+arguments[1]+' '+arguments[2]) var ret = this.buildBaseUrl.apply(this, arguments); //url //console.log("buildBaseUrl "+ret) return ret }2、进一步分析得知由于sdk使用spdy协议,导致无法抓包
通过hook 将是否使用spdy返回false
var SwitchConfig = Java.use('mtopsdk.mtop.global.SwitchConfig'); SwitchConfig.isGlobalSpdySwitchOpen.overload().implementation = function(){ var ret = this.isGlobalSpdySwitchOpen.apply(this, arguments); console.log("\nisGlobalSpdySwitchOpenl "+ret) return false }不同应用集成mtopsdk 混淆程度不一样,函数名可能会变
终于可以抓到包
虽然可以看到包,但请求有签名,无法直接改包,还需要针对具体业务进行hook修改参数,后续可以分析下签名机制
其他app可以通过设置no_proxy来bypass wifi代理
1、Socket(Proxy proxy)
2、openConnection (Proxy proxy)
3、OkHttpClient.Builder().proxy(proxy);
等等,需要具体进行hook
============支付宝APP使用mpaas-rpc框架======
参考https://juejin.im/post/5bc850caf265da0abf7d195d#heading-12
(请求通过socket连接发送http协议,暂时没法导入fiddler等代理)
通过frida hook可以打印出请求和响应
var Throwable = null; Java.perform(function () { Throwable = Java.use("java.lang.Throwable"); }); /* * 输出当前调用堆栈 */ function PrintStack() { var stackElements = Throwable.$new().getStackTrace(); var body = "Stack: " + stackElements[0];//method//stackElements[0].getMethodName() for (var i = 1; i < stackElements.length; i++) { body += "\n at " + stackElements[i]; } console.log(body); }; Java.perform(function() { //========android 7+ try{ var array_list = Java.use("java.util.ArrayList"); var ApiClient = Java.use('com.android.org.conscrypt.TrustManagerImpl'); ApiClient.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) { var k = array_list.$new(); return k; } }catch (e) { //console.log('universal '+e); } var CoreHttpManager = Java.use('com.alipay.mobile.common.transport.http.inner.CoreHttpManager'); CoreHttpManager.a.overload('com.alipay.mobile.common.transport.http.HttpUrlRequest').implementation = function(){ //PrintStack() //console.log("") // console.log("CoreHttpManager "+arguments[0].getUrl()+' '+arguments[0].getTag('operationType')) var ret = this.a.apply(this, arguments); return ret } //请求,这个位置已经sign过无法更改参数 var HttpCaller = Java.use('com.alipay.mobile.common.rpc.transport.http.HttpCaller'); HttpCaller.sendRequest.overload('com.alipay.mobile.common.transport.http.HttpUrlRequest').implementation = function(){ var ret = this.sendRequest.apply(this, arguments); var blacklist = ['com.alipayhk.imobilewallet.plugin.home.union.query', 'ant.abtest.configlite', 'alipay.mappconfig.queryAppInfo', 'alipay.mappconfig.queryStageInfo', 'alipay.livetradeprod.soundWave.getInitArgs.pb'] var opertype = arguments[0].getTag('operationType') var url = arguments[0].getUrl() var data = arguments[0].getReqData() var header = arguments[0].getHeaders() var Map = Java.use('java.util.HashMap') var args_map = Java.cast(arguments[0].getTags(), Map) var tags = args_map.toString() var resdata = ret.getResData() if (blacklist.indexOf(opertype) == -1 ){ // try{ // console.log("httpcaller ==request "+url+' '+opertype + ' =header: '+header+ ' =tags: '+tags+' =data: '+byteArr2str(data, true)+' \n======response '+byteArr2str(resdata,true)) // console.log("") // }catch(e){ // //console.log('decode error '+opertype) // console.log("httpcaller ==request "+url+' '+opertype + ' =header: '+header+ ' =tags: '+tags+' =data: '+byteArr2str(data, false)+' \n======response '+byteArr2str(resdata, false)) // console.log("") // } } return ret } //es6支持默认参数 function byteArr2str(ba, w){ if(w){ var string = Java.use('java.lang.String') return string.$new(ba) }else{ var array = Java.use('java.util.Arrays') return array.toString(ba) } } //array2str function arr(arr){ if (arr != null){ var ret = '' for(var i = 0, len = arr.length; i < len; i++){ ret += String.fromCharCode(arr[i]) } return ret } } //参考https://juejin.im/post/5bc850caf265da0abf7d195d#heading-12 //Serializer数据格式protobuf和json两种 //在此位置更改参数 var RpcInvoker = Java.use('com.alipay.mobile.common.rpc.RpcInvoker'); RpcInvoker.singleCall.overload('java.lang.reflect.Method', '[Ljava.lang.Object;', 'java.lang.String', 'int', 'com.alipay.mobile.common.rpc.transport.InnerRpcInvokeContext', 'com.alipay.mobile.common.rpc.protocol.util.RPCProtoDesc').implementation = function(){ console.log("") console.log('call '+arguments[2]+ ' =data: '+arguments[1]) var ret = this.singleCall.apply(this, arguments); return ret } }, 0);可以打印出所有请求
