From 6c9cfe00f92ab119f83df35542676018027a290e Mon Sep 17 00:00:00 2001 From: dusoleil Date: Tue, 31 Aug 2021 19:35:35 -0400 Subject: Add Interactive Mode to Comms comm.interact() will drop the user into an "interactive" mode where they can directly control what is sent. A SIGINT (Ctrl+C) will drop the script out of interactive mode and continue executing the rest of the script. If the output of the program (input into our script) goes into a broken state (such as when the target program exits), interactive mode will automatically exit. Signed-off-by: dusoleil --- tools/sploit/sploit/comm.py | 50 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/sploit/sploit/comm.py b/tools/sploit/sploit/comm.py index 9b68c38..0b5bc2a 100644 --- a/tools/sploit/sploit/comm.py +++ b/tools/sploit/sploit/comm.py @@ -1,6 +1,10 @@ import subprocess +import threading import tempfile import os +import sys +import select +import signal from sploit.log import log @@ -43,13 +47,57 @@ class Comm: def writeline(self, data): self.write(data + b'\n') + def interact(self): + print("Interact Mode") + syncstop = threading.Event() + def readloop(): + poll = select.poll() + poll.register(self.back.stdin) + def readall(): + while(True): + data = self.back.stdin.readline() + if(data == b''): + break + log(data) + while not syncstop.isSet(): + readall() + dat = poll.poll(100) + if(len(dat)>0): + if(dat[0][1] & select.POLLIN): + readall() + else: + syncstop.set() + os.set_blocking(self.back.stdin.fileno(),False) + readthread = threading.Thread(target=readloop,daemon=True) + readthread.start() + stdin = sys.stdin.buffer + signal.signal(signal.SIGALRM,lambda: 0) + while not syncstop.isSet(): + try: + signal.alarm(1) + data = stdin.readline() + if(data and not syncstop.isSet()): + self.write(data) + else: + break + except TypeError: + pass + except KeyboardInterrupt: + break + signal.alarm(0) + syncstop.set() + readthread.join() + os.set_blocking(self.back.stdin.fileno(),True) + print("Interact Mode Done") + class Process: def __init__(self, args): print(f"Running: {' '.join(args)}") self.proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + stderr=subprocess.STDOUT, + preexec_fn=lambda : os.setpgrp()) print(f"PID: {self.proc.pid}") self.stdin = self.proc.stdout self.stdout = self.proc.stdin -- cgit v1.2.3