抓包应该是我们逆向的第一步,只有先抓到包,才能决定我们是否要进行脱壳、逆向。万一他没有加密、万一数据不是我们想要的那岂不是白忙活了。但是目前很APP都设置了门槛,比如新版的抖音、淘宝、天眼查等挂上代理就直接无数据或者就显示不出你想要的数据。还没有开始就直接结束了,让人懊恼不已。没办法只能上科技与狠活了。(感谢r0ysue肉师傅,以下很多素材都来源于他)
这个一般我们设置好IP和端口,导入证书不出意外是没问题。常见的抓包工具fiddler、charles、Burpsuite、httpcanary
针对双向证书绑定的APP,打印和保存证书,再导入到抓包工具中。
将证书导出后,charles进行证书配置。
ssl pinning 证书在代码中的额外校验:
objection 中的 Bypass SSL pinning hook的证书种类:
DroidSSLUnpinning 这个工具是WooyunDota瘦蛟舞大佬总结的,github上有源码,以下我也贴出来了,他总结了一些常见的证书过检测的方法。
使用方法:
1 attach : frida -U com.example.mennomorsink.webviewtest2 --no-pause -l hooks.js
2 spawn : frida -U -f com.example.mennomorsink.webviewtest2 -l hooks.js --no-pause
如果APP出现了混淆,使用 objection、DroidSSLUnpinning都无法成功hook住,首先不要慌,我们的目标还是先搞清楚他用的是什么框架。可以hook java.io.File类,因为校验证书的过程中,必然要打开它,通过打印的调栈再结合源码可以分析出到底使用了什么框架。
r0capture安卓应用层抓包通杀脚本这个工具比较厉害,无视所有证书校验或绑定,不用考虑任何证书的事情。
Spawn 模式:
python3 r0capture.py -U -f com.coolapk.market -v
Attach 模式,抓包内容保存成pcap文件供后续分析:
python3 r0capture.py -U 酷安 -v -p iqiyi.pcap
function hook_KeyStore_load() {
Java.perform(function () {
var ByteString
=
Java.use(
"com.android.okhttp.okio.ByteString"
);
var myArray
=
new Array(
1024
);
var i
=
0
for
(i
=
0
; i < myArray.length; i
+
+
) {
myArray[i]
=
0x0
;
}
var
buffer
=
Java.array(
'byte'
, myArray);
var StringClass
=
Java.use(
"java.lang.String"
);
var KeyStore
=
Java.use(
"java.security.KeyStore"
);
KeyStore.load.overload(
'java.security.KeyStore$LoadStoreParameter'
).implementation
=
function (arg0) {
/
/
可以在此打印调用栈观察信息
console.log(
"KeyStore.load1:"
, arg0);
this.load(arg0);
};
KeyStore.load.overload(
'java.io.InputStream'
,
'[C'
).implementation
=
function (arg0, arg1) {
/
/
可以在此打印调用栈观察信息
console.log(
"KeyStore.load2:"
, arg0, arg1 ? StringClass.$new(arg1) : null);
if
(arg0) {
var
file
=
Java.use(
"java.io.File"
).$new(
"/sdcard/Download/"
+
String(arg0)
+
".p12"
);
var out
=
Java.use(
"java.io.FileOutputStream"
).$new(
file
);
var r;
while
((r
=
arg0.read(
buffer
)) >
0
) {
out.write(
buffer
,
0
, r)
}
console.log(
"save success!"
)
out.close()
}
this.load(arg0, arg1);
};
console.log(
"hook_KeyStore_load..."
);
});
}
function hook_KeyStore_load() {
Java.perform(function () {
var ByteString
=
Java.use(
"com.android.okhttp.okio.ByteString"
);
var myArray
=
new Array(
1024
);
var i
=
0
for
(i
=
0
; i < myArray.length; i
+
+
) {
myArray[i]
=
0x0
;
}
var
buffer
=
Java.array(
'byte'
, myArray);
var StringClass
=
Java.use(
"java.lang.String"
);
var KeyStore
=
Java.use(
"java.security.KeyStore"
);
KeyStore.load.overload(
'java.security.KeyStore$LoadStoreParameter'
).implementation
=
function (arg0) {
/
/
可以在此打印调用栈观察信息
console.log(
"KeyStore.load1:"
, arg0);
this.load(arg0);
};
KeyStore.load.overload(
'java.io.InputStream'
,
'[C'
).implementation
=
function (arg0, arg1) {
/
/
可以在此打印调用栈观察信息
console.log(
"KeyStore.load2:"
, arg0, arg1 ? StringClass.$new(arg1) : null);
if
(arg0) {
var
file
=
Java.use(
"java.io.File"
).$new(
"/sdcard/Download/"
+
String(arg0)
+
".p12"
);
var out
=
Java.use(
"java.io.FileOutputStream"
).$new(
file
);
var r;
while
((r
=
arg0.read(
buffer
)) >
0
) {
out.write(
buffer
,
0
, r)
}
console.log(
"save success!"
)
out.close()
}
this.load(arg0, arg1);
};
console.log(
"hook_KeyStore_load..."
);
});
}
function hook_ssl() {
Java.perform(function () {
var ClassName
=
"com.android.org.conscrypt.Platform"
;
var Platform
=
Java.use(ClassName);
var targetMethod
=
"checkServerTrusted"
;
var
len
=
Platform[targetMethod].overloads.length;
console.log(
len
);
for
(var i
=
0
; i <
len
;
+
+
i) {
Platform[targetMethod].overloads[i].implementation
=
function () {
console.log(
"class:"
, ClassName,
"target:"
, targetMethod,
" i:"
, i, arguments);
}
}
});
}
function hook_ssl() {
Java.perform(function () {
var ClassName
=
"com.android.org.conscrypt.Platform"
;
var Platform
=
Java.use(ClassName);
var targetMethod
=
"checkServerTrusted"
;
var
len
=
Platform[targetMethod].overloads.length;
console.log(
len
);
for
(var i
=
0
; i <
len
;
+
+
i) {
Platform[targetMethod].overloads[i].implementation
=
function () {
console.log(
"class:"
, ClassName,
"target:"
, targetMethod,
" i:"
, i, arguments);
}
}
});
}
sslContextEmptyTrustManager
const x509TrustManager: X509TrustManager
=
Java.use(
"javax.net.ssl.X509TrustManager"
);
const sSLContext: SSLContext
=
Java.use(
"javax.net.ssl.SSLContext"
);
okHttp3CertificatePinnerCheck
const certificatePinner: CertificatePinner
=
Java.use(
"okhttp3.CertificatePinner"
);
okHttp3CertificatePinnerCheckOkHttp
const certificatePinner: CertificatePinner
=
Java.use(
"okhttp3.CertificatePinner"
);
appceleratorTitaniumPinningTrustManager
const pinningTrustManager: PinningTrustManager
=
Java.use(
"appcelerator.https.PinningTrustManager"
);
/
/
Android
7
+
TrustManagerImpl.verifyChain()
trustManagerImplVerifyChainCheck
const trustManagerImpl: TrustManagerImpl
=
Java.use(
"com.android.org.conscrypt.TrustManagerImpl"
);
const TrustManagerImplverifyChain
=
trustManagerImpl.verifyChain;
/
/
Android
7
+
TrustManagerImpl.checkTrustedRecursive()
trustManagerImplCheckTrustedRecursiveCheck
const trustManagerImpl: TrustManagerImpl
=
Java.use(
"com.android.org.conscrypt.TrustManagerImpl"
);
const TrustManagerImplcheckTrustedRecursive
=
trustManagerImpl.checkTrustedRecursive;
phoneGapSSLCertificateChecker
const sslCertificateChecker: SSLCertificateChecker
=
Java.use(
"nl.xservices.plugins.SSLCertificateChecker"
);
sslContextEmptyTrustManager
const x509TrustManager: X509TrustManager
=
Java.use(
"javax.net.ssl.X509TrustManager"
);
const sSLContext: SSLContext
=
Java.use(
"javax.net.ssl.SSLContext"
);
okHttp3CertificatePinnerCheck
const certificatePinner: CertificatePinner
=
Java.use(
"okhttp3.CertificatePinner"
);
okHttp3CertificatePinnerCheckOkHttp
const certificatePinner: CertificatePinner
=
Java.use(
"okhttp3.CertificatePinner"
);
appceleratorTitaniumPinningTrustManager
const pinningTrustManager: PinningTrustManager
=
Java.use(
"appcelerator.https.PinningTrustManager"
);
/
/
Android
7
+
TrustManagerImpl.verifyChain()
trustManagerImplVerifyChainCheck
const trustManagerImpl: TrustManagerImpl
=
Java.use(
"com.android.org.conscrypt.TrustManagerImpl"
);
const TrustManagerImplverifyChain
=
trustManagerImpl.verifyChain;
/
/
Android
7
+
TrustManagerImpl.checkTrustedRecursive()
trustManagerImplCheckTrustedRecursiveCheck
const trustManagerImpl: TrustManagerImpl
=
Java.use(
"com.android.org.conscrypt.TrustManagerImpl"
);
const TrustManagerImplcheckTrustedRecursive
=
trustManagerImpl.checkTrustedRecursive;
phoneGapSSLCertificateChecker
const sslCertificateChecker: SSLCertificateChecker
=
Java.use(
"nl.xservices.plugins.SSLCertificateChecker"
);
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使用.
var X509Certificate
=
Java.use(
"java.security.cert.X509Certificate"
);
var TrustManager;
try
{
TrustManager
=
Java.registerClass({
name:
'org.wooyun.TrustManager'
,
implements: [X509TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},
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
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.'
);
}
} 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(
"javax.net.ssl.HttpsURLConnection"
);
/
*
libcore
/
luni
/
src
/
main
/
java
/
javax
/
net
/
ssl
/
HttpsURLConnection.java
*
/
/
*
public void setDefaultHostnameVerifier(HostnameVerifier)
*
/
HttpsURLConnection.setDefaultHostnameVerifier.implementation
=
function(hostnameVerifier) {
quiet_send(
"HttpsURLConnection.setDefaultHostnameVerifier invoked"
);
return
null;
};
/
*
libcore
/
luni
/
src
/
main
/
java
/
javax
/
net
/
ssl
/
HttpsURLConnection.java
*
/
/
*
public void setSSLSocketFactory(SSLSocketFactory)
*
/
HttpsURLConnection.setSSLSocketFactory.implementation
=
function(SSLSocketFactory) {
quiet_send(
"HttpsURLConnection.setSSLSocketFactory invoked"
);
return
null;
};
/
*
libcore
/
luni
/
src
/
main
/
java
/
javax
/
net
/
ssl
/
HttpsURLConnection.java
*
/
/
*
public void setHostnameVerifier(HostnameVerifier)
*
/
HttpsURLConnection.setHostnameVerifier.implementation
=
function(hostnameVerifier) {
quiet_send(
"HttpsURLConnection.setHostnameVerifier invoked"
);
return
null;
};
/
*
*
*
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
/
/
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
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
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'
)
}
});
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使用.
var X509Certificate
=
Java.use(
"java.security.cert.X509Certificate"
);
var TrustManager;
try
{
TrustManager
=
Java.registerClass({
name:
'org.wooyun.TrustManager'
,
implements: [X509TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},
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
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.'
);
}
} 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);
}
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-1-3 17:49
被西贝巴巴编辑
,原因: 修改标题