forked from julioverne/ssl-kill-switch2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SSLKillSwitch2.xm
134 lines (112 loc) · 4.58 KB
/
SSLKillSwitch2.xm
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
#import <Foundation/Foundation.h>
#import <Security/SecureTransport.h>
#import <dlfcn.h>
#import <substrate.h>
extern const char* __progname;
#define PREFERENCE_FILE @"/private/var/mobile/Library/Preferences/com.nablac0d3.SSLKillSwitchSettings.plist"
#define PREFERENCE_KEY @"shouldDisableCertificateValidation"
static inline void SSKLog(NSString *format, ...)
{
@autoreleasepool {
NSString *newFormat = [[NSString alloc] initWithFormat:@"=== SSL Kill Switch 2: %@", format];
va_list args;
va_start(args, format);
NSLogv(newFormat, args);
va_end(args);
}
}
static inline BOOL shouldHookFromPreference(NSString *preferenceSetting)
{
@autoreleasepool {
//Disable in apsd, prevent this break push notification
if(strcmp(__progname, "apsd")==0) {
return NO;
}
BOOL shouldHook = NO;
NSDictionary* plist = [[NSDictionary alloc] initWithContentsOfFile:PREFERENCE_FILE]?:@{};
shouldHook = [plist[preferenceSetting]?:@YES boolValue];
SSKLog(@"Preference set to %d.", shouldHook);
if(shouldHook) {
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
bundleId = [bundleId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *excludedBundleIdsString = plist[@"excludedBundleIds"]?:@"";
excludedBundleIdsString = [excludedBundleIdsString stringByReplacingOccurrencesOfString:@" " withString:@""];
NSArray *excludedBundleIds = [excludedBundleIdsString componentsSeparatedByString:@","]?:@[];
if ([excludedBundleIds containsObject:bundleId]) {
SSKLog(@"Not hooking excluded bundle: %@", bundleId);
shouldHook = NO;
}
}
return shouldHook;
}
}
#pragma mark SecureTransport hooks - iOS 9 and below
static OSStatus (*original_SSLSetSessionOption)(SSLContextRef context, SSLSessionOption option, Boolean value);
static OSStatus replaced_SSLSetSessionOption(SSLContextRef context, SSLSessionOption option, Boolean value)
{
if(option == kSSLSessionOptionBreakOnServerAuth) {
return noErr;
}
return original_SSLSetSessionOption(context, option, value);
}
static SSLContextRef (*original_SSLCreateContext)(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType);
static SSLContextRef replaced_SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
{
SSLContextRef sslContext = original_SSLCreateContext(alloc, protocolSide, connectionType);
//SSLSetClientSideAuthenticate(sslContext, kNeverAuthenticate);
//original_SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnCertRequested, false);
original_SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnServerAuth, true);
//original_SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnClientAuth, false);
return sslContext;
}
static OSStatus (*original_SSLHandshake)(SSLContextRef context);
static OSStatus replaced_SSLHandshake(SSLContextRef context)
{
OSStatus result = original_SSLHandshake(context);
if (result == errSSLServerAuthCompleted) {
return original_SSLHandshake(context);
}
return result;
}
#pragma mark BoringSSL hooks - iOS 12 - 13
static int custom_verify_callback_that_does_not_validate(void *ssl, uint8_t *out_alert)
{
return 0;
}
static void (*original_SSL_set_custom_verify)(void *ssl, int mode, int (*callback)(void *ssl, uint8_t *out_alert));
static void replaced_SSL_set_custom_verify(void *ssl, int mode, int (*callback)(void *ssl, uint8_t *out_alert))
{
original_SSL_set_custom_verify(ssl, 0, custom_verify_callback_that_does_not_validate);
}
static void (*original_SSL_CTX_set_custom_verify)(void *ctx, int mode, int (*callback)(void *ssl, uint8_t *out_alert));
static void replaced_SSL_CTX_set_custom_verify(void *ctx, int mode, int (*callback)(void *ssl, uint8_t *out_alert))
{
original_SSL_CTX_set_custom_verify(ctx, 0, custom_verify_callback_that_does_not_validate);
}
static char *(*original_SSL_get_psk_identity)(void *ssl);
static char *replaced_SSL_get_psk_identity(void *ssl)
{
return (char *)"notarealPSKidentity";
}
%ctor
{
if(shouldHookFromPreference(PREFERENCE_KEY)) {
// load for bind symbols
dlopen("/usr/lib/libboringssl.dylib", RTLD_NOW);
#define HOOKFN(fName) \
void* sym##fName = dlsym(RTLD_DEFAULT, ""#fName""); \
if(sym##fName != NULL) { \
MSHookFunction(sym##fName,(void *) replaced_##fName, (void **) &original_##fName); \
} else { \
SSKLog(@"Symbol[%s] Not Resolved.", ""#fName""); \
}
// Security.framework
HOOKFN(SSLSetSessionOption)
HOOKFN(SSLHandshake)
HOOKFN(SSLCreateContext)
// libboringssl.dylib
HOOKFN(SSL_set_custom_verify)
HOOKFN(SSL_CTX_set_custom_verify)
HOOKFN(SSL_get_psk_identity)
}
}