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

Fixed Windows platform transitions

Exception handling in the output thread was cleaned up and had Windows
platform raise the RawModeExit exception to trigger an exit when
interactive end marker was observed.
This commit is contained in:
Caleb Stewart 2021-06-18 19:45:59 -04:00
parent cce789c99d
commit a95f2df50c
2 changed files with 12 additions and 14 deletions

View File

@ -590,12 +590,9 @@ class Manager:
data = target.platform.channel.recv(4096) data = target.platform.channel.recv(4096)
if data != b"" and data is not None: if data != b"" and data is not None:
try:
data = target.platform.process_output(data) data = target.platform.process_output(data)
sys.stdout.buffer.write(data) sys.stdout.buffer.write(data)
sys.stdout.buffer.flush() sys.stdout.buffer.flush()
except RawModeExit:
interactive_complete.set()
else: else:
interactive_complete.wait(timeout=0.1) interactive_complete.wait(timeout=0.1)
@ -605,6 +602,9 @@ class Manager:
# This is a hack to get the interactive loop out of a blocking # This is a hack to get the interactive loop out of a blocking
# read call. The interactive loop will receive a KeyboardInterrupt # read call. The interactive loop will receive a KeyboardInterrupt
os.kill(os.getpid(), signal.SIGINT) os.kill(os.getpid(), signal.SIGINT)
except RawModeExit:
interactive_complete.set()
os.kill(os.getpid(), signal.SIGINT)
try: try:
self.target.platform.interactive = True self.target.platform.interactive = True

View File

@ -13,7 +13,6 @@ processes and open multiple files with this platform. However, you should be
careful to cleanup all processes and files prior to return from your method careful to cleanup all processes and files prior to return from your method
or code as the C2 will not attempt to garbage collect file or proces handles. or code as the C2 will not attempt to garbage collect file or proces handles.
""" """
import os
import sys import sys
import gzip import gzip
import json import json
@ -46,7 +45,7 @@ PWNCAT_WINDOWS_C2_VERSION = "v0.2.1"
PWNCAT_WINDOWS_C2_RELEASE_URL = "https://github.com/calebstewart/pwncat-windows-c2/releases/download/{version}/pwncat-windows-{version}.tar.gz" PWNCAT_WINDOWS_C2_RELEASE_URL = "https://github.com/calebstewart/pwncat-windows-c2/releases/download/{version}/pwncat-windows-{version}.tar.gz"
class PowershellError(Exception): class PowershellError(PlatformError):
"""Executing a powershell script caused an error""" """Executing a powershell script caused an error"""
def __init__(self, msg): def __init__(self, msg):
@ -55,7 +54,7 @@ class PowershellError(Exception):
self.message = msg self.message = msg
class ProtocolError(Exception): class ProtocolError(PlatformError):
def __init__(self, code: int, message: str): def __init__(self, code: int, message: str):
self.code = code self.code = code
self.message = message self.message = message
@ -908,7 +907,7 @@ function prompt {
transformed = bytearray(b"") transformed = bytearray(b"")
has_cr = False has_cr = False
for b in data: for idx, b in enumerate(data):
# Basically, we just transform bare \r to \r\n # Basically, we just transform bare \r to \r\n
if has_cr and b != ord("\n"): if has_cr and b != ord("\n"):
@ -924,10 +923,9 @@ function prompt {
if INTERACTIVE_END_MARKER[self.interactive_tracker] == b: if INTERACTIVE_END_MARKER[self.interactive_tracker] == b:
self.interactive_tracker += 1 self.interactive_tracker += 1
if self.interactive_tracker == len(INTERACTIVE_END_MARKER): if self.interactive_tracker == len(INTERACTIVE_END_MARKER):
# NOTE: this is a dirty hack to trigger the main input thread self.interactive_tracker = 0
# to leave interactive mode, because it's bound in an input call self.channel.unrecv(data[idx + 1 :])
os.kill(os.getpid(), signal.SIGINT) raise pwncat.util.RawModeExit
raise pwncat.manager.RawModeExit
else: else:
self.interactive_tracker = 0 self.interactive_tracker = 0