|
8 | 8 | import subprocess
|
9 | 9 | import sys
|
10 | 10 | import threading
|
| 11 | +import time |
11 | 12 | import traceback
|
12 | 13 |
|
13 | 14 | try:
|
@@ -120,7 +121,7 @@ def export(symbol):
|
120 | 121 |
|
121 | 122 | def generate_request_id():
|
122 | 123 | chars = 'abcdefghijklmnopqrstuvwxyz'
|
123 |
| - return ''.join(random.choice(chars) for x in xrange(32)) |
| 124 | + return ''.join(random.choice(chars) for x in range(32)) |
124 | 125 |
|
125 | 126 | @export
|
126 | 127 | def inet_pton(family, address):
|
@@ -223,40 +224,58 @@ def __init__(self, std, is_alive):
|
223 | 224 | threading.Thread.__init__(self)
|
224 | 225 | self.std = std
|
225 | 226 | self.is_alive = is_alive
|
226 |
| - self.data = '' |
| 227 | + self.data = bytes() |
227 | 228 | self.data_lock = threading.RLock()
|
228 | 229 |
|
229 | 230 | def run(self):
|
230 |
| - for byte in iter(lambda: self.std.read(1), ''): |
| 231 | + for byte in iter(lambda: self.std.read(1), bytes()): |
231 | 232 | self.data_lock.acquire()
|
232 | 233 | self.data += byte
|
233 | 234 | self.data_lock.release()
|
234 | 235 |
|
235 | 236 | def is_read_ready(self):
|
236 | 237 | return len(self.data) != 0
|
237 | 238 |
|
238 |
| - def read(self, l = None): |
239 |
| - data = '' |
| 239 | + def peek(self, l = None): |
| 240 | + data = bytes() |
240 | 241 | self.data_lock.acquire()
|
241 | 242 | if l == None:
|
242 | 243 | data = self.data
|
243 |
| - self.data = '' |
244 | 244 | else:
|
245 | 245 | data = self.data[0:l]
|
246 |
| - self.data = self.data[l:] |
| 246 | + self.data_lock.release() |
| 247 | + return data |
| 248 | + |
| 249 | + def read(self, l = None): |
| 250 | + self.data_lock.acquire() |
| 251 | + data = self.peek(l) |
| 252 | + self.data = self.data[len(data):] |
247 | 253 | self.data_lock.release()
|
248 | 254 | return data
|
249 | 255 |
|
250 | 256 | #@export
|
251 | 257 | class STDProcess(subprocess.Popen):
|
252 | 258 | def __init__(self, *args, **kwargs):
|
253 | 259 | subprocess.Popen.__init__(self, *args, **kwargs)
|
| 260 | + self.echo_protection = False |
254 | 261 |
|
255 | 262 | def start(self):
|
256 | 263 | self.stdout_reader = STDProcessBuffer(self.stdout, lambda: self.poll() == None)
|
257 | 264 | self.stdout_reader.start()
|
258 | 265 | self.stderr_reader = STDProcessBuffer(self.stderr, lambda: self.poll() == None)
|
259 | 266 | self.stderr_reader.start()
|
| 267 | + |
| 268 | + def write(self, channel_data): |
| 269 | + self.stdin.write(channel_data) |
| 270 | + self.stdin.flush() |
| 271 | + if self.echo_protection: |
| 272 | + end_time = time.time() + 0.5 |
| 273 | + out_data = bytes() |
| 274 | + while (time.time() < end_time) and (out_data != channel_data): |
| 275 | + if self.stdout_reader.is_read_ready(): |
| 276 | + out_data = self.stdout_reader.peek(len(channel_data)) |
| 277 | + if out_data == channel_data: |
| 278 | + self.stdout_reader.read(len(channel_data)) |
260 | 279 | export(STDProcess)
|
261 | 280 |
|
262 | 281 | class PythonMeterpreter(object):
|
@@ -310,25 +329,25 @@ def run(self):
|
310 | 329 | else:
|
311 | 330 | channels_for_removal = []
|
312 | 331 | # iterate over the keys because self.channels could be modified if one is closed
|
313 |
| - channel_ids = self.channels.keys() |
| 332 | + channel_ids = list(self.channels.keys()) |
314 | 333 | for channel_id in channel_ids:
|
315 | 334 | channel = self.channels[channel_id]
|
316 |
| - data = '' |
| 335 | + data = bytes() |
317 | 336 | if isinstance(channel, STDProcess):
|
318 | 337 | if not channel_id in self.interact_channels:
|
319 | 338 | continue
|
320 |
| - if channel.stdout_reader.is_read_ready(): |
321 |
| - data = channel.stdout_reader.read() |
322 |
| - elif channel.stderr_reader.is_read_ready(): |
| 339 | + if channel.stderr_reader.is_read_ready(): |
323 | 340 | data = channel.stderr_reader.read()
|
| 341 | + elif channel.stdout_reader.is_read_ready(): |
| 342 | + data = channel.stdout_reader.read() |
324 | 343 | elif channel.poll() != None:
|
325 | 344 | self.handle_dead_resource_channel(channel_id)
|
326 | 345 | elif isinstance(channel, MeterpreterSocketClient):
|
327 | 346 | while len(select.select([channel.fileno()], [], [], 0)[0]):
|
328 | 347 | try:
|
329 | 348 | d = channel.recv(1)
|
330 | 349 | except socket.error:
|
331 |
| - d = '' |
| 350 | + d = bytes() |
332 | 351 | if len(d) == 0:
|
333 | 352 | self.handle_dead_resource_channel(channel_id)
|
334 | 353 | break
|
@@ -474,7 +493,7 @@ def _core_channel_write(self, request, response):
|
474 | 493 | if channel.poll() != None:
|
475 | 494 | self.handle_dead_resource_channel(channel_id)
|
476 | 495 | return ERROR_FAILURE, response
|
477 |
| - channel.stdin.write(channel_data) |
| 496 | + channel.write(channel_data) |
478 | 497 | elif isinstance(channel, MeterpreterFile):
|
479 | 498 | channel.write(channel_data)
|
480 | 499 | elif isinstance(channel, MeterpreterSocket):
|
|
0 commit comments