马蜂窝旅游
HTTPCanary抓包
POST /rest/app/user/login/ HTTP/1.1
User-Agent: Dalvik/2.1.0 (Linux; U; Android 10; Pixel XL Build/QP1A.191005.007.A3) mfwappcode/com.mfw.roadbook mfwappver/8.1.6 mfwversioncode/535 mfwsdk/20140507 channel/GROWTH-WAP-LC-3 mfwjssdk/1.1 mfwappjsapi/1.5
Connection: close
X-HTTP-METHOD-OVERRIDE: PUT
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: mapi.mafengwo.cn
Accept-Encoding: gzip
Cookie: __openudid=40:4E:36:24:41:C1; PHPSESSID=b1qpoi77ffcei07808dplb9p53; mfw_uuid=66f26266-1c4d-1dbc-c45a-b01dd11fcf99; oad_n=a%3A3%3A%7Bs%3A3%3A%22oid%22%3Bi%3A1029%3Bs%3A2%3A%22dm%22%3Bs%3A16%3A%22mapi.mafengwo.cn%22%3Bs%3A2%3A%22ft%22%3Bs%3A19%3A%222024-09-24+14%3A55%3A34%22%3B%7D
Content-Length: 637
x_auth_username=15828712517&device_type=android&oauth_version=1.0&oauth_signature_method=HMAC-SHA1&screen_height=2392&open_udid=40%3A4E%3A36%3A24%3A41%3AC1&put_style=default&app_version_code=535&x_auth_mode=client_auth&sys_ver=10&brand=google&app_code=com.mfw.roadbook&screen_scale=3.5&screen_width=1440&time_offset=480&device_id=40%3A4E%3A36%3A24%3A41%3AC1&oauth_signature=rrW8P2RVZH5Piw%2FJtM2OaJA7Ilk%3D&x_auth_password=passwoed777&oauth_consumer_key=5&oauth_timestamp=1727161555&oauth_nonce=1804f12b-a80a-419f-9b66-ca815320e8fd&mfwsdk_ver=20140507&app_ver=8.1.6&hardware_model=Pixel+XL&channel_id=GROWTH-WAP-LC-3&after_style=default&
x_auth_username=15838712517
device_type=android
oauth_version=1.0
oauth_signature_method=HMAC-SHA1
screen_height=2392
open_udid=40:4E:36:24:41:C1
put_style=default
app_version_code=535
x_auth_mode=client_auth
sys_ver=10
brand=google
app_code=com.mfw.roadbook
screen_scale=3.5
screen_width=1440
time_offset=480
device_id=40:4E:36:24:41:C1
oauth_signature=g2gp+QpP1sAuQ9Ix7YdOfY6ryr4=
x_auth_password=password777+/
oauth_consumer_key=5
oauth_timestamp=1727240241
oauth_nonce=74b0be1f-91e9-48c9-9bbf-cb9314c8d13a
mfwsdk_ver=20140507
app_ver=8.1.6
hardware_model=Pixel+XL
channel_id=GROWTH-WAP-LC-3
after_style=default
上面大多数的数据都是固定的,差不多也就是这些不是固定的
oauth_nonce=74b0be1f-91e9-48c9-9bbf-cb9314c8d13a
oauth_signature=g2gp+QpP1sAuQ9Ix7YdOfY6ryr4=
oauth_timestamp=1727240241
这里原本可能会遇到检测的,但是我没遇到,但是再看看绕过检测的东西
HOOK.js
Java.perform(function() {
/*
hook list:
1.SSLcontext
2.okhttp
3.webview
4.XUtils
5.httpclientandroidlib
6.JSSE
7.network\_security\_config (android 7.0+)
8.Apache Http client (support partly)
9.OpenSSLSocketImpl
10.TrustKit
11.Cronet
*/
// Attempts to bypass SSL pinning implementations in a number of
// ways. These include implementing a new TrustManager that will
// accept any SSL certificate, overriding OkHTTP v3 check()
// method etc.
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var HostnameVerifier = Java.use('javax.net.ssl.HostnameVerifier');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var quiet_output = false;
// Helper method to honor the quiet flag.
function quiet_send(data) {
if (quiet_output) {
return;
}
send(data)
}
// Implement a new TrustManager
// ref: https://gist.github.com/oleavr/3ca67a173ff7d207c6b8c3b0ca65a9d8
// Java.registerClass() is only supported on ART for now(201803). 所以android 4.4以下不兼容,4.4要切换成ART使用.
/*
06-07 16:15:38.541 27021-27073/mi.sslpinningdemo W/System.err: java.lang.IllegalArgumentException: Required method checkServerTrusted(X509Certificate[], String, String, String) missing
06-07 16:15:38.542 27021-27073/mi.sslpinningdemo W/System.err: at android.net.http.X509TrustManagerExtensions.<init>(X509TrustManagerExtensions.java:73)
at mi.ssl.MiPinningTrustManger.<init>(MiPinningTrustManger.java:61)
06-07 16:15:38.543 27021-27073/mi.sslpinningdemo W/System.err: at mi.sslpinningdemo.OkHttpUtil.getSecPinningClient(OkHttpUtil.java:112)
at mi.sslpinningdemo.OkHttpUtil.get(OkHttpUtil.java:62)
at mi.sslpinningdemo.MainActivity$1$1.run(MainActivity.java:36)
*/
var X509Certificate = Java.use("java.security.cert.X509Certificate");
var TrustManager;
try {
TrustManager = Java.registerClass({//创建自定义的 TrustManager
name: 'org.wooyun.TrustManager',
implements: [X509TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},//checkClientTrusted 和 checkServerTrusted 方法被重写以不执行任何检查。
checkServerTrusted: function(chain, authType) {},
getAcceptedIssuers: function() {
// var certs = [X509Certificate.$new()];
// return certs;
return [];
}
}
});
} catch (e) {
quiet_send("registerClass from X509TrustManager >>>>>>>> " + e.message);
}
// Prepare the TrustManagers array to pass to SSLContext.init()
var TrustManagers = [TrustManager.$new()];
try {
// Prepare a Empty SSLFactory修改 SSLContext 的初始化,载入新修改的TrustManagers
var TLS_SSLContext = SSLContext.getInstance("TLS");
TLS_SSLContext.init(null, TrustManagers, null);
var EmptySSLFactory = TLS_SSLContext.getSocketFactory();
} catch (e) {
quiet_send(e.message);
}
send('Custom, Empty TrustManager ready');
// Get a handle on the init() on the SSLContext class
var SSLContext_init = SSLContext.init.overload(
'[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom');
// Override the init method, specifying our new TrustManager
SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {
quiet_send('Overriding SSLContext.init() with the custom TrustManager');
SSLContext_init.call(this, null, TrustManagers, null);
};
/*** okhttp3.x unpinning ***/
// Wrap the logic in a try/catch as not all applications will have
// okhttp as part of the app.
try {
var CertificatePinner = Java.use('okhttp3.CertificatePinner');
quiet_send('OkHTTP 3.x Found');
CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
quiet_send('OkHTTP 3.x check() called. Not throwing an exception.');
}
var OkHttpClient$Builder = Java.use('okhttp3.OkHttpClient$Builder');
quiet_send('OkHttpClient$Builder Found');
console.log("hostnameVerifier", OkHttpClient$Builder.hostnameVerifier);
OkHttpClient$Builder.hostnameVerifier.implementation = function () {
quiet_send('OkHttpClient$Builder hostnameVerifier() called. Not throwing an exception.');
return this;
}
var myHostnameVerifier = Java.registerClass({
name: 'com.xiaojianbang.MyHostnameVerifier',
implements: [HostnameVerifier],
methods: {
verify: function (hostname, session) {
return true;
}
}
});
var OkHttpClient = Java.use('okhttp3.OkHttpClient');
OkHttpClient.hostnameVerifier.implementation = function () {
quiet_send('OkHttpClient hostnameVerifier() called. Not throwing an exception.');
return myHostnameVerifier.$new();
}
} catch (err) {
// If we dont have a ClassNotFoundException exception, raise the
// problem encountered.
if (err.message.indexOf('ClassNotFoundException') === 0) {
throw new Error(err);
}
}
// Appcelerator Titanium PinningTrustManager
// Wrap the logic in a try/catch as not all applications will have
// appcelerator as part of the app.
try {
var PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');
send('Appcelerator Titanium Found');
PinningTrustManager.checkServerTrusted.implementation = function() {
quiet_send('Appcelerator checkServerTrusted() called. Not throwing an exception.');
}
} catch (err) {
// If we dont have a ClassNotFoundException exception, raise the
// problem encountered.
if (err.message.indexOf('ClassNotFoundException') === 0) {
throw new Error(err);
}
}
/*** okhttp unpinning ***/
try {
var OkHttpClient = Java.use("com.squareup.okhttp.OkHttpClient");
OkHttpClient.setCertificatePinner.implementation = function(certificatePinner) {
// do nothing
quiet_send("OkHttpClient.setCertificatePinner Called!");
return this;
};
// Invalidate the certificate pinnet checks (if "setCertificatePinner" was called before the previous invalidation)
var CertificatePinner = Java.use("com.squareup.okhttp.CertificatePinner");
CertificatePinner.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function(p0, p1) {
// do nothing
quiet_send("okhttp Called! [Certificate]");
return;
};
CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function(p0, p1) {
// do nothing
quiet_send("okhttp Called! [List]");
return;
};
} catch (e) {
quiet_send("com.squareup.okhttp not found");
}
/*** WebView Hooks ***/
/* frameworks/base/core/java/android/webkit/WebViewClient.java */
/* public void onReceivedSslError(Webview, SslErrorHandler, SslError) */
var WebViewClient = Java.use("android.webkit.WebViewClient");
WebViewClient.onReceivedSslError.implementation = function(webView, sslErrorHandler, sslError) {
quiet_send("WebViewClient onReceivedSslError invoke");
//执行proceed方法
sslErrorHandler.proceed();
return;
};
WebViewClient.onReceivedError.overload('android.webkit.WebView', 'int', 'java.lang.String', 'java.lang.String').implementation = function(a, b, c, d) {
quiet_send("WebViewClient onReceivedError invoked");
return;
};
WebViewClient.onReceivedError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceError').implementation = function() {
quiet_send("WebViewClient onReceivedError invoked");
return;
};
/*** JSSE Hooks ***/
/* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */
/* public final TrustManager[] getTrustManager() */
/* TrustManagerFactory.getTrustManagers maybe cause X509TrustManagerExtensions error */
// var TrustManagerFactory = Java.use("javax.net.ssl.TrustManagerFactory");
// TrustManagerFactory.getTrustManagers.implementation = function(){
// quiet_send("TrustManagerFactory getTrustManagers invoked");
// return TrustManagers;
// }
var HttpsURLConnection = Java.use("com.android.okhttp.internal.huc.HttpsURLConnectionImpl");
HttpsURLConnection.setSSLSocketFactory.implementation = function(SSLSocketFactory) {
quiet_send("HttpsURLConnection.setSSLSocketFactory invoked");
};
HttpsURLConnection.setHostnameVerifier.implementation = function(hostnameVerifier) {
quiet_send("HttpsURLConnection.setHostnameVerifier invoked");
};
/*** Xutils3.x hooks ***/
//Implement a new HostnameVerifier
var TrustHostnameVerifier;
try {
TrustHostnameVerifier = Java.registerClass({
name: 'org.wooyun.TrustHostnameVerifier',
implements: [HostnameVerifier],
method: {
verify: function(hostname, session) {
return true;
}
}
});
} catch (e) {
//java.lang.ClassNotFoundException: Didn't find class "org.wooyun.TrustHostnameVerifier"
quiet_send("registerClass from hostnameVerifier >>>>>>>> " + e.message);
}
try {
var RequestParams = Java.use('org.xutils.http.RequestParams');
RequestParams.setSslSocketFactory.implementation = function(sslSocketFactory) {
sslSocketFactory = EmptySSLFactory;
return null;
}
RequestParams.setHostnameVerifier.implementation = function(hostnameVerifier) {
hostnameVerifier = TrustHostnameVerifier.$new();
return null;
}
} catch (e) {
quiet_send("Xutils hooks not Found");
}
/*** httpclientandroidlib Hooks ***/
try {
var AbstractVerifier = Java.use("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
AbstractVerifier.verify.overload('java.lang.String', '[Ljava.lang.String', '[Ljava.lang.String', 'boolean').implementation = function() {
quiet_send("httpclientandroidlib Hooks");
return null;
}
} catch (e) {
quiet_send("httpclientandroidlib Hooks not found");
}
/***
android 7.0+ network_security_config TrustManagerImpl hook
apache httpclient partly
***/
var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
// try {
// var Arrays = Java.use("java.util.Arrays");
// //apache http client pinning maybe baypass
// //https://github.com/google/conscrypt/blob/c88f9f55a523f128f0e4dace76a34724bfa1e88c/platform/src/main/java/org/conscrypt/TrustManagerImpl.java#471
// TrustManagerImpl.checkTrusted.implementation = function (chain, authType, session, parameters, authType) {
// quiet_send("TrustManagerImpl checkTrusted called");
// //Generics currently result in java.lang.Object
// return Arrays.asList(chain);
// }
//
// } catch (e) {
// quiet_send("TrustManagerImpl checkTrusted nout found");
// }
try {
// Android 7+ TrustManagerImpl
TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
quiet_send("TrustManagerImpl verifyChain called");
// Skip all the logic and just return the chain again :P
//https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2017/november/bypassing-androids-network-security-configuration/
// https://github.com/google/conscrypt/blob/c88f9f55a523f128f0e4dace76a34724bfa1e88c/platform/src/main/java/org/conscrypt/TrustManagerImpl.java#L650
return untrustedChain;
}
} catch (e) {
quiet_send("TrustManagerImpl verifyChain nout found below 7.0");
}
// OpenSSLSocketImpl
try {
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certRefs, authMethod) {
quiet_send('OpenSSLSocketImpl.verifyCertificateChain');
}
quiet_send('OpenSSLSocketImpl pinning')
} catch (err) {
quiet_send('OpenSSLSocketImpl pinner not found');
}
// Trustkit
try {
var Activity = Java.use("com.datatheorem.android.trustkit.pinning.OkHostnameVerifier");
Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(str) {
quiet_send('Trustkit.verify1: ' + str);
return true;
};
Activity.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(str) {
quiet_send('Trustkit.verify2: ' + str);
return true;
};
quiet_send('Trustkit pinning')
} catch (err) {
quiet_send('Trustkit pinner not found')
}
try {
//cronet pinner hook
//weibo don't invoke
var netBuilder = Java.use("org.chromium.net.CronetEngine$Builder");
//https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/CronetEngine.Builder.html#enablePublicKeyPinningBypassForLocalTrustAnchors(boolean)
netBuilder.enablePublicKeyPinningBypassForLocalTrustAnchors.implementation = function(arg) {
//weibo not invoke
console.log("Enables or disables public key pinning bypass for local trust anchors = " + arg);
//true to enable the bypass, false to disable.
var ret = netBuilder.enablePublicKeyPinningBypassForLocalTrustAnchors.call(this, true);
return ret;
};
netBuilder.addPublicKeyPins.implementation = function(hostName, pinsSha256, includeSubdomains, expirationDate) {
console.log("cronet addPublicKeyPins hostName = " + hostName);
//var ret = netBuilder.addPublicKeyPins.call(this,hostName, pinsSha256,includeSubdomains, expirationDate);
//this 是调用 addPublicKeyPins 前的对象吗? Yes,CronetEngine.Builder
return this;
};
} catch (err) {
console.log('[-] Cronet pinner not found')
}
});
这里的绕过全是是HOOK了相应对应的检测函数,把对应的检测全部HOOK,然后函数之间做了nothing,或者是传入了一个自定义的参数,传入了对应的函数,也是什么也不做,直接把保护绕过完了
关键函数定位
这里的关键函数定位还是很简单的,这里我直接去HOOK了Toast
var Toast =Java.use("android.widget.Toast");
Toast.show.implementation = function(){
showstack();
console.log("Toast.show.implementation");
return this.show();
}
[Pixel XL::马蜂窝旅游]-> java.lang.Throwable
at android.widget.Toast.show(Native Method)
at com.growingio.android.sdk.agent.VdsAgent.showToast(VdsAgent.java:520)
at com.mfw.roadbook.account.view.AccountFragment.showToast(AccountFragment.java:274)
at com.mfw.roadbook.account.presenter.AccountPresenter.onLoginError(AccountPresenter.java:131)
at com.mfw.roadbook.account.presenter.AccountPresenter$1.onLoginError(AccountPresenter.java:75)
at com.mfw.roadbook.account.model.AccountLoginApi.onErrorResponse(AccountLoginApi.java:46)
at com.mfw.uniloginsdk.UniLogin$LoginCallbackClosure$1.onErrorResponse(UniLogin.java:469)
at com.android.volley.Request.deliverError(Request.java:613)
at com.mfw.melon.http.request.MJsonObjectRequest.deliverError(MJsonObjectRequest.java:42)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:115)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
com.mfw.roadbook.account.presenter.AccountPresenter.onLoginError(AccountPresenter.java:131)
这个位置可以直接找到关键函数
public void login(String account, String password) {
if (TextUtils.isEmpty(account)) {
this.accountView.showToast("请输入账号");
} else if (TextUtils.isEmpty(password)) {
this.accountView.showToast("请输入密码");
} else {
this.accountView.showDialog("正在登录...");
this.accountLoginApi.login(account, password, new BasicAccount.OnLoginListener() { // from class: com.mfw.roadbook.account.presenter.AccountPresenter.1
private final String MESSAGE = "账号密码登录";
@Override // com.mfw.roadbook.account.model.BasicAccount.OnLoginListener
public void onLoginSuccess(UniLoginAccountModelItem item) {
AccountPresenter.this.accountView.sendLoginEvent(1, "登录成功", "账号密码登录");
AccountPresenter.this.listener.onLoginSuccess(item);
}
@Override // com.mfw.roadbook.account.model.BasicAccount.OnLoginListener
public void onLoginError(int key, String message) {
AccountPresenter.this.accountView.sendLoginEvent(-1, key == -1 ? "登录失败" : message, "账号密码登录");
AccountPresenter.this.listener.onLoginError(key, message);
}
@Override // com.mfw.roadbook.account.model.BasicAccount.OnLoginListener
public void onLoginServerError(int key, UniLoginAccountModelItem item) {
AccountPresenter.this.listener.onLoginServerError(key, item);
}
});
}
}
大概的跟进几步,可以看到getSign的定义的类了
package com.mfw.uniloginsdk.rest;
import com.mfw.uniloginsdk.LoginCommon;
import com.mfw.uniloginsdk.UniRequestModel;
import com.mfw.uniloginsdk.util.DomainUtil;
import com.mfw.uniloginsdk.util.SecurityTools;
import java.util.Map;
/* loaded from: classes4.dex */
public class LoginRequestModel extends UniRequestModel {
private final String URL_LOGIN = DomainUtil.REST_URL + "app/user/login/";
private String account;
private String password;
public LoginRequestModel(String account, String password) {
this.account = account;
this.password = password;
}
@Override // com.mfw.melon.http.MBaseRequestModel
public int getMethod() {
return 2;
}
@Override // com.mfw.melon.http.MBaseRequestModel
public String getUrl() {
return this.URL_LOGIN;
}
@Override // com.mfw.melon.http.MBaseRequestModel
protected void setParams(Map<String, String> params) {
params.put("put_style", "default");
params.put("after_style", "default");
params.put("x_auth_username", this.account);
params.put("x_auth_password", this.password);
}
@Override // com.mfw.uniloginsdk.UniRequestModel, com.mfw.melon.http.MBaseRequestModel
public Map<String, String> getParams() {
Map<String, String> params = super.getParams();
params.put(LoginCommon.HTTP_BASE_PARAM_OAUTH_SIGNATURE, SecurityTools.getLoginOauthSignature(this, params));
return params;
}
}
最终我们定位到了包:com.mfw.tnative.AuthorizeHelper的xAuthencode
private native String xAuthencode(Context context, String str, String str2, String str3, boolean z);
不过这是进行了native化的
HOOK
先利用Frida来HOOK一下java层的xAuthencode
var AuthorizeHelper = Java.use("com.mfw.tnative.AuthorizeHelper");
AuthorizeHelper.xAuthencode.overload('android.content.Context', 'java.lang.String', 'java.lang.String', 'java.lang.String', 'boolean').implementation = function(a,b,c,d,e){
console.log("args[0]:"+a);
console.log("args[1]:"+b);
console.log("args[2]:"+c);
console.log("args[3]:"+d);
console.log("args[4]:"+e);
var result = this.xAuthencode(a,b,c,d,e);
console.log("result: " + result);
return result;
}
result:
args[0]:com.mfw.roadbook.MainApplication@fd32da7
args[1]:PUT&https%3A%2F%2Fmapi.mafengwo.cn%2Frest%2Fapp%2Fuser%2Flogin%2F&after_style%3Ddefault%26app_code%3Dcom.mfw.roadbook%26app_ver%3D8.1.6%26app_version_code%3D535%26brand%3Dgoogle%26channel_id%3DGROWTH-WAP-LC-3%26device_id%3D40%253A4E%253A36%253A24%253A41%253AC1%26device_type%3Dandroid%26hardware_model%3DPixel%2520XL%26mfwsdk_ver%3D20140507%26oauth_consumer_key%3D5%26oauth_nonce%3D1b6be857-bec5-4302-97be-6778d3bed316%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1727240426%26oauth_version%3D1.0%26open_udid%3D40%253A4E%253A36%253A24%253A41%253AC1%26put_style%3Ddefault%26screen_height%3D2392%26screen_scale%3D3.5%26screen_width%3D1440%26sys_ver%3D10%26time_offset%3D480%26x_auth_mode%3Dclient_auth%26x_auth_password%3Dpassword777%2520%252F%26x_auth_username%3D15838712517
args[2]:
args[3]:com.mfw.roadbook
args[4]:true
result: b0nNedgOwdVRN12uLzlSI7APAgk=
这里的arg[1]来url解码一下
PUT&https://mapi.mafengwo.cn/rest/app/user/login/&after_style=default&app_code=com.mfw.roadbook&app_ver=8.1.6&app_version_code=535&brand=google&channel_id=GROWTH-WAP-LC-3&device_id=40:4E:36:24:41:C1&device_type=android&hardware_model=Pixel XL&mfwsdk_ver=20140507&oauth_consumer_key=5&oauth_nonce=1b6be857-bec5-4302-97be-6778d3bed316&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1727240426&oauth_version=1.0&open_udid=40:4E:36:24:41:C1&put_style=default&screen_height=2392&screen_scale=3.5&screen_width=1440&sys_ver=10&time_offset=480&x_auth_mode=client_auth&x_auth_password=password777 /&x_auth_username=15838712517
这里全是我们之前抓包得到的数据,大多数都是硬件信息和固定值,所有我们知道了对应的传入的参数,再来看看result:b0nNedgOwdVRN12uLzlSI7APAgk=(大概率是base64的结果,而且我们传入的是这么大片的数据,得到的很少字节的数据,大概率考虑是摘要算法之后的结果)
固定传入:
方便之后进行数据的同意,我们固定一下参数,然后用来主动调用
function call_java()
{
var AuthorizeHelper = Java.use("com.mfw.tnative.AuthorizeHelper");
var current_application = Java.use('android.app.ActivityThread').currentApplication();
var context = current_application.getApplicationContext();
// var arg0="com.mfw.roadbook.MainApplication@fd32da7";
var arg1="PUT&https%3A%2F%2Fmapi.mafengwo.cn%2Frest%2Fapp%2Fuser%2Flogin%2F&after_style%3Ddefault%26app_code%3Dcom.mfw.roadbook%26app_ver%3D8.1.6%26app_version_code%3D535%26brand%3Dgoogle%26channel_id%3DGROWTH-WAP-LC-3%26device_id%3D40%253A4E%253A36%253A24%253A41%253AC1%26device_type%3Dandroid%26hardware_model%3DPixel%2520XL%26mfwsdk_ver%3D20140507%26oauth_consumer_key%3D5%26oauth_nonce%3D1b6be857-bec5-4302-97be-6778d3bed316%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1727240426%26oauth_version%3D1.0%26open_udid%3D40%253A4E%253A36%253A24%253A41%253AC1%26put_style%3Ddefault%26screen_height%3D2392%26screen_scale%3D3.5%26screen_width%3D1440%26sys_ver%3D10%26time_offset%3D480%26x_auth_mode%3Dclient_auth%26x_auth_password%3Dpassword777%2520%252F%26x_auth_username%3D15838712517";
var arg2="";
var arg3="com.mfw.roadbook";
var arg4=true;
AuthorizeHelper.$new(arg3).xAuthencode(context,arg1,arg2,arg3,arg4);
}
SO层逆向
package com.mfw.tnative;
import android.content.Context;
/* loaded from: classes4.dex */
public class AuthorizeHelper {
private static AuthorizeHelper instance;
private String packageName;
private native boolean signatureChecked(Context context, String str);
private native String xAuthencode(Context context, String str, String str2, String str3, boolean z);
private AuthorizeHelper(String name) {
this.packageName = name;
}
public static AuthorizeHelper getInstance(String name) {
if (instance == null) {
instance = new AuthorizeHelper(name);
}
return instance;
}
public String cryptoParams(Context context, String source, String key, boolean isLogin) {
return xAuthencode(context, source, key, this.packageName, isLogin);
}
public boolean isAppSingedCorrect(Context context) {
return signatureChecked(context, this.packageName);
}
static {
System.loadLibrary("mfw");
}
}
SO文件:System.loadLibrary("mfw");
IDA分析:
{
if ( signatureChecked(a1, a2, a3, a6, a6, a5, a4, a3) != 1 )
return _JNIEnv::NewStringUTF(a1, "Illegal signature");
StringUTFChars = _JNIEnv::GetStringUTFChars(a1, v12, 0);
ConsumerSecret = getConsumerSecret(StringUTFChars);
std::allocator<char>::allocator(v26);
std::string::string(v28, ConsumerSecret, v26);
std::allocator<char>::~allocator(v26);
if ( std::string::empty(v28) )
{
v7 = _JNIEnv::NewStringUTF(a1, "Illegal app secret do not found!");
}
else
{
mfw::Base64::Base64(&v16);
v18 = _JNIEnv::GetStringUTFChars(a1, v13, 0);
std::string::append(v28, "&");
if ( a7 || *v18 )
{
std::string::append(v28, v18);
}
else
{
GuestTokenSecret = getGuestTokenSecret(StringUTFChars);
std::string::append(v28, GuestTokenSecret);
}
v10 = std::string::data(v28);
v19 = j_strlen(v10);
v20 = std::string::data(v28);
mfw::Sha1::CHmac::SetKey(v26, v20, v19);
v21 = _JNIEnv::GetStringUTFChars(a1, v14, 0);
v22 = j_strlen(v21);
v23 = v21;
mfw::Sha1::CHmac::Update(v26, v21, v22);
v24 = 20;
mfw::Sha1::CHmac::Final(v26, v27, 0x14u);
v25 = mfw::Base64::base64_encode(&v16, v27, 20);
_JNIEnv::ReleaseStringUTFChars(a1, v14, v21);
_JNIEnv::ReleaseStringUTFChars(a1, v13, v18);
_JNIEnv::ReleaseStringUTFChars(a1, v12, StringUTFChars);
v7 = _JNIEnv::NewStringUTF(a1, v25);
}
std::string::~string(v28);
return v7;
}
C++写的程序,我们从后往前看 v7——>v25——>v27——>v22
这些数据都是可疑的,v26大概率是context
从后往前看,先是v25,HOOK一下看看是不是魔改的base64
function print_arg(args) {
if (args instanceof NativePointer) {
var module = Process.findRangeByAddress(args);
if (module != null) {
return hexdump(args) + "\n";
}
}
return ptr(args)+"\n";
}
function hook_native_addr(funcPtr, paramsNum){
var module = Process.findModuleByAddress(funcPtr);
if (module === null) {
console.log("Module not found for function pointer");
return;
}
Interceptor.attach(funcPtr, {
onEnter: function(args){
this.logs = [];
this.params = [];
this.logs.push("call ————>" + module.name + "!" + ptr(funcPtr).sub(module.base) + "\n");
for(let i = 0; i < paramsNum; i++){
this.params.push(args[i]);
}
for(let i = 0; i < paramsNum; i++){
this.logs.push("this.args" + i + " onEnter: " + print_arg(this.params[i])+ "\n");
}
}, onLeave: function(retval){
for(let i = 0; i < paramsNum; i++){
this.logs.push("this.args" + i + " onLeave: " + print_arg(this.params[i])+ "\n");
}
this.logs.push("retval onLeave: " + print_arg(retval) + "\n");
console.log(this.logs);
}
});
function call_java()
{
var AuthorizeHelper = Java.use("com.mfw.tnative.AuthorizeHelper");
var current_application = Java.use('android.app.ActivityThread').currentApplication();
var context = current_application.getApplicationContext();
// var arg0="com.mfw.roadbook.MainApplication@fd32da7";
var arg1="PUT&https%3A%2F%2Fmapi.mafengwo.cn%2Frest%2Fapp%2Fuser%2Flogin%2F&after_style%3Ddefault%26app_code%3Dcom.mfw.roadbook%26app_ver%3D8.1.6%26app_version_code%3D535%26brand%3Dgoogle%26channel_id%3DGROWTH-WAP-LC-3%26device_id%3D40%253A4E%253A36%253A24%253A41%253AC1%26device_type%3Dandroid%26hardware_model%3DPixel%2520XL%26mfwsdk_ver%3D20140507%26oauth_consumer_key%3D5%26oauth_nonce%3D1b6be857-bec5-4302-97be-6778d3bed316%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1727240426%26oauth_version%3D1.0%26open_udid%3D40%253A4E%253A36%253A24%253A41%253AC1%26put_style%3Ddefault%26screen_height%3D2392%26screen_scale%3D3.5%26screen_width%3D1440%26sys_ver%3D10%26time_offset%3D480%26x_auth_mode%3Dclient_auth%26x_auth_password%3Dpassword777%2520%252F%26x_auth_username%3D15838712517";
var arg2="";
var arg3="com.mfw.roadbook";
var arg4=true;
AuthorizeHelper.$new(arg3).xAuthencode(context,arg1,arg2,arg3,arg4);
}
var moduleBase = Module.findBaseAddress("libmfw.so");
if (moduleBase !== null) {
var baseaddr = moduleBase.add(0x6E3C+1);
hook_native_addr(baseaddr, 3);
} else {
console.log("Module not found: libencryptlib.so");
}
result:
call ————>libmfw.so!0x6e3d
,this.args0 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1edf28 b0 43 a2 b4 68 a9 d0 e0 20 92 7d d6 21 00 00 00 .C..h... .}.!...
be1edf38 00 b9 c0 c9 80 b0 93 b2 11 03 00 00 80 b0 93 b2 ................
be1edf48 14 00 00 00 00 00 00 00 01 23 45 67 89 ab cd ef .........#Eg....
be1edf58 fe dc ba 98 76 54 32 10 f0 e1 d2 c3 00 85 d4 d9 ....vT2.........
be1edf68 00 00 00 00 00 00 00 00 00 00 00 00 25 65 6d 61 ............%ema
be1edf78 35 31 44 33 37 38 33 38 31 35 32 31 00 00 80 37 51D378381521...7
be1edf88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1edf98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1edfa8 00 00 00 00 00 00 00 00 88 1a 00 00 70 66 af d9 ............pf..
be1edfb8 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
be1edfc8 f0 e1 d2 c3 48 14 a4 d3 00 00 00 00 00 00 00 00 ....H...........
be1edfd8 00 00 00 00 44 13 e2 9f 93 4d 27 3a a0 ea 4f fc ....D....M':..O.
be1edfe8 d0 e1 9c cf 8f 15 23 5a 00 00 00 80 00 00 00 00 ......#Z........
be1edff8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee008 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee018 a0 02 00 00 ac 05 96 a5 6f 49 cd 79 d8 0e c1 d5 ........oI.y....
,this.args1 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1ee020 6f 49 cd 79 d8 0e c1 d5 51 37 5d ae 2f 39 52 23 oI.y....Q7]./9R#
be1ee030 b0 0f 02 09 28 b9 c0 c9 aa 8d a1 d9 84 00 82 e0 ....(...........
be1ee040 06 00 00 00 21 b9 c0 c9 00 b9 c0 c9 aa 8d a1 d9 ....!...........
be1ee050 84 00 82 e0 06 00 00 00 08 47 51 13 af 8e a1 c0 .........GQ.....
be1ee060 88 e0 1e be 8c e0 1e be 01 00 00 00 f0 e1 1e be ................
be1ee070 84 00 82 e0 84 fe 1e be 05 00 00 00 08 47 51 13 .............GQ.
be1ee080 a8 de d4 12 c0 4f 51 13 e8 52 51 13 f8 52 51 13 .....OQ..RQ..RQ.
be1ee090 03 00 00 00 01 00 00 00 02 00 00 00 08 e3 1e be ................
be1ee0a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0e0 00 00 00 00 06 00 00 00 04 00 00 00 08 47 51 13 .............GQ.
be1ee0f0 00 00 00 00 98 e1 1e be 1c e1 1e be c7 db 2a e8 ..............*.
be1ee100 00 00 00 00 08 47 51 13 a8 de d4 12 c0 4f 51 13 .....GQ......OQ.
be1ee110 e8 52 51 13 f8 52 51 13 01 00 00 00 57 8f a2 c2 .RQ..RQ.....W...
,this.args2 onEnter: 0x14
,this.args0 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1edf28 b0 43 a2 b4 68 a9 d0 e0 20 92 7d d6 21 00 00 00 .C..h... .}.!...
be1edf38 00 b9 c0 c9 80 b0 93 b2 11 03 00 00 80 b0 93 b2 ................
be1edf48 14 00 00 00 00 00 00 00 01 23 45 67 89 ab cd ef .........#Eg....
be1edf58 fe dc ba 98 76 54 32 10 f0 e1 d2 c3 00 85 d4 d9 ....vT2.........
be1edf68 00 00 00 00 00 00 00 00 00 00 00 00 25 65 6d 61 ............%ema
be1edf78 35 31 44 33 37 38 33 38 31 35 32 31 00 00 80 37 51D378381521...7
be1edf88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1edf98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1edfa8 00 00 00 00 00 00 00 00 88 1a 00 00 70 66 af d9 ............pf..
be1edfb8 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
be1edfc8 f0 e1 d2 c3 48 14 a4 d3 00 00 00 00 00 00 00 00 ....H...........
be1edfd8 00 00 00 00 44 13 e2 9f 93 4d 27 3a a0 ea 4f fc ....D....M':..O.
be1edfe8 d0 e1 9c cf 8f 15 23 5a 00 00 00 80 00 00 00 00 ......#Z........
be1edff8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee008 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee018 a0 02 00 00 ac 05 96 a5 6f 49 cd 79 d8 0e c1 d5 ........oI.y....
,this.args1 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1ee020 6f 49 cd 79 d8 0e c1 d5 51 37 5d ae 2f 39 52 23 oI.y....Q7]./9R#
be1ee030 b0 0f 02 09 28 b9 c0 c9 aa 8d a1 d9 84 00 82 e0 ....(...........
be1ee040 06 00 00 00 21 b9 c0 c9 00 b9 c0 c9 aa 8d a1 d9 ....!...........
be1ee050 84 00 82 e0 06 00 00 00 08 47 51 13 af 8e a1 c0 .........GQ.....
be1ee060 88 e0 1e be 8c e0 1e be 01 00 00 00 f0 e1 1e be ................
be1ee070 84 00 82 e0 84 fe 1e be 05 00 00 00 08 47 51 13 .............GQ.
be1ee080 a8 de d4 12 c0 4f 51 13 e8 52 51 13 f8 52 51 13 .....OQ..RQ..RQ.
be1ee090 03 00 00 00 01 00 00 00 02 00 00 00 08 e3 1e be ................
be1ee0a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0e0 00 00 00 00 06 00 00 00 04 00 00 00 08 47 51 13 .............GQ.
be1ee0f0 00 00 00 00 98 e1 1e be 1c e1 1e be c7 db 2a e8 ..............*.
be1ee100 00 00 00 00 08 47 51 13 a8 de d4 12 c0 4f 51 13 .....GQ......OQ.
be1ee110 e8 52 51 13 f8 52 51 13 01 00 00 00 57 8f a2 c2 .RQ..RQ.....W...
,this.args2 onLeave: 0x14
,retval onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
bf995920 62 30 6e 4e 65 64 67 4f 77 64 56 52 4e 31 32 75 b0nNedgOwdVRN12u
bf995930 4c 7a 6c 53 49 37 41 50 41 67 6b 3d 00 00 67 00 LzlSI7APAgk=..g.
bf995940 01 00 00 00 35 00 00 00 00 00 01 00 00 00 00 00 ....5...........
bf995950 00 00 ee be 00 00 00 00 00 00 00 00 00 00 00 00 ................
bf995960 50 61 63 6b 61 67 65 4e 61 6d 65 00 76 61 72 63 PackageName.varc
bf995970 68 61 72 28 31 30 30 29 00 00 00 00 00 00 00 00 har(100)........
bf995980 01 00 00 00 50 00 00 00 00 20 00 00 00 00 00 00 ....P.... ......
bf995990 00 00 a9 be 00 00 00 00 00 00 00 00 00 00 00 00 ................
bf9959a0 78 53 25 cd 90 4d 35 c0 10 2a c3 c9 00 9d 49 ec xS%..M5..*....I.
bf9959b0 00 00 00 00 00 00 00 00 24 1b 00 00 00 3b 00 00 ........$....;..
bf9959c0 43 6f 6f 6b 69 65 4d 6f 6e 73 74 65 72 43 6c 69 CookieMonsterCli
bf9959d0 65 6e 74 00 74 43 6f 6f 6b 69 65 73 00 5f 41 00 ent.tCookies._A.
bf9959e0 01 00 00 00 cd 2b 7f cb 51 28 82 cb 67 33 c7 cb .....+..Q(..g3..
bf9959f0 c3 27 c7 cb 00 00 00 00 a0 c8 4f ec 58 7e 7d 3a .'........O.X~}:
bf995a00 00 00 00 00 00 00 00 00 e0 4b bc d9 00 65 63 75 .........K...ecu
bf995a10 51 00 00 00 45 00 00 00 a0 85 9a bf 60 15 9b bf Q...E.......`...
result: b0nNedgOwdVRN12uLzlSI7APAgk=
我们发现和我们JAVA层的HOOK的结果是一样的,那么v27很可能就是之前加密得到的结果了,因为v16是this,20是len
be1ee020 6f 49 cd 79 d8 0e c1 d5 51 37 5d ae 2f 39 52 23 oI.y....Q7]./9R#
be1ee030 b0 0f 02 09 28
我们通过base64解码,在进行to Hex的操作,其实就得到对应的数据,其实也就是上面的20个字节了
再去看看mfw::Sha1::CHmac::Final(v26, v27, 0x14u);
var baseaddr = moduleBase.add(0x06A80+1);
hook_native_addr(baseaddr, 3);
call ————>libmfw.so!0x6a81
,this.args0 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1edf50 4c 4a aa 42 0c c6 9d 82 cf 42 86 5d 43 bf 46 d7 LJ.B.....B.]C.F.
be1edf60 5f 26 c9 bd 00 85 d4 d9 0d 00 00 00 00 00 00 00 _&..............
be1edf70 11 00 00 00 25 65 6d 61 35 31 44 33 37 38 33 38 ....%ema51D37838
be1edf80 31 35 32 31 00 00 00 37 72 6f 77 73 44 33 25 64 1521...7rowsD3%d
be1edf90 73 73 61 70 64 72 6f 77 25 37 37 37 30 32 35 32 ssapdrow%7770252
be1edfa0 32 35 32 25 36 32 25 46 75 61 5f 78 75 5f 68 74 252%62%Fua_xu_ht
be1edfb0 6e 72 65 73 70 66 af d9 f1 21 43 0f a7 f6 3b c8 nrespf...!C...;.
be1edfc0 40 c5 b5 94 a2 85 54 6a b8 10 65 cc 48 14 a4 d3 @.....Tj..e.H...
be1edfd0 01 00 00 00 00 00 00 00 00 00 00 00 2f 3a 2f 3d ............/:/=
be1edfe0 18 18 1d 3d 69 69 1a 16 6e 6a 6e 3e 3f 65 65 38 ...=ii..njn>?ee8
be1edff0 3f 6b 3a 3a 68 6b 3f 3d 64 39 65 69 5c 5c 5c 7a ?k::hk?=d9ei\\\z
be1ee000 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c \\\\\\\\\\\\\\\\
be1ee010 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c 5c ac 05 96 a5 \\\\\\\\\\\\....
be1ee020 07 00 00 00 95 af 5f b9 84 00 82 e0 00 00 00 00 ......_.........
be1ee030 00 00 5c 00 28 b9 c0 c9 aa 8d a1 d9 84 00 82 e0 ..\.(...........
be1ee040 06 00 00 00 21 b9 c0 c9 00 b9 c0 c9 aa 8d a1 d9 ....!...........
,this.args1 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1ee020 07 00 00 00 95 af 5f b9 84 00 82 e0 00 00 00 00 ......_.........
be1ee030 00 00 5c 00 28 b9 c0 c9 aa 8d a1 d9 84 00 82 e0 ..\.(...........
be1ee040 06 00 00 00 21 b9 c0 c9 00 b9 c0 c9 aa 8d a1 d9 ....!...........
be1ee050 84 00 82 e0 06 00 00 00 08 47 51 13 af 8e a1 c0 .........GQ.....
be1ee060 88 e0 1e be 8c e0 1e be 01 00 00 00 f0 e1 1e be ................
be1ee070 84 00 82 e0 84 fe 1e be 05 00 00 00 08 47 51 13 .............GQ.
be1ee080 a8 de d4 12 c0 4f 51 13 e8 52 51 13 f8 52 51 13 .....OQ..RQ..RQ.
be1ee090 03 00 00 00 01 00 00 00 02 00 00 00 08 e3 1e be ................
be1ee0a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0e0 00 00 00 00 06 00 00 00 04 00 00 00 08 47 51 13 .............GQ.
be1ee0f0 00 00 00 00 98 e1 1e be 1c e1 1e be c7 db 2a e8 ..............*.
be1ee100 00 00 00 00 08 47 51 13 a8 de d4 12 c0 4f 51 13 .....GQ......OQ.
be1ee110 e8 52 51 13 f8 52 51 13 01 00 00 00 57 8f a2 c2 .RQ..RQ.....W...
,this.args2 onEnter: 0x14
,this.args0 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1edf50 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
be1edf60 f0 e1 d2 c3 00 85 d4 d9 00 00 00 00 00 00 00 00 ................
be1edf70 00 00 00 00 25 65 6d 61 35 31 44 33 37 38 33 38 ....%ema51D37838
be1edf80 31 35 32 31 00 00 80 37 00 00 00 00 00 00 00 00 1521...7........
be1edf90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1edfa0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1edfb0 88 1a 00 00 70 66 af d9 01 23 45 67 89 ab cd ef ....pf...#Eg....
be1edfc0 fe dc ba 98 76 54 32 10 f0 e1 d2 c3 48 14 a4 d3 ....vT2.....H...
be1edfd0 00 00 00 00 00 00 00 00 00 00 00 00 44 13 e2 9f ............D...
be1edfe0 93 4d 27 3a a0 ea 4f fc d0 e1 9c cf 8f 15 23 5a .M':..O.......#Z
be1edff0 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee010 00 00 00 00 00 00 00 00 a0 02 00 00 ac 05 96 a5 ................
be1ee020 6f 49 cd 79 d8 0e c1 d5 51 37 5d ae 2f 39 52 23 oI.y....Q7]./9R#
be1ee030 b0 0f 02 09 28 b9 c0 c9 aa 8d a1 d9 84 00 82 e0 ....(...........
be1ee040 06 00 00 00 21 b9 c0 c9 00 b9 c0 c9 aa 8d a1 d9 ....!...........
,this.args1 onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1ee020 6f 49 cd 79 d8 0e c1 d5 51 37 5d ae 2f 39 52 23 oI.y....Q7]./9R#
be1ee030 b0 0f 02 09 28 b9 c0 c9 aa 8d a1 d9 84 00 82 e0 ....(...........
be1ee040 06 00 00 00 21 b9 c0 c9 00 b9 c0 c9 aa 8d a1 d9 ....!...........
be1ee050 84 00 82 e0 06 00 00 00 08 47 51 13 af 8e a1 c0 .........GQ.....
be1ee060 88 e0 1e be 8c e0 1e be 01 00 00 00 f0 e1 1e be ................
be1ee070 84 00 82 e0 84 fe 1e be 05 00 00 00 08 47 51 13 .............GQ.
be1ee080 a8 de d4 12 c0 4f 51 13 e8 52 51 13 f8 52 51 13 .....OQ..RQ..RQ.
be1ee090 03 00 00 00 01 00 00 00 02 00 00 00 08 e3 1e be ................
be1ee0a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee0e0 00 00 00 00 06 00 00 00 04 00 00 00 08 47 51 13 .............GQ.
be1ee0f0 00 00 00 00 98 e1 1e be 1c e1 1e be c7 db 2a e8 ..............*.
be1ee100 00 00 00 00 08 47 51 13 a8 de d4 12 c0 4f 51 13 .....GQ......OQ.
be1ee110 e8 52 51 13 f8 52 51 13 01 00 00 00 57 8f a2 c2 .RQ..RQ.....W...
,this.args2 onLeave: 0x14
,retval onLeave: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
be1edfb8 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 .#Eg........vT2.
be1edfc8 f0 e1 d2 c3 48 14 a4 d3 00 00 00 00 00 00 00 00 ....H...........
be1edfd8 00 00 00 00 44 13 e2 9f 93 4d 27 3a a0 ea 4f fc ....D....M':..O.
be1edfe8 d0 e1 9c cf 8f 15 23 5a 00 00 00 80 00 00 00 00 ......#Z........
be1edff8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee008 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
be1ee018 a0 02 00 00 ac 05 96 a5 6f 49 cd 79 d8 0e c1 d5 ........oI.y....
be1ee028 51 37 5d ae 2f 39 52 23 b0 0f 02 09 28 b9 c0 c9 Q7]./9R#....(...
be1ee038 aa 8d a1 d9 84 00 82 e0 06 00 00 00 21 b9 c0 c9 ............!...
be1ee048 00 b9 c0 c9 aa 8d a1 d9 84 00 82 e0 06 00 00 00 ................
be1ee058 08 47 51 13 af 8e a1 c0 88 e0 1e be 8c e0 1e be .GQ.............
be1ee068 01 00 00 00 f0 e1 1e be 84 00 82 e0 84 fe 1e be ................
be1ee078 05 00 00 00 08 47 51 13 a8 de d4 12 c0 4f 51 13 .....GQ......OQ.
be1ee088 e8 52 51 13 f8 52 51 13 03 00 00 00 01 00 00 00 .RQ..RQ.........
be1ee098 02 00 00 00 08 e3 1e be 00 00 00 00 00 00 00 00 ................
be1ee0a8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
base64的明文确实是从这里传过去的
再看看mfw::Sha1::CHmac::Update(v26, v21, v22);
if (moduleBase !== null)
{;;//32位程序要++1
var Input = moduleBase.add(0x0082A4+1);;
Interceptor.attach(Input,{
onEnter:function(args){
console.log("Input.onEnter:");
console.log(args[1].readCString());
},
onLeave:function(result){
}
}),
hook_native_addr(baseaddr, 3);
这里发现了从JAVA层传来的数据,所有使用了args[1].readCString()直接读完
result:
Input.onEnter:
PUT&https%3A%2F%2Fmapi.mafengwo.cn%2Frest%2Fapp%2Fuser%2Flogin%2F&after_style%3Ddefault%26app_code%3Dcom.mfw.roadbook%26app_ver%3D8.1.6%26app_version_code%3D535%26brand%3Dgoogle%26channel_id%3DGROWTH-WAP-LC-3%26device_id%3D40%253A4E%253A36%253A24%253A41%253AC1%26device_type%3Dandroid%26hardware_model%3DPixel%2520XL%26mfwsdk_ver%3D20140507%26oauth_consumer_key%3D5%26oauth_nonce%3D1b6be857-bec5-4302-97be-6778d3bed316%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1727240426%26oauth_version%3D1.0%26open_udid%3D40%253A4E%253A36%253A24%253A41%253AC1%26put_style%3Ddefault%26screen_height%3D2392%26screen_scale%3D3.5%26screen_width%3D1440%26sys_ver%3D10%26time_offset%3D480%26x_auth_mode%3Dclient_auth%26x_auth_password%3Dpassword777%2520%252F%26x_auth_username%3D15838712517
其实我们可以通过函数定义里面就可以看到大概率是HAMC_SHA1的加密同时上面还要SetKey()来设置KEY
一起HOOK了
var baseaddr = moduleBase.add(0x06938+1);
hook_native_addr(baseaddr, 3);
this.args1 onEnter: 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
c9c0b900 61 73 66 73 61 41 44 44 4a 46 35 35 62 32 36 32 asfsaADDJF55b262
c9c0b910 64 39 39 63 66 66 37 63 61 63 37 34 35 39 65 38 d99cff7cac7459e8
c9c0b920 26 00 0a 00 00 00 00 00 50 b9 c0 c9 00 00 00 c0 &.......P.......
c9c0b930 00 1e 23 ec 01 00 00 00 00 00 00 00 01 00 00 00 ..#.............
c9c0b940 00 00 00 00 00 00 c0 e0 40 97 20 ec 01 00 00 00 ........@. .
asfsaADDJF55b262d99cff7cac7459e8&
这里就可以得到KEY了
那么我们看看是不是标准HMAC_SHA1
这样就得到Sign了
标签:00,java,51,马蜂窝,旅游,mfw,var,com From: https://www.cnblogs.com/ovo-fisherman/p/18431734