1
1
import os
2
2
import sys
3
3
import shlex
4
+ import ctypes
4
5
import socket
5
6
import struct
6
7
import shutil
9
10
import platform
10
11
import subprocess
11
12
13
+ has_windll = hasattr (ctypes , 'windll' )
14
+
15
+ try :
16
+ import pwd
17
+ has_pwd = True
18
+ except ImportError :
19
+ has_pwd = False
20
+
21
+ class PROCESSENTRY32 (ctypes .Structure ):
22
+ _fields_ = [("dwSize" , ctypes .c_uint32 ),
23
+ ("cntUsage" , ctypes .c_uint32 ),
24
+ ("th32ProcessID" , ctypes .c_uint32 ),
25
+ ("th32DefaultHeapID" , ctypes .c_void_p ),
26
+ ("th32ModuleID" , ctypes .c_uint32 ),
27
+ ("cntThreads" , ctypes .c_uint32 ),
28
+ ("th32ParentProcessID" , ctypes .c_uint32 ),
29
+ ("thPriClassBase" , ctypes .c_int32 ),
30
+ ("dwFlags" , ctypes .c_uint32 ),
31
+ ("szExeFile" , (ctypes .c_char * 260 ))]
32
+
33
+ class SYSTEM_INFO (ctypes .Structure ):
34
+ _fields_ = [("wProcessorArchitecture" , ctypes .c_uint16 ),
35
+ ("wReserved" , ctypes .c_uint16 ),
36
+ ("dwPageSize" , ctypes .c_uint32 ),
37
+ ("lpMinimumApplicationAddress" , ctypes .c_void_p ),
38
+ ("lpMaximumApplicationAddress" , ctypes .c_void_p ),
39
+ ("dwActiveProcessorMask" , ctypes .c_uint32 ),
40
+ ("dwNumberOfProcessors" , ctypes .c_uint32 ),
41
+ ("dwProcessorType" , ctypes .c_uint32 ),
42
+ ("dwAllocationGranularity" , ctypes .c_uint32 ),
43
+ ("wProcessorLevel" , ctypes .c_uint16 ),
44
+ ("wProcessorRevision" , ctypes .c_uint16 ),]
45
+
46
+ class SID_AND_ATTRIBUTES (ctypes .Structure ):
47
+ _fields_ = [("Sid" , ctypes .c_void_p ),
48
+ ("Attributes" , ctypes .c_uint32 ),]
49
+
12
50
##
13
51
# STDAPI
14
52
##
103
141
104
142
TLV_TYPE_SHUTDOWN_HOW = TLV_META_TYPE_UINT | 1530
105
143
106
- ##
107
- # Sys
108
- ##
109
- PROCESS_EXECUTE_FLAG_HIDDEN = (1 << 0 )
110
- PROCESS_EXECUTE_FLAG_CHANNELIZED = (1 << 1 )
111
- PROCESS_EXECUTE_FLAG_SUSPENDED = (1 << 2 )
112
- PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN = (1 << 3 )
113
-
114
144
# Registry
115
145
TLV_TYPE_HKEY = TLV_META_TYPE_UINT | 1000
116
146
TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY
200
230
TLV_TYPE_POWER_FLAGS = TLV_META_TYPE_UINT | 4100
201
231
TLV_TYPE_POWER_REASON = TLV_META_TYPE_UINT | 4101
202
232
233
+ ##
234
+ # Sys
235
+ ##
236
+ PROCESS_EXECUTE_FLAG_HIDDEN = (1 << 0 )
237
+ PROCESS_EXECUTE_FLAG_CHANNELIZED = (1 << 1 )
238
+ PROCESS_EXECUTE_FLAG_SUSPENDED = (1 << 2 )
239
+ PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN = (1 << 3 )
240
+
241
+ PROCESS_ARCH_UNKNOWN = 0
242
+ PROCESS_ARCH_X86 = 1
243
+ PROCESS_ARCH_X64 = 2
244
+ PROCESS_ARCH_IA64 = 3
245
+
203
246
##
204
247
# Errors
205
248
##
@@ -228,6 +271,13 @@ def get_stat_buffer(path):
228
271
st_buf += struct .pack ('<II' , blksize , blocks )
229
272
return st_buf
230
273
274
+ def windll_GetNativeSystemInfo ():
275
+ if not has_windll :
276
+ return None
277
+ sysinfo = SYSTEM_INFO ()
278
+ ctypes .windll .kernel32 .GetNativeSystemInfo (ctypes .byref (sysinfo ))
279
+ return {0 :PROCESS_ARCH_X86 , 6 :PROCESS_ARCH_IA64 , 9 :PROCESS_ARCH_X64 }.get (sysinfo .wProcessorArchitecture , PROCESS_ARCH_UNKNOWN )
280
+
231
281
@meterpreter .register_function
232
282
def channel_create_stdapi_fs_file (request , response ):
233
283
fpath = packet_get_tlv (request , TLV_TYPE_FILE_PATH )['value' ]
@@ -278,11 +328,16 @@ def stdapi_sys_config_sysinfo(request, response):
278
328
response += tlv_pack (TLV_TYPE_COMPUTER_NAME , uname_info [1 ])
279
329
response += tlv_pack (TLV_TYPE_OS_NAME , uname_info [0 ] + ' ' + uname_info [2 ] + ' ' + uname_info [3 ])
280
330
arch = uname_info [4 ]
281
- if not arch and uname_info [1 ] == 'Windows' :
282
- if platform .architecture ()[0 ] == '32bit' :
283
- arch = 'x86'
284
- elif platform .architecture ()[0 ] == '64bit' :
331
+ if has_windll :
332
+ arch = windll_GetNativeSystemInfo ()
333
+ if arch == PROCESS_ARCH_IA64 :
334
+ arch = 'IA64'
335
+ elif arch == PROCESS_ARCH_X64 :
285
336
arch = 'x86_64'
337
+ elif arch == PROCESS_ARCH_X86 :
338
+ arch = 'x86'
339
+ else :
340
+ arch = uname_info [4 ]
286
341
response += tlv_pack (TLV_TYPE_ARCHITECTURE , arch )
287
342
return ERROR_SUCCESS , response
288
343
@@ -344,6 +399,8 @@ def stdapi_sys_process_get_processes_via_proc(request, response):
344
399
status [k [:- 1 ]] = v .strip ()
345
400
ppid = status .get ('PPid' )
346
401
uid = status .get ('Uid' ).split ('\t ' , 1 )[0 ]
402
+ if has_pwd :
403
+ uid = pwd .getpwuid (int (uid )).pw_name
347
404
if cmd :
348
405
pname = os .path .basename (cmd .split (' ' , 1 )[0 ])
349
406
ppath = cmd
@@ -359,11 +416,86 @@ def stdapi_sys_process_get_processes_via_proc(request, response):
359
416
response += tlv_pack (TLV_TYPE_PROCESS_GROUP , pgroup )
360
417
return ERROR_SUCCESS , response
361
418
419
+ def stdapi_sys_process_get_processes_via_windll (request , response ):
420
+ TH32CS_SNAPPROCESS = 2
421
+ PROCESS_QUERY_INFORMATION = 0x0400
422
+ PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
423
+ PROCESS_VM_READ = 0x10
424
+ TOKEN_QUERY = 0x0008
425
+ TokenUser = 1
426
+ k32 = ctypes .windll .kernel32
427
+ pe32 = PROCESSENTRY32 ()
428
+ pe32 .dwSize = ctypes .sizeof (PROCESSENTRY32 )
429
+ proc_snap = k32 .CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 )
430
+ result = k32 .Process32First (proc_snap , ctypes .byref (pe32 ))
431
+ if not result :
432
+ return ERROR_FAILURE , response
433
+ while result :
434
+ proc_h = k32 .OpenProcess ((PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ), False , pe32 .th32ProcessID )
435
+ if not proc_h :
436
+ proc_h = k32 .OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION , False , pe32 .th32ProcessID )
437
+ exe_path = (ctypes .c_char * 1024 )()
438
+ success = False
439
+ if hasattr (ctypes .windll .psapi , 'GetModuleFileNameExA' ):
440
+ success = ctypes .windll .psapi .GetModuleFileNameExA (proc_h , 0 , exe_path , ctypes .sizeof (exe_path ))
441
+ elif hasattr (k32 , 'GetModuleFileNameExA' ):
442
+ success = k32 .GetModuleFileNameExA (proc_h , 0 , exe_path , ctypes .sizeof (exe_path ))
443
+ if not success and hasattr (k32 , 'QueryFullProcessImageNameA' ):
444
+ dw_sz = ctypes .c_uint32 ()
445
+ dw_sz .value = ctypes .sizeof (exe_path )
446
+ success = k32 .QueryFullProcessImageNameA (proc_h , 0 , exe_path , ctypes .byref (dw_sz ))
447
+ if not success and hasattr (ctypes .windll .psapi , 'GetProcessImageFileNameA' ):
448
+ success = ctypes .windll .psapi .GetProcessImageFileNameA (proc_h , exe_path , ctypes .sizeof (exe_path ))
449
+ if success :
450
+ exe_path = ctypes .string_at (exe_path )
451
+ else :
452
+ exe_path = ''
453
+ complete_username = ''
454
+ tkn_h = ctypes .c_long ()
455
+ tkn_len = ctypes .c_uint32 ()
456
+ if ctypes .windll .advapi32 .OpenProcessToken (proc_h , TOKEN_QUERY , ctypes .byref (tkn_h )):
457
+ ctypes .windll .advapi32 .GetTokenInformation (tkn_h , TokenUser , None , 0 , ctypes .byref (tkn_len ))
458
+ buf = (ctypes .c_ubyte * tkn_len .value )()
459
+ if ctypes .windll .advapi32 .GetTokenInformation (tkn_h , TokenUser , ctypes .byref (buf ), ctypes .sizeof (buf ), ctypes .byref (tkn_len )):
460
+ user_tkn = SID_AND_ATTRIBUTES ()
461
+ ctypes .memmove (ctypes .byref (user_tkn ), buf , ctypes .sizeof (user_tkn ))
462
+ username = (ctypes .c_char * 512 )()
463
+ domain = (ctypes .c_char * 512 )()
464
+ u_len = ctypes .c_uint32 ()
465
+ u_len .value = ctypes .sizeof (username )
466
+ d_len = ctypes .c_uint32 ()
467
+ d_len .value = ctypes .sizeof (domain )
468
+ use = ctypes .c_ulong ()
469
+ use .value = 0
470
+ ctypes .windll .advapi32 .LookupAccountSidA (None , user_tkn .Sid , username , ctypes .byref (u_len ), domain , ctypes .byref (d_len ), ctypes .byref (use ))
471
+ complete_username = ctypes .string_at (domain ) + '\\ ' + ctypes .string_at (username )
472
+ k32 .CloseHandle (tkn_h )
473
+ parch = windll_GetNativeSystemInfo ()
474
+ is_wow64 = ctypes .c_ubyte ()
475
+ is_wow64 .value = 0
476
+ if hasattr (k32 , 'IsWow64Process' ):
477
+ if k32 .IsWow64Process (proc_h , ctypes .byref (is_wow64 )):
478
+ if is_wow64 .value :
479
+ parch = PROCESS_ARCH_X86
480
+ pgroup = ''
481
+ pgroup += tlv_pack (TLV_TYPE_PID , pe32 .th32ProcessID )
482
+ pgroup += tlv_pack (TLV_TYPE_PARENT_PID , pe32 .th32ParentProcessID )
483
+ pgroup += tlv_pack (TLV_TYPE_USER_NAME , complete_username )
484
+ pgroup += tlv_pack (TLV_TYPE_PROCESS_NAME , pe32 .szExeFile )
485
+ pgroup += tlv_pack (TLV_TYPE_PROCESS_PATH , exe_path )
486
+ pgroup += tlv_pack (TLV_TYPE_PROCESS_ARCH , parch )
487
+ response += tlv_pack (TLV_TYPE_PROCESS_GROUP , pgroup )
488
+ result = k32 .Process32Next (proc_snap , ctypes .byref (pe32 ))
489
+ k32 .CloseHandle (proc_h )
490
+ k32 .CloseHandle (proc_snap )
491
+ return ERROR_SUCCESS , response
362
492
363
493
@meterpreter .register_function
364
494
def stdapi_sys_process_get_processes (request , response ):
365
495
if os .path .isdir ('/proc' ):
366
496
return stdapi_sys_process_get_processes_via_proc (request , response )
497
+ elif has_windll :
498
+ return stdapi_sys_process_get_processes_via_windll (request , response )
367
499
return ERROR_FAILURE , response
368
500
369
501
@meterpreter .register_function
0 commit comments