-
Notifications
You must be signed in to change notification settings - Fork 158
/
tiktok-ssl-pinning-bypass.js
151 lines (137 loc) · 5.23 KB
/
tiktok-ssl-pinning-bypass.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
function waitForModule(moduleName) {
return new Promise(resolve => {
const interval = setInterval(() => {
const module = Process.findModuleByName(moduleName);
if (module != null) {
clearInterval(interval);
resolve(module);
}
}, 0);
});
}
//Only needed when apk is patched with frida-gadget
//spoofSignature()
function spoofSignature() {
const originalSignature = "<ORIGINAL_APK_SIGNATURE>" //This will be set by patch_apk.py
Java.perform(() => {
const PackageManager = Java.use("android.app.ApplicationPackageManager");
const Signature = Java.use("android.content.pm.Signature");
const ActivityThread = Java.use('android.app.ActivityThread');
PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(a, b) {
const packageInfo = this.getPackageInfo(a, b);
const context = ActivityThread.currentApplication().getApplicationContext();
const name = context.getPackageName();
if (a == name && b == 64) {
const signature = Signature.$new(originalSignature);
packageInfo.signatures.value = Java.array('android.content.pm.Signature', [signature]);
}
return packageInfo;
}
});
}
function hook_certVerify(lib) {
const arm_offset = "<ARM_OFFSET>";
const arm64_offset = "<ARM64_OFFSET>";
let offset = ptr(0);
if (Process.arch == "arm" && !isNaN(arm_offset)) {
offset = ptr(arm_offset);
} else if (Process.arch == "arm64" && !isNaN(arm64_offset)) {
offset = ptr(arm64_offset);
} else {
logger("[*][-] You need to run gen_script.py first.");
return;
}
const f = lib.base.add(offset);
try {
hook_callback(f);
logger(`[*][+] Hooked certVerify at offset: ${offset}`);
}catch(e){
logger(`[*][-] Failed to hook certVerify at offset: ${offset}`);
}
}
function hook_callback(callback) {
const f = new NativeFunction(callback, "int", ["pointer", "pointer"]);
Interceptor.attach(f, {
onLeave: function(retval) {
retval.replace(0)
}
})
}
function hook_SSL_CTX_set_custom_verify(library) {
const functionName = "SSL_CTX_set_custom_verify"
try {
const f = Module.getExportByName(library.name, functionName);
const SSL_CTX_set_custom_verify = new NativeFunction(f, 'void', ['pointer', 'int', 'pointer'])
Interceptor.replace(SSL_CTX_set_custom_verify, new NativeCallback(function(ssl, mode, callback) {
hook_callback(callback);
SSL_CTX_set_custom_verify(ssl, mode, callback)
}, 'void', ['pointer', 'int', 'pointer']));
logger(`[*][+] Hooked function: ${functionName}`);
} catch (err) {
logger(`[*][-] Failed to hook function: ${functionName}`);
logger(err.toString())
}
}
function logger(message) {
console.log(message);
Java.perform(function() {
var Log = Java.use("android.util.Log");
Log.v("TIKTOK_SSL_PINNING_BYPASS", message);
});
}
logger("[*][*] Waiting for libttboringssl...");
waitForModule("libttboringssl.so").then((lib) => {
logger(`[*][+] Found libttboringssl at: ${lib.base}`)
hook_SSL_CTX_set_custom_verify(lib);
});
logger("[*][*] Waiting for libsscronet...");
waitForModule("libsscronet.so").then((lib) => {
logger(`[*][+] Found libsscronet at: ${lib.base}`)
hook_certVerify(lib);
});
//Universal Android SSL Pinning Bypass #2
Java.perform(function() {
try {
var array_list = Java.use("java.util.ArrayList");
var ApiClient = Java.use('com.android.org.conscrypt.TrustManagerImpl');
if (ApiClient.checkTrustedRecursive) {
logger("[*][+] Hooked checkTrustedRecursive")
ApiClient.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) {
var k = array_list.$new();
return k;
}
} else {
logger("[*][-] checkTrustedRecursive not Found")
}
} catch (e) {
logger("[*][-] Failed to hook checkTrustedRecursive")
}
});
Java.perform(function() {
try {
const x509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
const sSLContext = Java.use("javax.net.ssl.SSLContext");
const TrustManager = Java.registerClass({
implements: [x509TrustManager],
methods: {
checkClientTrusted(chain, authType) {
},
checkServerTrusted(chain, authType) {
},
getAcceptedIssuers() {
return [];
},
},
name: "com.leftenter.tiktok",
});
const TrustManagers = [TrustManager.$new()];
const SSLContextInit = sSLContext.init.overload(
"[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom");
SSLContextInit.implementation = function(keyManager, trustManager, secureRandom) {
SSLContextInit.call(this, keyManager, TrustManagers, secureRandom);
};
logger("[*][+] Hooked SSLContextInit")
} catch (e) {
logger("[*][-] Failed to hook SSLContextInit")
}
})