-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathsnapchat-ssl-pinning-bypass.js
137 lines (121 loc) · 4.66 KB
/
snapchat-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
const pattern_arm64 = 'fd 7b ba a9 fc 6f 01 a9 fa 67 02 a9 f8 5f 03 a9 f6 57 04 a9 f4 4f 05 a9 fd 03 00 91 ff 43 0e d1 53';
const pattern_arm = '2d e9 f0 4f ad f5 0b 7d 81 46 b5 48';
//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");
PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function (a, b) {
const packageInfo = this.getPackageInfo(a, b);
if (a == "com.snapchat.android" && b == 64) {
const signature = Signature.$new(originalSignature);
packageInfo.signatures.value = Java.array('android.content.pm.Signature', [signature]);
}
return packageInfo;
}
});
}
function hook_PKPState_CheckPublicKeyPins_by_pattern(library, pattern) {
let found = false;
Memory.scan(library.base, library.size, pattern, {
onMatch(address, size) {
found = true;
hook_PKPState_CheckPublicKeyPins_by_address(address);
return 'stop';
},
onComplete() {
if (!found) {
logger("[*][-] Failed to find PKPState->CheckPublicKeyPins function")
}
}
});
}
function hook_PKPState_CheckPublicKeyPins_by_offset(library, offset) {
hook_PKPState_CheckPublicKeyPins_by_address(library.base.add(offset));
}
function hook_PKPState_CheckPublicKeyPins_by_address(address) {
try {
const thumb = Process.arch == "arm" ? 1 : 0
Interceptor.attach(address.add(thumb), {
onLeave: function (retvalue) {
retvalue.replace(1);
}
});
logger("[*][+] Hooked KPState->CheckPublicKeyPins");
} catch (e) {
logger("[*][-] Failed to hook function: KPState->CheckPublicKeyPins")
}
}
function logger(message) {
console.log(message);
Java.perform(function () {
var Log = Java.use("android.util.Log");
Log.v("SNAPCHAT_SSL_PINNING_BYPASS", message);
});
}
function waitForModule(moduleName) {
return new Promise(resolve => {
const interval = setInterval(() => {
const module = Process.findModuleByName(moduleName);
if (module != null) {
clearInterval(interval);
resolve(module);
}
}, 10);
});
}
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.snapchat",
});
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")
}
});
waitForModule("libclient.so").then(lib => {
//hook_PKPState_CheckPublicKeyPins_by_offset(lib, offset) // get offset with static analyse
if (Process.arch == "arm64") {
hook_PKPState_CheckPublicKeyPins_by_pattern(lib, pattern_arm64);
} else if (Process.arch == "arm") {
hook_PKPState_CheckPublicKeyPins_by_pattern(lib, pattern_arm);
}
});