48
48
except ImportError :
49
49
has_winreg = False
50
50
51
+ try :
52
+ import winreg
53
+ has_winreg = True
54
+ except ImportError :
55
+ has_winreg = (has_winreg or False )
56
+
57
+ if sys .version_info [0 ] < 3 :
58
+ is_str = lambda obj : issubclass (obj .__class__ , str )
59
+ is_bytes = lambda obj : issubclass (obj .__class__ , str )
60
+ bytes = lambda * args : str (* args [:1 ])
61
+ NULL_BYTE = '\x00 '
62
+ else :
63
+ is_str = lambda obj : issubclass (obj .__class__ , __builtins__ ['str' ])
64
+ is_bytes = lambda obj : issubclass (obj .__class__ , bytes )
65
+ str = lambda x : __builtins__ ['str' ](x , 'UTF-8' )
66
+ NULL_BYTE = bytes ('\x00 ' , 'UTF-8' )
67
+ long = int
68
+
51
69
if has_ctypes :
52
70
#
53
71
# Windows Structures
@@ -498,11 +516,12 @@ def get_stat_buffer(path):
498
516
blocks = si .st_blocks
499
517
st_buf = struct .pack ('<IHHH' , si .st_dev , min (0xffff , si .st_ino ), si .st_mode , si .st_nlink )
500
518
st_buf += struct .pack ('<HHHI' , si .st_uid , si .st_gid , 0 , rdev )
501
- st_buf += struct .pack ('<IIII' , si .st_size , si .st_atime , si .st_mtime , si .st_ctime )
519
+ st_buf += struct .pack ('<IIII' , si .st_size , long ( si .st_atime ), long ( si .st_mtime ), long ( si .st_ctime ) )
502
520
st_buf += struct .pack ('<II' , blksize , blocks )
503
521
return st_buf
504
522
505
523
def netlink_request (req_type ):
524
+ import select
506
525
# See RFC 3549
507
526
NLM_F_REQUEST = 0x0001
508
527
NLM_F_ROOT = 0x0100
@@ -513,17 +532,25 @@ def netlink_request(req_type):
513
532
sock .bind ((os .getpid (), 0 ))
514
533
seq = int (time .time ())
515
534
nlmsg = struct .pack ('IHHIIB15x' , 32 , req_type , (NLM_F_REQUEST | NLM_F_ROOT ), seq , 0 , socket .AF_UNSPEC )
516
- sfd = os .fdopen (sock .fileno (), 'w+b' )
517
- sfd .write (nlmsg )
535
+ sock .send (nlmsg )
518
536
responses = []
519
- response = cstruct_unpack (NLMSGHDR , sfd .read (ctypes .sizeof (NLMSGHDR )))
537
+ if not len (select .select ([sock .fileno ()], [], [], 0.5 )[0 ]):
538
+ return responses
539
+ raw_response_data = sock .recv (0xfffff )
540
+ response = cstruct_unpack (NLMSGHDR , raw_response_data [:ctypes .sizeof (NLMSGHDR )])
541
+ raw_response_data = raw_response_data [ctypes .sizeof (NLMSGHDR ):]
520
542
while response .type != NLMSG_DONE :
521
543
if response .type == NLMSG_ERROR :
522
544
break
523
- response_data = sfd . read (response .len - 16 )
545
+ response_data = raw_response_data [: (response .len - 16 )]
524
546
responses .append (response_data )
525
- response = cstruct_unpack (NLMSGHDR , sfd .read (ctypes .sizeof (NLMSGHDR )))
526
- sfd .close ()
547
+ raw_response_data = raw_response_data [len (response_data ):]
548
+ if not len (raw_response_data ):
549
+ if not len (select .select ([sock .fileno ()], [], [], 0.5 )[0 ]):
550
+ break
551
+ raw_response_data = sock .recv (0xfffff )
552
+ response = cstruct_unpack (NLMSGHDR , raw_response_data [:ctypes .sizeof (NLMSGHDR )])
553
+ raw_response_data = raw_response_data [ctypes .sizeof (NLMSGHDR ):]
527
554
sock .close ()
528
555
return responses
529
556
@@ -559,7 +586,7 @@ def channel_open_stdapi_fs_file(request, response):
559
586
else :
560
587
fmode = 'rb'
561
588
file_h = open (fpath , fmode )
562
- channel_id = meterpreter .add_channel (file_h )
589
+ channel_id = meterpreter .add_channel (MeterpreterFile ( file_h ) )
563
590
response += tlv_pack (TLV_TYPE_CHANNEL_ID , channel_id )
564
591
return ERROR_SUCCESS , response
565
592
@@ -675,6 +702,7 @@ def stdapi_sys_process_execute(request, response):
675
702
proc_h .stderr = open (os .devnull , 'rb' )
676
703
else :
677
704
proc_h = STDProcess (args , stdin = subprocess .PIPE , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
705
+ proc_h .echo_protection = True
678
706
proc_h .start ()
679
707
else :
680
708
proc_h = subprocess .Popen (args , stdin = subprocess .PIPE , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
@@ -693,15 +721,15 @@ def stdapi_sys_process_getpid(request, response):
693
721
694
722
def stdapi_sys_process_get_processes_via_proc (request , response ):
695
723
for pid in os .listdir ('/proc' ):
696
- pgroup = ''
724
+ pgroup = bytes ()
697
725
if not os .path .isdir (os .path .join ('/proc' , pid )) or not pid .isdigit ():
698
726
continue
699
- cmd = open (os .path .join ('/proc' , pid , 'cmdline' ), 'rb' ).read (512 ).replace ('\x00 ' , ' ' )
700
- status_data = open (os .path .join ('/proc' , pid , 'status' ), 'rb' ).read ()
727
+ cmdline_file = open (os .path .join ('/proc' , pid , 'cmdline' ), 'rb' )
728
+ cmd = str (cmdline_file .read (512 ).replace (NULL_BYTE , bytes (' ' , 'UTF-8' )))
729
+ status_data = str (open (os .path .join ('/proc' , pid , 'status' ), 'rb' ).read ())
701
730
status_data = map (lambda x : x .split ('\t ' ,1 ), status_data .split ('\n ' ))
702
- status_data = filter (lambda x : len (x ) == 2 , status_data )
703
731
status = {}
704
- for k , v in status_data :
732
+ for k , v in filter ( lambda x : len ( x ) == 2 , status_data ) :
705
733
status [k [:- 1 ]] = v .strip ()
706
734
ppid = status .get ('PPid' )
707
735
uid = status .get ('Uid' ).split ('\t ' , 1 )[0 ]
@@ -725,14 +753,14 @@ def stdapi_sys_process_get_processes_via_proc(request, response):
725
753
def stdapi_sys_process_get_processes_via_ps (request , response ):
726
754
ps_args = ['ps' , 'ax' , '-w' , '-o' , 'pid,ppid,user,command' ]
727
755
proc_h = subprocess .Popen (ps_args , stdin = subprocess .PIPE , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
728
- ps_output = proc_h .stdout .read ()
756
+ ps_output = str ( proc_h .stdout .read () )
729
757
ps_output = ps_output .split ('\n ' )
730
758
ps_output .pop (0 )
731
759
for process in ps_output :
732
760
process = process .split ()
733
761
if len (process ) < 4 :
734
762
break
735
- pgroup = ''
763
+ pgroup = bytes ()
736
764
pgroup += tlv_pack (TLV_TYPE_PID , int (process [0 ]))
737
765
pgroup += tlv_pack (TLV_TYPE_PARENT_PID , int (process [1 ]))
738
766
pgroup += tlv_pack (TLV_TYPE_USER_NAME , process [2 ])
@@ -793,7 +821,7 @@ def stdapi_sys_process_get_processes_via_windll(request, response):
793
821
use = ctypes .c_ulong ()
794
822
use .value = 0
795
823
ctypes .windll .advapi32 .LookupAccountSidA (None , user_tkn .Sid , username , ctypes .byref (u_len ), domain , ctypes .byref (d_len ), ctypes .byref (use ))
796
- complete_username = ctypes .string_at (domain ) + '\\ ' + ctypes .string_at (username )
824
+ complete_username = str ( ctypes .string_at (domain )) + '\\ ' + str ( ctypes .string_at (username ) )
797
825
k32 .CloseHandle (tkn_h )
798
826
parch = windll_GetNativeSystemInfo ()
799
827
is_wow64 = ctypes .c_ubyte ()
@@ -802,7 +830,7 @@ def stdapi_sys_process_get_processes_via_windll(request, response):
802
830
if k32 .IsWow64Process (proc_h , ctypes .byref (is_wow64 )):
803
831
if is_wow64 .value :
804
832
parch = PROCESS_ARCH_X86
805
- pgroup = ''
833
+ pgroup = bytes ()
806
834
pgroup += tlv_pack (TLV_TYPE_PID , pe32 .th32ProcessID )
807
835
pgroup += tlv_pack (TLV_TYPE_PARENT_PID , pe32 .th32ParentProcessID )
808
836
pgroup += tlv_pack (TLV_TYPE_USER_NAME , complete_username )
@@ -850,16 +878,18 @@ def stdapi_fs_delete_dir(request, response):
850
878
@meterpreter .register_function
851
879
def stdapi_fs_delete_file (request , response ):
852
880
file_path = packet_get_tlv (request , TLV_TYPE_FILE_PATH )['value' ]
853
- os .unlink (file_path )
881
+ if os .path .exists (file_path ):
882
+ os .unlink (file_path )
854
883
return ERROR_SUCCESS , response
855
884
856
885
@meterpreter .register_function
857
886
def stdapi_fs_file_expand_path (request , response ):
858
887
path_tlv = packet_get_tlv (request , TLV_TYPE_FILE_PATH )['value' ]
859
888
if has_windll :
889
+ path_tlv = ctypes .create_string_buffer (bytes (path_tlv , 'UTF-8' ))
860
890
path_out = (ctypes .c_char * 4096 )()
861
- path_out_len = ctypes .windll .kernel32 .ExpandEnvironmentStringsA (path_tlv , ctypes .byref (path_out ), ctypes .sizeof (path_out ))
862
- result = '' . join (path_out )[: path_out_len ]
891
+ path_out_len = ctypes .windll .kernel32 .ExpandEnvironmentStringsA (ctypes . byref ( path_tlv ) , ctypes .byref (path_out ), ctypes .sizeof (path_out ))
892
+ result = str ( ctypes . string_at (path_out ))
863
893
elif path_tlv == '%COMSPEC%' :
864
894
result = '/bin/sh'
865
895
elif path_tlv in ['%TEMP%' , '%TMP%' ]:
@@ -912,7 +942,8 @@ def stdapi_fs_md5(request, response):
912
942
@meterpreter .register_function
913
943
def stdapi_fs_mkdir (request , response ):
914
944
dir_path = packet_get_tlv (request , TLV_TYPE_DIRECTORY_PATH )['value' ]
915
- os .mkdir (dir_path )
945
+ if not os .path .isdir (dir_path ):
946
+ os .mkdir (dir_path )
916
947
return ERROR_SUCCESS , response
917
948
918
949
@meterpreter .register_function
@@ -965,7 +996,7 @@ def stdapi_fs_stat(request, response):
965
996
966
997
@meterpreter .register_function
967
998
def stdapi_net_config_get_interfaces (request , response ):
968
- if hasattr (socket , 'AF_NETLINK' ):
999
+ if hasattr (socket , 'AF_NETLINK' ) and hasattr ( socket , 'NETLINK_ROUTE' ) :
969
1000
interfaces = stdapi_net_config_get_interfaces_via_netlink ()
970
1001
elif has_osxsc :
971
1002
interfaces = stdapi_net_config_get_interfaces_via_osxsc ()
@@ -974,7 +1005,7 @@ def stdapi_net_config_get_interfaces(request, response):
974
1005
else :
975
1006
return ERROR_FAILURE , response
976
1007
for iface_info in interfaces :
977
- iface_tlv = ''
1008
+ iface_tlv = bytes ()
978
1009
iface_tlv += tlv_pack (TLV_TYPE_MAC_NAME , iface_info .get ('name' , 'Unknown' ))
979
1010
iface_tlv += tlv_pack (TLV_TYPE_MAC_ADDRESS , iface_info .get ('hw_addr' , '\x00 \x00 \x00 \x00 \x00 \x00 ' ))
980
1011
if 'mtu' in iface_info :
@@ -1002,7 +1033,7 @@ def stdapi_net_config_get_interfaces_via_netlink():
1002
1033
0x0100 : 'PROMISC' ,
1003
1034
0x1000 : 'MULTICAST'
1004
1035
}
1005
- iface_flags_sorted = iface_flags .keys ()
1036
+ iface_flags_sorted = list ( iface_flags .keys () )
1006
1037
# Dictionaries don't maintain order
1007
1038
iface_flags_sorted .sort ()
1008
1039
interfaces = {}
@@ -1106,7 +1137,7 @@ def stdapi_net_config_get_interfaces_via_osxsc():
1106
1137
hw_addr = hw_addr .replace (':' , '' )
1107
1138
hw_addr = hw_addr .decode ('hex' )
1108
1139
iface_info ['hw_addr' ] = hw_addr
1109
- ifnames = interfaces .keys ()
1140
+ ifnames = list ( interfaces .keys () )
1110
1141
ifnames .sort ()
1111
1142
for iface_name , iface_info in interfaces .items ():
1112
1143
iface_info ['index' ] = ifnames .index (iface_name )
@@ -1138,7 +1169,10 @@ def stdapi_net_config_get_interfaces_via_windll():
1138
1169
iface_info ['index' ] = AdapterAddresses .u .s .IfIndex
1139
1170
if AdapterAddresses .PhysicalAddressLength :
1140
1171
iface_info ['hw_addr' ] = ctypes .string_at (ctypes .byref (AdapterAddresses .PhysicalAddress ), AdapterAddresses .PhysicalAddressLength )
1141
- iface_info ['name' ] = str (ctypes .wstring_at (AdapterAddresses .Description ))
1172
+ iface_desc = ctypes .wstring_at (AdapterAddresses .Description )
1173
+ if not is_str (iface_desc ):
1174
+ iface_desc = str (iface_desc )
1175
+ iface_info ['name' ] = iface_desc
1142
1176
iface_info ['mtu' ] = AdapterAddresses .Mtu
1143
1177
pUniAddr = AdapterAddresses .FirstUnicastAddress
1144
1178
while pUniAddr :
@@ -1174,7 +1208,7 @@ def stdapi_net_config_get_interfaces_via_windll_mib():
1174
1208
table_data = ctypes .string_at (table , pdwSize .value )
1175
1209
entries = struct .unpack ('I' , table_data [:4 ])[0 ]
1176
1210
table_data = table_data [4 :]
1177
- for i in xrange (entries ):
1211
+ for i in range (entries ):
1178
1212
addrrow = cstruct_unpack (MIB_IPADDRROW , table_data )
1179
1213
ifrow = MIB_IFROW ()
1180
1214
ifrow .dwIndex = addrrow .dwIndex
@@ -1244,9 +1278,10 @@ def stdapi_registry_close_key(request, response):
1244
1278
def stdapi_registry_create_key (request , response ):
1245
1279
root_key = packet_get_tlv (request , TLV_TYPE_ROOT_KEY )['value' ]
1246
1280
base_key = packet_get_tlv (request , TLV_TYPE_BASE_KEY )['value' ]
1281
+ base_key = ctypes .create_string_buffer (bytes (base_key , 'UTF-8' ))
1247
1282
permission = packet_get_tlv (request , TLV_TYPE_PERMISSION ).get ('value' , winreg .KEY_ALL_ACCESS )
1248
1283
res_key = ctypes .c_void_p ()
1249
- if ctypes .windll .advapi32 .RegCreateKeyExA (root_key , base_key , 0 , None , 0 , permission , None , ctypes .byref (res_key ), None ) == ERROR_SUCCESS :
1284
+ if ctypes .windll .advapi32 .RegCreateKeyExA (root_key , ctypes . byref ( base_key ) , 0 , None , 0 , permission , None , ctypes .byref (res_key ), None ) == ERROR_SUCCESS :
1250
1285
response += tlv_pack (TLV_TYPE_HKEY , res_key .value )
1251
1286
return ERROR_SUCCESS , response
1252
1287
return ERROR_FAILURE , response
@@ -1255,18 +1290,20 @@ def stdapi_registry_create_key(request, response):
1255
1290
def stdapi_registry_delete_key (request , response ):
1256
1291
root_key = packet_get_tlv (request , TLV_TYPE_ROOT_KEY )['value' ]
1257
1292
base_key = packet_get_tlv (request , TLV_TYPE_BASE_KEY )['value' ]
1293
+ base_key = ctypes .create_string_buffer (bytes (base_key , 'UTF-8' ))
1258
1294
flags = packet_get_tlv (request , TLV_TYPE_FLAGS )['value' ]
1259
1295
if (flags & DELETE_KEY_FLAG_RECURSIVE ):
1260
- result = ctypes .windll .shlwapi .SHDeleteKeyA (root_key , base_key )
1296
+ result = ctypes .windll .shlwapi .SHDeleteKeyA (root_key , ctypes . byref ( base_key ) )
1261
1297
else :
1262
- result = ctypes .windll .advapi32 .RegDeleteKeyA (root_key , base_key )
1298
+ result = ctypes .windll .advapi32 .RegDeleteKeyA (root_key , ctypes . byref ( base_key ) )
1263
1299
return result , response
1264
1300
1265
1301
@meterpreter .register_function_windll
1266
1302
def stdapi_registry_delete_value (request , response ):
1267
1303
root_key = packet_get_tlv (request , TLV_TYPE_ROOT_KEY )['value' ]
1268
1304
value_name = packet_get_tlv (request , TLV_TYPE_VALUE_NAME )['value' ]
1269
- result = ctypes .windll .advapi32 .RegDeleteValueA (root_key , value_name )
1305
+ value_name = ctypes .create_string_buffer (bytes (value_name , 'UTF-8' ))
1306
+ result = ctypes .windll .advapi32 .RegDeleteValueA (root_key , ctypes .byref (value_name ))
1270
1307
return result , response
1271
1308
1272
1309
@meterpreter .register_function_windll
@@ -1335,9 +1372,10 @@ def stdapi_registry_load_key(request, response):
1335
1372
def stdapi_registry_open_key (request , response ):
1336
1373
root_key = packet_get_tlv (request , TLV_TYPE_ROOT_KEY )['value' ]
1337
1374
base_key = packet_get_tlv (request , TLV_TYPE_BASE_KEY )['value' ]
1375
+ base_key = ctypes .create_string_buffer (bytes (base_key , 'UTF-8' ))
1338
1376
permission = packet_get_tlv (request , TLV_TYPE_PERMISSION ).get ('value' , winreg .KEY_ALL_ACCESS )
1339
1377
handle_id = ctypes .c_void_p ()
1340
- if ctypes .windll .advapi32 .RegOpenKeyExA (root_key , base_key , 0 , permission , ctypes .byref (handle_id )) == ERROR_SUCCESS :
1378
+ if ctypes .windll .advapi32 .RegOpenKeyExA (root_key , ctypes . byref ( base_key ) , 0 , permission , ctypes .byref (handle_id )) == ERROR_SUCCESS :
1341
1379
response += tlv_pack (TLV_TYPE_HKEY , handle_id .value )
1342
1380
return ERROR_SUCCESS , response
1343
1381
return ERROR_FAILURE , response
@@ -1367,24 +1405,26 @@ def stdapi_registry_query_class(request, response):
1367
1405
1368
1406
@meterpreter .register_function_windll
1369
1407
def stdapi_registry_query_value (request , response ):
1370
- REG_SZ = 1
1371
- REG_DWORD = 4
1372
1408
hkey = packet_get_tlv (request , TLV_TYPE_HKEY )['value' ]
1373
1409
value_name = packet_get_tlv (request , TLV_TYPE_VALUE_NAME )['value' ]
1410
+ value_name = ctypes .create_string_buffer (bytes (value_name , 'UTF-8' ))
1374
1411
value_type = ctypes .c_uint32 ()
1375
1412
value_type .value = 0
1376
1413
value_data = (ctypes .c_ubyte * 4096 )()
1377
1414
value_data_sz = ctypes .c_uint32 ()
1378
1415
value_data_sz .value = ctypes .sizeof (value_data )
1379
- result = ctypes .windll .advapi32 .RegQueryValueExA (hkey , value_name , 0 , ctypes .byref (value_type ), value_data , ctypes .byref (value_data_sz ))
1416
+ result = ctypes .windll .advapi32 .RegQueryValueExA (hkey , ctypes . byref ( value_name ) , 0 , ctypes .byref (value_type ), value_data , ctypes .byref (value_data_sz ))
1380
1417
if result == ERROR_SUCCESS :
1381
1418
response += tlv_pack (TLV_TYPE_VALUE_TYPE , value_type .value )
1382
- if value_type .value == REG_SZ :
1383
- response += tlv_pack (TLV_TYPE_VALUE_DATA , ctypes .string_at (value_data ) + ' \x00 ' )
1384
- elif value_type .value == REG_DWORD :
1419
+ if value_type .value == winreg . REG_SZ :
1420
+ response += tlv_pack (TLV_TYPE_VALUE_DATA , ctypes .string_at (value_data ) + NULL_BYTE )
1421
+ elif value_type .value == winreg . REG_DWORD :
1385
1422
value = value_data [:4 ]
1386
1423
value .reverse ()
1387
- value = '' .join (map (chr , value ))
1424
+ if sys .version_info [0 ] < 3 :
1425
+ value = '' .join (map (chr , value ))
1426
+ else :
1427
+ value = bytes (value )
1388
1428
response += tlv_pack (TLV_TYPE_VALUE_DATA , value )
1389
1429
else :
1390
1430
response += tlv_pack (TLV_TYPE_VALUE_DATA , ctypes .string_at (value_data , value_data_sz .value ))
@@ -1395,9 +1435,10 @@ def stdapi_registry_query_value(request, response):
1395
1435
def stdapi_registry_set_value (request , response ):
1396
1436
hkey = packet_get_tlv (request , TLV_TYPE_HKEY )['value' ]
1397
1437
value_name = packet_get_tlv (request , TLV_TYPE_VALUE_NAME )['value' ]
1438
+ value_name = ctypes .create_string_buffer (bytes (value_name , 'UTF-8' ))
1398
1439
value_type = packet_get_tlv (request , TLV_TYPE_VALUE_TYPE )['value' ]
1399
1440
value_data = packet_get_tlv (request , TLV_TYPE_VALUE_DATA )['value' ]
1400
- result = ctypes .windll .advapi32 .RegSetValueExA (hkey , value_name , 0 , value_type , value_data , len (value_data ))
1441
+ result = ctypes .windll .advapi32 .RegSetValueExA (hkey , ctypes . byref ( value_name ) , 0 , value_type , value_data , len (value_data ))
1401
1442
return result , response
1402
1443
1403
1444
@meterpreter .register_function_windll
0 commit comments