commit alpc.py before rewriting

This commit is contained in:
Clement Rouault
2017-07-12 16:27:43 +02:00
parent 89fe39fadf
commit 5d34493356
2 changed files with 151 additions and 16 deletions
+146 -15
View File
@@ -41,17 +41,37 @@ class AlpcMessage(gn.PORT_MESSAGE):
data = property(read_data, write_data)
class MessageAttribute(gn.ALPC_MESSAGE_ATTRIBUTES):
def __new__(cls, flags):
size = cls._get_required_buffer_size(flags)
buffer = ctypes.c_buffer(size)
self = cls.from_buffer(buffer)
self.raw_buffer = buffer
return self
# def __new__(cls, flags):
# size = cls._get_required_buffer_size(flags)
# buffer = ctypes.c_buffer(size)
# self = cls.from_buffer(buffer)
# self.raw_buffer = buffer
# return self
ATTRIBUTE_BY_FLAG = [(gn.ALPC_MESSAGE_SECURITY_ATTRIBUTE, gn.ALPC_SECURITY_ATTR),
(gn.ALPC_MESSAGE_VIEW_ATTRIBUTE, gn.ALPC_DATA_VIEW_ATTR),
(gn.ALPC_MESSAGE_CONTEXT_ATTRIBUTE, gn.ALPC_CONTEXT_ATTR),
(gn.ALPC_MESSAGE_HANDLE_ATTRIBUTE, gn.ALPC_HANDLE_ATTR)]
#define ALPC_MESSAGE_SECURITY_ATTRIBUTE 0x80000000
#define ALPC_MESSAGE_VIEW_ATTRIBUTE 0x40000000
#define ALPC_MESSAGE_CONTEXT_ATTRIBUTE 0x20000000
#define ALPC_MESSAGE_HANDLE_ATTRIBUTE 0x10000000
def __init__(self, flags):
res = gn.DWORD()
winproxy.AlpcInitializeMessageAttribute(flags, self, len(self.raw_buffer), res)
@classmethod
def with_attributes(cls, flags):
size = cls._get_required_buffer_size(flags)
buffer = ctypes.c_buffer(size)
self = cls.from_buffer(buffer)
self.raw_buffer = buffer
res = gn.DWORD()
winproxy.AlpcInitializeMessageAttribute(flags, self, len(self.raw_buffer), res)
return self
@staticmethod
def _get_required_buffer_size(flags):
res = gn.DWORD()
@@ -62,6 +82,24 @@ class MessageAttribute(gn.ALPC_MESSAGE_ATTRIBUTES):
return res.value
return res.value
def is_allocated(self, value):
return self.AllocatedAttributes & value
def is_valid(self, value):
return self.ValidAttributes & value
def get_attribute(self, flag):
offset = ctypes.sizeof(self)
for sflag, struct in self.ATTRIBUTE_BY_FLAG:
if sflag == flag:
return struct.from_address(ctypes.addressof(self) + offset)
elif self.is_allocated(sflag):
offset += ctypes.sizeof(struct)
raise ValueError("ALPC Attribute Flag not found :(")
class AlpcPORT(object):
def __init__(self, port_name, msglen=0x1000):
@@ -86,6 +124,7 @@ class AlpcPORT(object):
port_attr = gn.ALPC_PORT_ATTRIBUTES()
port_attr.Flags = 0
# port_attr.Flags = 0x2080000 # Test
port_attr.MaxMessageLength = msglen
port_attr.MemoryBandwidth = 0
port_attr.MaxPoolUsage = 0
@@ -117,19 +156,77 @@ class AlpcPORT(object):
def send_receive_data(port_handle, data):
#sendmsg_attr = MessageAttribute(ALPC_MESSAGE_CONTEXT_ATTRIBUTE + ALPC_MESSAGE_HANDLE_ATTRIBUTE + 1)
sendmsg_attr = MessageAttribute(0)
# sendmsg_attr = MessageAttribute.with_attributes(ALPC_MESSAGE_VIEW_ATTRIBUTE)
# sendmsg_attr.ValidAttributes = ALPC_MESSAGE_VIEW_ATTRIBUTE
sendmsg_attr = MessageAttribute.with_attributes(0)
sendmsg = AlpcMessage(len(data))
sendmsg.data = data
# import pdb;pdb.set_trace()
size = gn.SIZE_T(0x1000)
receive = AlpcMessage(size.value)
receive_attr = MessageAttribute(0)
receive_attr = MessageAttribute.with_attributes(ALPC_MESSAGE_VIEW_ATTRIBUTE)
# Its strange that this line does not always have the same effect has the one bellow
# winproxy.NtAlpcSendWaitReceivePort(port_handle, ALPC_MSGFLG_SYNC_REQUEST, sendmsg, sendmsg_attr, receive, ctypes.byref(size), receive_attr, None)
winproxy.NtAlpcSendWaitReceivePort(port_handle, ALPC_MSGFLG_SYNC_REQUEST, sendmsg, sendmsg_attr, receive, size, receive_attr, None)
# winproxy.NtAlpcSendWaitReceivePort(port_handle, 0x40020000, sendmsg, sendmsg_attr, receive, size, receive_attr, None)
return receive_attr, receive
class ALPC_DATA_VIEW_ATTR(ctypes.Structure): # _ALPC_DATA_VIEW_ATTR
_fields_ = [
("Flags", gn.ULONG),
("SectionHandle", gn.HANDLE),
("ViewBase", gn.ULONG), # must be zero on input
("ViewSize", gn.ULONG)
]
class ALPC_DATA_VIEW_ATTR64(ctypes.Structure): # _ALPC_DATA_VIEW_ATTR
_fields_ = [
("Flags", gn.ULONG),
("SectionHandle", gn.HANDLE),
("ViewBase", gn.ULONGLONG), # must be zero on input
("ViewSize", gn.ULONGLONG)
]
def send_receive_data_view(port_handle, data, view):
sendmsg_attr = MessageAttribute.with_attributes(ALPC_MESSAGE_VIEW_ATTRIBUTE)
sendmsg_attr.ValidAttributes = ALPC_MESSAGE_VIEW_ATTRIBUTE
view_attr = ALPC_DATA_VIEW_ATTR64.from_address(ctypes.addressof(sendmsg_attr) + 8)
# view_attr.Flags = 0x60000 # 0x20000 -> Unmap la section dans le sender
view_attr.Flags = 0x40000
# view_attr.Flags = 0x10000
view_attr.SectionHandle = view.SectionHandle
view_attr.ViewBase = view.ViewBase
view_attr.ViewSize = view.ViewSize
xx = windows.winproxy.AlpcGetMessageAttribute(sendmsg_attr, ALPC_MESSAGE_VIEW_ATTRIBUTE)
sendmsg = AlpcMessage(len(data))
sendmsg.data = data
print(sendmsg_attr.ValidAttributes)
size = gn.SIZE_T(0x1000)
receive = AlpcMessage(size.value)
receive_attr = MessageAttribute.with_attributes(ALPC_MESSAGE_VIEW_ATTRIBUTE)
receive_attr.ValidAttributes = ALPC_MESSAGE_VIEW_ATTRIBUTE
# Its strange that this line does not always have the same effect has the one bellow
# winproxy.NtAlpcSendWaitReceivePort(port_handle, ALPC_MSGFLG_SYNC_REQUEST, sendmsg, sendmsg_attr, receive, ctypes.byref(size), receive_attr, None)
# winproxy.NtAlpcSendWaitReceivePort(port_handle, 0, sendmsg, sendmsg_attr, None, size, None, None)
winproxy.NtAlpcSendWaitReceivePort(port_handle, ALPC_MSGFLG_SYNC_REQUEST , sendmsg, sendmsg_attr, receive, size, receive_attr, None)
# winproxy.NtAlpcSendWaitReceivePort(port_handle, 0x000000000410000, sendmsg, sendmsg_attr, None, None, None, None)
# 0000000000410000 # Flags ?
print(hex(windows.current_process.query_memory(view.ViewBase).State))
print(hex(windows.current_process.query_memory(view.ViewBase).Protect))
return receive_attr, receive
class AlpcClient(object):
def __init__(self):
self.portname = None
@@ -176,10 +273,12 @@ class AlpcClient(object):
#port_attr.MaxPoolUsage = 0
port_attr.Flags = 0x10000 # Flag qui fonctionne pour l'UAC
port_attr.Flags = 0x2090000 # Test
port_attr.Flags = 0x2080000 # Test # Tes2
# 0x0010000 est le flag qui permet l'impersonation (en tout cas le pop UAC)
#port_attr.MaxPoolUsage = 4294967295
#port_attr.MaxSectionSize = 4294967295
##port_attr.MaxViewSize = 4294967295
port_attr.MaxViewSize = 4294967295
#port_attr.MaxTotalSectionSize = 4294967295
#port_attr.DupObjectTypes = 4093
@@ -196,13 +295,12 @@ class AlpcClient(object):
# tst.MaxTotalSectionSize -> 4294967295
# tst.DupObjectTypes -> 4093
if connect_msg is not None:
size = len(connect_msg)
send_msg = AlpcMessage(size)
send_msg.data = connect_msg
sendmsg_attr = MessageAttribute(0)
receive_attr = MessageAttribute(0)
sendmsg_attr = MessageAttribute.with_attributes(0)
receive_attr = MessageAttribute.with_attributes(0)
receive_attr = None
sendmsg_attr = None
buffersize = gn.DWORD(len(send_msg.raw_buffer))
@@ -217,6 +315,7 @@ class AlpcClient(object):
#import pdb;pdb.set_trace()
x = winproxy.NtAlpcConnectPort(handle, port_name,obj_attr, port_attr, ALPC_MSGFLG_SYNC_REQUEST, None, send_msg, buffersize, sendmsg_attr, receive_attr, None)
# If send_msg is not None, it contains the ClientId.UniqueProcess : PID of the server :)
self.handle = handle.value
self.portname = port_name
if connect_msg is not None:
@@ -225,6 +324,10 @@ class AlpcClient(object):
def send_receive(self, data):
return send_receive_data(self.handle, data)
def send_receive_view(self, data, view):
return send_receive_data_view(self.handle, data, view)
class AlpcServer(object):
def __init__(self, port_name):
self.port = AlpcPORT(port_name)
@@ -232,7 +335,8 @@ class AlpcServer(object):
def wait_data(self):
size = gn.SIZE_T(0x1000)
receive = AlpcMessage(size.value)
receive_attr = MessageAttribute(0)
# receive_attr = MessageAttribute(0)
receive_attr = MessageAttribute.with_attributes(ALPC_MESSAGE_VIEW_ATTRIBUTE)
winproxy.NtAlpcSendWaitReceivePort(self.port.handle, 0, None, None, receive, size, receive_attr, None)
return receive_attr, receive
@@ -243,6 +347,8 @@ class AlpcServer(object):
ALPC_HANDLEFLG_DUPLICATE_INHERIT = 0x80000
port_attr = gn.ALPC_PORT_ATTRIBUTES()
port_attr.Flags = ALPC_HANDLEFLG_DUPLICATE_INHERIT
# port_attr.Flags = ALPC_HANDLEFLG_DUPLICATE_INHERIT + 0x30000 # Testing
# port_attr.Flags = 0x2080000 # Testing
port_attr.DupObjectTypes = 4
port_attr.MaxMessageLength = 0x578
port_attr.MemoryBandwidth = 0
@@ -258,8 +364,33 @@ class AlpcServer(object):
port_handle = self.port.handle
sendmsg = AlpcMessage(len(reply_msg))
sendmsg.data = reply_msg
sendmsg_attr = MessageAttribute(0)
sendmsg_attr = MessageAttribute.with_attributes(0)
sendmsg.MessageId = reply_to_msg.MessageId
winproxy.NtAlpcSendWaitReceivePort(port_handle, ALPC_MSGFLG_RELEASE_MESSAGE, sendmsg, None, None, None, None, None)
return None, None
def reply_with_view(self, reply_to_msg, reply_msg, view):
sendmsg_attr = MessageAttribute.with_attributes(ALPC_MESSAGE_VIEW_ATTRIBUTE)
sendmsg_attr.ValidAttributes = ALPC_MESSAGE_VIEW_ATTRIBUTE
view_attr = ALPC_DATA_VIEW_ATTR.from_address(ctypes.addressof(sendmsg_attr) + 8)
view_attr.Flags = 0x60000 # 0x20000 -> Unmap la section dans le sender
# view_attr.Flags = 0x40000
# view_attr.Flags = 0x40000
view_attr.SectionHandle = view.SectionHandle
view_attr.ViewBase = view.ViewBase
view_attr.ViewSize = view.ViewSize
print("Section jandle = {0}".format(view.SectionHandle))
windows.current_process.write_memory(view.ViewBase, "SERRRRVVVVVV")
port_handle = self.port.handle
sendmsg = AlpcMessage(len(reply_msg))
sendmsg.data = reply_msg
# sendmsg_attr = MessageAttribute.with_attributes(0)
sendmsg.MessageId = reply_to_msg.MessageId
winproxy.NtAlpcSendWaitReceivePort(port_handle, 0x410000, sendmsg, sendmsg_attr, None, None, None, None)
return None, None
+5 -1
View File
@@ -972,7 +972,6 @@ ALPC_MESSAGE_SECURITY_ATTRIBUTE = make_flag("ALPC_MESSAGE_SECURITY_ATTRIBUTE", 0
ALPC_MESSAGE_VIEW_ATTRIBUTE = make_flag("ALPC_MESSAGE_VIEW_ATTRIBUTE", 0x40000000)
ALPC_MESSAGE_CONTEXT_ATTRIBUTE = make_flag("ALPC_MESSAGE_CONTEXT_ATTRIBUTE", 0x20000000)
ALPC_MESSAGE_HANDLE_ATTRIBUTE = make_flag("ALPC_MESSAGE_HANDLE_ATTRIBUTE", 0x10000000)
ALPC_VIEWFLG_NOT_SECURE = make_flag("ALPC_VIEWFLG_NOT_SECURE", 0x40000)
ALPC_MSGFLG_REPLY_MESSAGE = make_flag("ALPC_MSGFLG_REPLY_MESSAGE", 0x1)
ALPC_MSGFLG_LPC_MODE = make_flag("ALPC_MSGFLG_LPC_MODE", 0x2)
ALPC_MSGFLG_RELEASE_MESSAGE = make_flag("ALPC_MSGFLG_RELEASE_MESSAGE", 0x10000)
@@ -983,6 +982,11 @@ ALPC_MSGFLG_WOW64_CALL = make_flag("ALPC_MSGFLG_WOW64_CALL", 0x80000000)
ALPC_CANCELFLG_TRY_CANCEL = make_flag("ALPC_CANCELFLG_TRY_CANCEL", 0x1)
ALPC_CANCELFLG_NO_CONTEXT_CHECK = make_flag("ALPC_CANCELFLG_NO_CONTEXT_CHECK", 0x8)
ALPC_CANCELFLGP_FLUSH = make_flag("ALPC_CANCELFLGP_FLUSH", 0x10000)
ALPC_HANDLEFLG_DUPLICATE_SAME_ACCESS = make_flag("ALPC_HANDLEFLG_DUPLICATE_SAME_ACCESS", 0x10000)
ALPC_HANDLEFLG_DUPLICATE_SAME_ATTRIBUTES = make_flag("ALPC_HANDLEFLG_DUPLICATE_SAME_ATTRIBUTES", 0x20000)
ALPC_HANDLEFLG_DUPLICATE_INHERIT = make_flag("ALPC_HANDLEFLG_DUPLICATE_INHERIT", 0x80000)
ALPC_SECFLG_CREATE_HANDLE = make_flag("ALPC_SECFLG_CREATE_HANDLE", 0x20000)
ALPC_VIEWFLG_NOT_SECURE = make_flag("ALPC_VIEWFLG_NOT_SECURE", 0x40000)
OWNER_SECURITY_INFORMATION = make_flag("OWNER_SECURITY_INFORMATION", ( 0x00000001 ))
GROUP_SECURITY_INFORMATION = make_flag("GROUP_SECURITY_INFORMATION", ( 0x00000002 ))
DACL_SECURITY_INFORMATION = make_flag("DACL_SECURITY_INFORMATION", ( 0x00000004 ))