Still working on RPC over alpc

This commit is contained in:
Clement Rouault
2017-07-06 18:11:32 +02:00
parent aff6ee4e17
commit 5e2ecf2af9
2 changed files with 59 additions and 5 deletions
+6 -4
View File
@@ -118,7 +118,7 @@ def construct_alpc_tower(object, syntax, protseq, endpoint, address):
towerarray = struct.pack("<H", 4) + floor_0 + floor_1 + floor_2 + floor_3
return len(towerarray), bytearray(towerarray)
def endpoint_map_alpc(targetiid, version=(1,0), nb_response=1):
def endpoint_map_alpc(targetiid, version=(1,0), nb_response=1, sid=gdef.WinLocalSystemSid):
if isinstance(targetiid, basestring):
targetiid = windows.com.IID.from_string(targetiid)
# Connect to epmapper
@@ -135,7 +135,7 @@ def endpoint_map_alpc(targetiid, version=(1,0), nb_response=1):
tower_array_size, towerarray = construct_alpc_tower(rpc_object, rpc_syntax, "ncalrpc", "", None)
# parameters
local_system_psid = windows.utils.get_known_sid(gdef.WinLocalSystemSid)
local_system_psid = windows.utils.get_known_sid(sid)
context = (0, 0, 0, 0, 0)
# Pack request
@@ -154,8 +154,10 @@ def endpoint_map_alpc(targetiid, version=(1,0), nb_response=1):
return [explode_alpc_tower(obj) for obj in unpacked[2]]
def find_alpc_endpoint_and_connect(targetiid, version=(1,0)):
alpctowers = endpoint_map_alpc(targetiid, version, nb_response=50)
def find_alpc_endpoint_and_connect(targetiid, version=(1,0), sid=gdef.WinLocalSystemSid):
dbgprint("Finding ALPC endpoints for <{0}>".format(targetiid), "RPC")
alpctowers = endpoint_map_alpc(targetiid, version, nb_response=50, sid=sid)
dbgprint("ALPC endpoints list: <{0}>".format(alpctowers), "RPC")
for tower in alpctowers:
dbgprint("Trying to connect to endpoint <{0}>".format(tower.endpoint), "RPC")
alpc_port = r"\RPC Control\{0}".format(tower.endpoint)
+53 -1
View File
@@ -37,7 +37,15 @@ class NdrUniquePTR(object):
return pack_dword(0)
return pack_dword(0x02020202) + subpack
def unpack(self, stream):
ptr = NdrLong.unpack(stream)
if not ptr:
return None
return self.subcls.unpack(stream)
def pack_in_struct(self, data, id):
if data is None:
return pack_dword(0), None
subpack = self.subcls.pack(data)
if subpack is None:
return pack_dword(0), None
@@ -55,6 +63,16 @@ class NdrUniquePTR(object):
return None
return self.subcls.parse(stream)
class NdrFixedArray(object):
def __init__(self, subcls, size):
self.subcls = subcls
self.size = size
def pack(self, data):
data = list(data)
assert len(data) == self.size
return dword_pad("".join([self.subcls.pack(elt) for elt in data]))
class NdrSID(object):
@classmethod
@@ -64,6 +82,11 @@ class NdrSID(object):
sid_data = windows.current_process.read_memory(psid.value, size)
return pack_dword(subcount[0]) + dword_pad(sid_data)
@classmethod
def unpack(cls, stream):
subcount = NdrLong.unpack(stream)
return stream.read(8 + (subcount * 4))
class NdrWString(object):
@classmethod
def pack(cls, data):
@@ -75,6 +98,15 @@ class NdrWString(object):
result += data
return dword_pad(result)
@classmethod
def unpack(cls, stream):
stream.align(4)
size1, zero, size2 = stream.partial_unpack("<3I")
assert size1 == size2
assert zero == 0
s = stream.read(size1 * 2)
return s.decode("utf-16-le")
class NdrCString(object):
@classmethod
def pack(cls, data):
@@ -97,8 +129,28 @@ class NdrLong(object):
@classmethod
def unpack(self, stream):
stream.align(4)
return stream.partial_unpack("<I")[0]
class NdrHyper(object):
@classmethod
def pack(cls, data):
return struct.pack("<Q", data)
@classmethod
def unpack(self, stream):
stream.align(4)
return stream.partial_unpack("<Q")[0]
class NdrShort(object):
@classmethod
def pack(cls, data):
return struct.pack("<H", data)
@classmethod
def unpack(self, stream):
return stream.partial_unpack("<H")[0]
class NdrByte(object):
@classmethod
@@ -174,7 +226,7 @@ class NdrParameters(object):
for (member, memberdata) in zip(cls.MEMBERS, data):
packed_member = member.pack(memberdata)
res.append(packed_member)
return dword_pad("".join(res))
return "".join(dword_pad(elt) for elt in res)
@classmethod
def unpack(cls, stream):