-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathSSLKillSwitch.js
185 lines (139 loc) · 5.3 KB
/
SSLKillSwitch.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
Thanks to Alban Diquet for his SSL Kill Switch 2 project - https://github.com/nabla-c0d3/ssl-kill-switch2
*/
'use strict';
/*
Stuff from nabla-c0d3's SSL Kill Switch 2 (https://github.com/nabla-c0d3/ssl-kill-switch2) converted to run with Frida.
No idea currently why all of this does not work with iOS 10.
*/
var errSSLServerAuthCompleted = -9481; /* <Security/SecureTransport.h> peer cert is valid, or was ignored if verification disabled */
var kSSLSessionOptionBreakOnServerAuth = 0;
var noErr = 0;
/* OSStatus SSLHandshake ( SSLContextRef context ); */
var SSLHandshake = new NativeFunction(
Module.findExportByName("Security", "SSLHandshake"),
'int',
['pointer']
);
Interceptor.replace(SSLHandshake, new NativeCallback(function (context) {
var result = SSLHandshake(context);
// Hijack the flow when breaking on server authentication
if (result == errSSLServerAuthCompleted) {
console.log("Relacing SSLHandshake");
// Do not check the cert and call SSLHandshake() again
return SSLHandshake(context);
}
return result;
}, 'int', ['pointer']));
/* SSLContextRef SSLCreateContext ( CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType ); */
var SSLCreateContext = new NativeFunction(
Module.findExportByName("Security", "SSLCreateContext"),
'pointer',
['pointer', 'int', 'int']
);
Interceptor.replace(SSLCreateContext, new NativeCallback(function (alloc, protocolSide, connectionType) {
console.log("Relacing SSLCreateContext");
var sslContext = SSLCreateContext(alloc, protocolSide, connectionType);
// Immediately set the kSSLSessionOptionBreakOnServerAuth option in order to disable cert validation
SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnServerAuth, 1);
return sslContext;
}, 'pointer', ['pointer', 'int', 'int']));
/* OSStatus SSLSetSessionOption ( SSLContextRef context, SSLSessionOption option, Boolean value );*/
var SSLSetSessionOption = new NativeFunction(
Module.findExportByName("Security", "SSLSetSessionOption"),
'int',
['pointer', 'int', 'bool']
);
Interceptor.replace(SSLSetSessionOption, new NativeCallback(function (context, option, value) {
// Remove the ability to modify the value of the kSSLSessionOptionBreakOnServerAuth option
if (option == kSSLSessionOptionBreakOnServerAuth) {
console.log("Relacing SSLSetSessionOption");
return noErr;
}
return SSLSetSessionOption(context, option, value);
}, 'int', ['pointer', 'int', 'bool']));
/*
The old way of killing SSL Pinning
*/
// SecTrustResultType
var kSecTrustResultInvalid = 0;
var kSecTrustResultProceed = 1;
// var kSecTrustResultConfirm = 2 // Deprecated
var kSecTrustResultDeny = 3;
var kSecTrustResultUnspecified = 4;
var kSecTrustResultRecoverableTrustFailure = 6;
var kSecTrustResultFatalTrustFailure = 6;
var kSecTrustResultOtherError = 7;
/*
OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result);
*/
var SecTrustEvaluate = new NativeFunction(
Module.findExportByName("Security", "SecTrustEvaluate"),
'int',
['pointer', 'pointer']
);
Interceptor.replace(SecTrustEvaluate, new NativeCallback(function (trust, result) {
console.log("Relacing SecTrustEvaluate");
var ret = SecTrustEvaluate(trust, result);
result = kSecTrustResultProceed;
return ret;
}, 'int', ['pointer', 'pointer']));
/*
Killing SSL Pinning of some of the commonly encountered frameworks
*/
if (ObjC.classes.AFSecurityPolicy) {
/* AFNetworking */
Interceptor.attach(ObjC.classes.AFSecurityPolicy['- setSSLPinningMode:'].implementation, {
onEnter: function (args) {
console.log("Relacing AFSecurityPolicy setSSLPinningMode = 0 was " + args[2]);
args[2] = ptr('0x0');
}
});
Interceptor.attach(ObjC.classes.AFSecurityPolicy['- setAllowInvalidCertificates:'].implementation, {
onEnter: function (args) {
console.log("Relacing AFSecurityPolicy setAllowInvalidCertificates = 1 was " + args[2]);
args[2] = ptr('0x1');
}
});
}
if (ObjC.classes.KonyUtil) {
/* Kony */
Interceptor.attach(ObjC.classes.KonyUtil['+ shouldAllowSelfSignedCertificate'].implementation, {
onLeave: function (retval) {
console.log("Relacing KonyUtil shouldAllowSelfSignedCertificate = 1 was " + retval);
retval.replace(0x1);
}
});
Interceptor.attach(ObjC.classes.KonyUtil['+ shouldAllowBundledWithSystemDefault'].implementation, {
onLeave: function (retval) {
console.log("Relacing KonyUtil shouldAllowBundledWithSystemDefault = 1 was " + retval);
retval.replace(0x1);
}
});
Interceptor.attach(ObjC.classes.KonyUtil['+ shouldAllowBundledOnly'].implementation, {
onLeave: function (retval) {
console.log("Relacing KonyUtil shouldAllowBundledOnly = 0 was " + retval);
retval.replace(0x0);
}
});
}
/*
Other uncommon crap that I come across
*/
if (ObjC.classes.VGuardManager) {
/* vkey */
Interceptor.attach(ObjC.classes.VGuardManager['- setEnableSSLPinning:'].implementation, {
onEnter: function (args) {
console.log("Relacing VGuardManager setEnableSSLPinning = 0 was " + args[2]);
args[2] = ptr('0x0');
}
});
}
if (ObjC.classes.eAhJgIkSdNCToZQwjpbnNbjfvZlYUSbyIFtfxkXSgI) {
Interceptor.attach(ObjC.classes.eAhJgIkSdNCToZQwjpbnNbjfvZlYUSbyIFtfxkXSgI['- setIsSSLHookDetected:'].implementation, {
onEnter: function (args) {
console.log("Relacing eAhJgIkSdNCToZQwjpbnNbjfvZlYUSbyIFtfxkXSgI setIsSSLHookDetected = 0 was " + args[2]);
args[2] = ptr('0x0');
}
});
}