12
12
import sys
13
13
import tempfile
14
14
import json
15
- import pcap
15
+ import pcap as pcap
16
+ from __init__ import __version__
17
+ from __init__ import __author__
18
+ from __init__ import debug
16
19
17
20
try :
18
21
import hexdump # pylint: disable=g-import-not-at-top
19
22
except ImportError :
20
23
print ("Unable to import hexdump module!" )
21
24
pass
22
25
23
- __author__ = "Daniel Baier, Francois Egner, Max Ufer"
24
- __version__ = "1.0.3"
25
-
26
26
27
27
28
28
46
46
# Names of all supported write functions:
47
47
SSL_WRITE = ["SSL_write" , "wolfSSL_write" , "writeApplicationData" , "NSS_write" ,"Full_write" ]
48
48
49
+ # here - where we are.
50
+ here = os .path .abspath (os .path .dirname (__file__ ))
51
+
49
52
50
53
51
54
def cleanup (live = False , socket_trace = False , full_capture = False , debug_output = False ):
@@ -96,7 +99,9 @@ def temp_fifo():
96
99
print (f'Failed to create FIFO: { e } ' )
97
100
98
101
99
- def ssl_log (app , pcap_name = None , verbose = False , spawn = False , keylog = False , enable_spawn_gating = False , mobile = False , live = False , environment_file = None , debug_output = False ,full_capture = False , socket_trace = False , host = False ):
102
+ def ssl_log (app , pcap_name = None , verbose = False , spawn = False , keylog = False , enable_spawn_gating = False , mobile = False , live = False , environment_file = None , debug_output = False ,full_capture = False , socket_trace = False , host = False , offsets = None ):
103
+ global debug
104
+ debug = debug_output
100
105
101
106
102
107
def on_message (message , data ):
@@ -191,20 +196,54 @@ def on_spawn_added(spawn):
191
196
device .resume (spawn .pid )
192
197
193
198
def instrument (process ):
194
- with open ("_ssl_log.js" ) as f :
195
- script = process .create_script (f .read ())
199
+ runtime = "qjs"
200
+ if debug :
201
+ if frida .__version__ < "16" :
202
+ process .enable_debugger (1337 )
203
+ print ("\n [!] running in debug mode" )
204
+ print ("[!] Chrome Inspector server listening on port 1337\n " )
205
+ runtime = "v8"
206
+
207
+ with open (os .path .join (here , '_ssl_log.js' )) as f :
208
+ script_string = f .read ()
209
+
210
+ if offsets_data is not None :
211
+ print (offsets_data )
212
+ script_string = script_string .replace ('"{OFFSETS}"' , offsets_data )
213
+
214
+ script = process .create_script (script_string , runtime = runtime )
215
+
216
+ if debug and frida .__version__ >= "16" :
217
+ script .enable_debugger (1337 )
196
218
script .on ("message" , on_message )
197
219
script .load ()
198
220
199
221
# Main code
200
222
global pcap_obj
223
+ global offsets_data
224
+
201
225
if mobile :
202
226
device = frida .get_usb_device ()
203
227
elif host :
204
228
device = frida .get_device_manager ().add_remote_device (host )
205
229
else :
206
230
device = frida .get_local_device ()
207
231
232
+
233
+ if offsets is not None :
234
+ if os .path .exists (offsets ):
235
+ file = open (offsets , "r" )
236
+ offsets_data = file .read ()
237
+ file .close ()
238
+ else :
239
+ try :
240
+ json .load (offsets )
241
+ offsets_data = offsets
242
+ except ValueError as e :
243
+ print ("Log error, defaulting to auto-detection?" )
244
+ else :
245
+ offsets_data = None
246
+
208
247
device .on ("child_added" , on_child_added )
209
248
if enable_spawn_gating :
210
249
device .enable_spawn_gating ()
@@ -279,7 +318,7 @@ def error(self, message):
279
318
self .exit (0 )
280
319
281
320
282
- if __name__ == "__main__" :
321
+ def main () :
283
322
284
323
parser = ArgParser (
285
324
add_help = False ,
@@ -322,6 +361,8 @@ def error(self, message):
322
361
help = "Catch newly spawned processes. ATTENTION: These could be unrelated to the current process!" )
323
362
args .add_argument ("exec" , metavar = "<executable/app name/pid>" ,
324
363
help = "executable/app whose SSL calls to log" )
364
+ args .add_argument ("--offsets" , required = False , metavar = "<offsets.json>" ,
365
+ help = "Provide custom offsets for all hooked functions inside a JSON file or a json string containing all offsets. For more details see our example json (offsets_example.json)" )
325
366
parsed = parser .parse_args ()
326
367
327
368
if parsed .full_capture and parsed .pcap is None :
@@ -331,7 +372,7 @@ def error(self, message):
331
372
try :
332
373
print ("Start logging" )
333
374
ssl_log (parsed .exec , parsed .pcap , parsed .verbose ,
334
- parsed .spawn , parsed .keylog , parsed .enable_spawn_gating , parsed .mobile , parsed .live , parsed .environment , parsed .debug , parsed .full_capture , parsed .socket_tracing ,parsed .host )
375
+ parsed .spawn , parsed .keylog , parsed .enable_spawn_gating , parsed .mobile , parsed .live , parsed .environment , parsed .debug , parsed .full_capture , parsed .socket_tracing , parsed .host , parsed . offsets )
335
376
336
377
except Exception as ar :
337
378
print (ar )
@@ -349,6 +390,9 @@ def error(self, message):
349
390
pcap_obj .android_Instance .pull_pcap_from_device ()
350
391
print (f"[*] full { capture_type } capture safed to _{ parsed .pcap } " )
351
392
352
-
393
+
353
394
cleanup (parsed .live ,parsed .socket_tracing ,parsed .full_capture ,parsed .debug )
354
395
396
+
397
+ if __name__ == "__main__" :
398
+ main ()
0 commit comments