Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom named pipe permissions #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions analyzer/windows/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,10 @@ def prepare(self):

# Initialize and start the Pipe Servers. This is going to be used for
# communicating with the injected and monitored processes.

self.command_pipe = PipeServer(PipeDispatcher, self.config.pipe, message=True,
custom_sddl = self.options.get("custom_pipe_sddl")
if custom_sddl:
log.info("Using custom pipe sddl: %s", custom_sddl)
self.command_pipe = PipeServer(PipeDispatcher, self.config.pipe, message=True, custom_sddl=custom_sddl,
dispatcher=CommandPipeHandler(self))
self.command_pipe.daemon = True
self.command_pipe.start()
Expand All @@ -270,7 +272,8 @@ def prepare(self):
# open up a pipe that monitored processes will use to send logs to
# before they head off to the host machine.
destination = self.config.ip, self.config.port
self.log_pipe_server = PipeServer(PipeForwarder, self.config.logpipe, destination=destination)
self.log_pipe_server = PipeServer(PipeForwarder, self.config.logpipe, custom_sddl=custom_sddl,
destination=destination)

# We update the target according to its category. If it's a file, then
# we store the path.
Expand Down
2 changes: 2 additions & 0 deletions analyzer/windows/lib/common/defines.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@
TRUNCATE_EXISTING = 5
CREATE_NO_WINDOW = 0x08000000

SDDL_REVISION_1 = 1


class STARTUPINFO(Structure):
_fields_ = [
Expand Down
41 changes: 32 additions & 9 deletions analyzer/windows/lib/core/pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@

from ctypes import create_string_buffer, c_uint, byref, sizeof, addressof

from lib.common.defines import KERNEL32, PIPE_ACCESS_INBOUND, ERROR_MORE_DATA
from lib.common.defines import KERNEL32, PIPE_ACCESS_INBOUND, ERROR_MORE_DATA, PVOID
from lib.common.defines import PIPE_TYPE_BYTE, PIPE_WAIT, ERROR_PIPE_CONNECTED
from lib.common.defines import PIPE_UNLIMITED_INSTANCES, INVALID_HANDLE_VALUE
from lib.common.defines import FILE_FLAG_WRITE_THROUGH, PIPE_READMODE_BYTE
from lib.common.defines import PIPE_READMODE_BYTE
from lib.common.defines import ERROR_BROKEN_PIPE, PIPE_TYPE_MESSAGE
from lib.common.defines import PIPE_ACCESS_DUPLEX, PIPE_READMODE_MESSAGE
from lib.common.defines import SECURITY_DESCRIPTOR, SECURITY_ATTRIBUTES, ADVAPI32
from lib.common.defines import SECURITY_DESCRIPTOR, SECURITY_ATTRIBUTES, ADVAPI32, SDDL_REVISION_1

log = logging.getLogger(__name__)

BUFSIZE = 0x10000
Expand Down Expand Up @@ -150,26 +151,48 @@ def stop(self):
class PipeServer(threading.Thread):
"""Accept incoming pipe handlers and initialize them in a new thread."""

def __init__(self, pipe_handler, pipe_name, message=False, **kwargs):
def __init__(self, pipe_handler, pipe_name, message=False, custom_sddl=None, **kwargs):
threading.Thread.__init__(self)
self.pipe_handler = pipe_handler
self.pipe_name = pipe_name
self.message = message
self.custom_sddl = custom_sddl
self.kwargs = kwargs
self.do_run = True
self.handlers = set()

def get_custom_security_descriptor(self):
if not self.custom_sddl:
return None

sd = PVOID(0)
result = ADVAPI32.ConvertStringSecurityDescriptorToSecurityDescriptorW(
self.custom_sddl, SDDL_REVISION_1, addressof(sd), 0)
if result == 0:
err = KERNEL32.GetLastError()
log.warning("ConvertStringSecurityDescriptorToSecurityDescriptorW Failed. Err: %s", err)
return None

return sd

def run(self):
while self.do_run:
# Create the Named Pipe.
sd = SECURITY_DESCRIPTOR()
if self.custom_sddl:
lp_security_descriptor = self.get_custom_security_descriptor()
if lp_security_descriptor is None:
log.warning("Failed to create pipe server security attributes.")
continue
else:
sd = SECURITY_DESCRIPTOR()
ADVAPI32.InitializeSecurityDescriptor(byref(sd), 1)
ADVAPI32.SetSecurityDescriptorDacl(byref(sd), True, None, False)
lp_security_descriptor = addressof(sd)

sa = SECURITY_ATTRIBUTES()
ADVAPI32.InitializeSecurityDescriptor(byref(sd), 1)
ADVAPI32.SetSecurityDescriptorDacl(byref(sd), True, None, False)
sa.nLength = sizeof(SECURITY_ATTRIBUTES)
sa.bInheritHandle = False
sa.lpSecurityDescriptor = addressof(sd)
# flags = FILE_FLAG_WRITE_THROUGH
sa.lpSecurityDescriptor = lp_security_descriptor

if self.message:
pipe_handle = KERNEL32.CreateNamedPipeW(
Expand Down