mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Change RPC_SYNTAX_IDENTIFIER to RPC_IF_ID + update setup_hook + some add to wincli
This commit is contained in:
+32
-2
@@ -1,5 +1,7 @@
|
||||
import argparse
|
||||
import os.path
|
||||
import code
|
||||
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
@@ -27,7 +29,7 @@ def find_one_process_from_kwargs(pid=None, name=None, **kwargs):
|
||||
print("Multiple process with name {0}, please choose:".format(name))
|
||||
for i, proc in enumerate(targets):
|
||||
print(" {0}) {1}".format(i, proc))
|
||||
choice = raw_input("Number > ")
|
||||
choice = int(raw_input("Number > "), 0)
|
||||
try:
|
||||
return targets[choice]
|
||||
except IndexError:
|
||||
@@ -135,6 +137,18 @@ def proc_command_addr(**kwargs):
|
||||
if res[1] != "NOTFOUND":
|
||||
print(" * {0}!{1}+{2:#x}".format(mod.name, res[1], dist))
|
||||
|
||||
def proc_find_modules(**kwargs):
|
||||
targets = find_processes_from_kwargs(**kwargs)
|
||||
for target in targets:
|
||||
mod_name = kwargs["modname"]
|
||||
try:
|
||||
mods = [m.name for m in target.peb.modules if mod_name.lower() in m.name.lower()]
|
||||
if mods:
|
||||
print(target)
|
||||
print(mods)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# Services
|
||||
|
||||
def find_services_from_kwargs(name=None, **kwargs):
|
||||
@@ -164,12 +178,20 @@ def serv_command_list(**kwargs):
|
||||
for serv in find_services_from_kwargs(**kwargs):
|
||||
print (serv)
|
||||
|
||||
def serv_command_get(**kwargs):
|
||||
print("Listing services")
|
||||
servs = find_services_from_kwargs(**kwargs)
|
||||
code.InteractiveConsole(locals()).interact()
|
||||
|
||||
def serv_command_start(**kwargs):
|
||||
serv = find_one_service_from_kwargs(**kwargs)
|
||||
serv.start()
|
||||
serv = find_one_service_from_kwargs(**kwargs)
|
||||
print(serv)
|
||||
|
||||
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(prog=__file__)
|
||||
subparsers = parser.add_subparsers(description='valid subcommands',)
|
||||
|
||||
@@ -187,7 +209,7 @@ proc_list_parser_ = proc_subparsers.add_parser('list')
|
||||
proc_list_parser_.set_defaults(func=proc_command_list)
|
||||
|
||||
proc_inject_parser = proc_subparsers.add_parser('shell')
|
||||
proc_inject_parser.set_defaults(func=proc_command_shell)
|
||||
|
||||
|
||||
proc_inject_parser = proc_subparsers.add_parser('kill')
|
||||
proc_inject_parser.set_defaults(func=proc_command_kill)
|
||||
@@ -199,6 +221,10 @@ proc_addr_parser = proc_subparsers.add_parser('addr')
|
||||
proc_addr_parser.set_defaults(func=proc_command_addr)
|
||||
proc_addr_parser.add_argument('addresses', type=lambda x: int(x, 0), nargs="+", help='The addresses to explore')
|
||||
|
||||
proc_findmod_parser = proc_subparsers.add_parser('findmod')
|
||||
proc_findmod_parser.set_defaults(func=proc_find_modules)
|
||||
proc_findmod_parser.add_argument('modname', help='The name of the module to find')
|
||||
|
||||
# Services commandes
|
||||
serv_parser = subparsers.add_parser('serv')
|
||||
serv_parser.set_defaults(func=proc_command_list)
|
||||
@@ -214,6 +240,10 @@ serv_list_parser_.set_defaults(func=serv_command_list)
|
||||
serv_list_parser_ = serv_subparsers.add_parser('start')
|
||||
serv_list_parser_.set_defaults(func=serv_command_start)
|
||||
|
||||
serv_list_parser_ = serv_subparsers.add_parser('get')
|
||||
serv_list_parser_.set_defaults(func=serv_command_get)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
res = parser.parse_args()
|
||||
res.func(**res.__dict__)
|
||||
@@ -104,10 +104,8 @@ class IATHook(object):
|
||||
|
||||
|
||||
## New simple hook API based on winproxy
|
||||
|
||||
def setup_hook(target, hook, dll_to_hook):
|
||||
"TODO: Test and doc :D"
|
||||
dll_to_hook = "python27.dll"
|
||||
dll_name, api_name = windows.winproxy.get_target(target)
|
||||
prototype = target.prototype
|
||||
hook._types_info = (prototype._restype_,) + prototype._argtypes_
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import ndr
|
||||
from client import (RPC_SYNTAX_IDENTIFIER, RPCClient,
|
||||
REQUEST_TYPE_CALL, REQUEST_TYPE_BIND,
|
||||
RESPONSE_TYPE_BIND_OK, RESPONSE_TYPE_FAIL, RESPONSE_TYPE_SUCESS)
|
||||
from client import RPCClient, RPC_IF_ID
|
||||
|
||||
from epmapper import find_alpc_endpoint_and_connect, endpoint_map_alpc, construct_alpc_tower
|
||||
+45
-70
@@ -1,77 +1,62 @@
|
||||
import windows.alpc2 as alpc
|
||||
import windows.com
|
||||
from windows.generated_def import USHORT, DWORD, CHAR
|
||||
import ctypes
|
||||
import struct
|
||||
|
||||
import windows.alpc as alpc
|
||||
import windows.com
|
||||
import windows.generated_def as gdef
|
||||
|
||||
class _RPC_SYNTAX_IDENTIFIER(ctypes.Structure):
|
||||
|
||||
class _RPC_IF_ID(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("SyntaxGUID", windows.com.IID),
|
||||
("MajorVersion", USHORT),
|
||||
("MinorVersion", USHORT),
|
||||
("Uuid", gdef.IID),
|
||||
("MajorVersion", gdef.USHORT),
|
||||
("MinorVersion", gdef.USHORT),
|
||||
]
|
||||
|
||||
def __repr__(self):
|
||||
return '<RPC_SYNTAX_IDENTIFIER "{0}" ({1}, {2})>'.format(self.SyntaxGUID.to_string(), self.MajorVersion, self.MinorVersion)
|
||||
RPC_SYNTAX_IDENTIFIER = _RPC_SYNTAX_IDENTIFIER
|
||||
return '<RPC_IF_ID "{0}" ({1}, {2})>'.format(self.Uuid.to_string(), self.MajorVersion, self.MinorVersion)
|
||||
|
||||
# DEFINES
|
||||
|
||||
REQUEST_TYPE_CALL = 0
|
||||
REQUEST_TYPE_BIND = 1
|
||||
|
||||
KNOW_REQUEST_TYPE = {
|
||||
REQUEST_TYPE_CALL : "REQUEST_CALL",
|
||||
REQUEST_TYPE_BIND : "REQUEST_BIND",
|
||||
}
|
||||
RPC_IF_ID = _RPC_IF_ID
|
||||
|
||||
|
||||
RESPONSE_TYPE_BIND_OK = 1
|
||||
RESPONSE_TYPE_FAIL = 2
|
||||
RESPONSE_TYPE_SUCESS = 3
|
||||
KNOW_REQUEST_TYPE = {x:x for x in [gdef.RPC_REQUEST_TYPE_CALL, gdef.RPC_REQUEST_TYPE_BIND]}
|
||||
|
||||
|
||||
KNOW_RESPONSE_TYPE = {
|
||||
RESPONSE_TYPE_FAIL : "RESPONSE_FAIL",
|
||||
RESPONSE_TYPE_SUCESS : "RESPONSE_SUCESS",
|
||||
RESPONSE_TYPE_BIND_OK: "RESPONSE_BIND_OK",
|
||||
}
|
||||
KNOW_RESPONSE_TYPE = {x:x for x in [gdef.RPC_RESPONSE_TYPE_FAIL, gdef.RPC_RESPONSE_TYPE_SUCESS, gdef.RPC_RESPONSE_TYPE_SUCESS]}
|
||||
|
||||
|
||||
KNOWN_RPC_ERROR_CODE = {
|
||||
1783 : "RPC_X_BAD_STUB_DATA",
|
||||
1717 : "RPC_S_UNKNOWN_IF",
|
||||
1728 : "RPC_S_PROTOCOL_ERROR",
|
||||
1730 : "RPC_S_UNSUPPORTED_TRANS_SYN",
|
||||
1745 : "RPC_S_PROCNUM_OUT_OF_RANGE",
|
||||
}
|
||||
KNOWN_RPC_ERROR_CODE = {x:x for x in [
|
||||
gdef.ERROR_INVALID_HANDLE,
|
||||
gdef.RPC_X_BAD_STUB_DATA,
|
||||
gdef.RPC_S_UNKNOWN_IF,
|
||||
gdef.RPC_S_PROTOCOL_ERROR,
|
||||
gdef.RPC_S_UNSUPPORTED_TRANS_SYN,
|
||||
gdef.RPC_S_PROCNUM_OUT_OF_RANGE,
|
||||
]}
|
||||
|
||||
BIND_IF_SYNTAX_NDR32 = 1
|
||||
BIND_IF_SYNTAX_NDR64 = 2
|
||||
BIND_IF_SYNTAX_UNKNOWN = 4
|
||||
|
||||
NOT_USED = 0xBAADF00D
|
||||
|
||||
|
||||
class ALPC_RPC_BIND(ctypes.Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
("request_type", DWORD),
|
||||
("UNK1", DWORD),
|
||||
("UNK2", DWORD),
|
||||
("target", RPC_SYNTAX_IDENTIFIER),
|
||||
("flags", DWORD),
|
||||
("if_nb_ndr32", USHORT),
|
||||
("if_nb_ndr64", USHORT),
|
||||
("if_nb_unkn", USHORT),
|
||||
("PAD", USHORT),
|
||||
("register_multiple_syntax", DWORD),
|
||||
("use_flow", DWORD),
|
||||
("UNK5", DWORD),
|
||||
("maybe_flow_id", DWORD),
|
||||
("UNK7", DWORD),
|
||||
("some_context_id", DWORD),
|
||||
("UNK9", DWORD),
|
||||
("request_type", gdef.DWORD),
|
||||
("UNK1", gdef.DWORD),
|
||||
("UNK2", gdef.DWORD),
|
||||
("target", RPC_IF_ID),
|
||||
("flags", gdef.DWORD),
|
||||
("if_nb_ndr32", gdef.USHORT),
|
||||
("if_nb_ndr64", gdef.USHORT),
|
||||
("if_nb_unkn", gdef.USHORT),
|
||||
("PAD", gdef.USHORT),
|
||||
("register_multiple_syntax", gdef.DWORD),
|
||||
("use_flow", gdef.DWORD),
|
||||
("UNK5", gdef.DWORD),
|
||||
("maybe_flow_id", gdef.DWORD),
|
||||
("UNK7", gdef.DWORD),
|
||||
("some_context_id", gdef.DWORD),
|
||||
("UNK9", gdef.DWORD),
|
||||
]
|
||||
|
||||
|
||||
@@ -88,7 +73,7 @@ class RPCClient(object):
|
||||
response = self._send_request(request)
|
||||
# Parse reponse
|
||||
request_type = self._get_request_type(response)
|
||||
if request_type != RESPONSE_TYPE_BIND_OK:
|
||||
if request_type != gdef.RPC_RESPONSE_TYPE_BIND_OK:
|
||||
raise ValueError("Unexpected reponse type. Expected RESPONSE_TYPE_BIND_OK got {0}".format(KNOW_RESPONSE_TYPE.get(request_type, request_type)))
|
||||
iid_hash = hash(buffer(IID)[:]) # TODO: add __hash__ to IID
|
||||
self.if_bind_number[iid_hash] = self.number_of_bind_if
|
||||
@@ -103,7 +88,7 @@ class RPCClient(object):
|
||||
response = self._send_request(request)
|
||||
# Parse reponse
|
||||
request_type = self._get_request_type(response)
|
||||
if request_type != RESPONSE_TYPE_SUCESS:
|
||||
if request_type != gdef.RPC_RESPONSE_TYPE_SUCESS:
|
||||
raise ValueError("Unexpected reponse type. Expected RESPONSE_SUCESS got {0}".format(KNOW_RESPONSE_TYPE.get(request_type, request_type)))
|
||||
|
||||
data = struct.unpack("<6I", response[:6 * 4])
|
||||
@@ -117,18 +102,16 @@ class RPCClient(object):
|
||||
def _forge_call_request(self, interface_nb, method_offset, params):
|
||||
# TODO: differents REQUEST_IDENTIFIER for each req ?
|
||||
# TODO: what is this '0' ? (1 is also accepted) (flags ?)
|
||||
request = struct.pack("<16I", REQUEST_TYPE_CALL, NOT_USED, 1, self.REQUEST_IDENTIFIER, interface_nb, method_offset, *[NOT_USED] * 10)
|
||||
request = struct.pack("<16I", gdef.RPC_REQUEST_TYPE_CALL, NOT_USED, 1, self.REQUEST_IDENTIFIER, interface_nb, method_offset, *[NOT_USED] * 10)
|
||||
request += params
|
||||
return request
|
||||
|
||||
def _forge_bind_request(self, uuid, syntaxversion, requested_if_nb):
|
||||
# if syntaxversion == (1, 0):
|
||||
# requested_if_nb = 0x10000
|
||||
version_major, version_minor = syntaxversion
|
||||
req = ALPC_RPC_BIND()
|
||||
req.request_type = REQUEST_TYPE_BIND
|
||||
req.target = RPC_SYNTAX_IDENTIFIER(uuid, *syntaxversion)
|
||||
req.flags = BIND_IF_SYNTAX_NDR32
|
||||
req.request_type = gdef.RPC_REQUEST_TYPE_BIND
|
||||
req.target = RPC_IF_ID(uuid, *syntaxversion)
|
||||
req.flags = gdef.BIND_IF_SYNTAX_NDR32
|
||||
req.if_nb_ndr32 = requested_if_nb
|
||||
req.if_nb_ndr64 = 0
|
||||
req.if_nb_unkn = 0
|
||||
@@ -139,15 +122,7 @@ class RPCClient(object):
|
||||
def _get_request_type(self, response):
|
||||
"raise if request_type == RESPONSE_TYPE_FAIL"
|
||||
request_type = struct.unpack("<I", response[:4])[0]
|
||||
if request_type == RESPONSE_TYPE_FAIL:
|
||||
if request_type == gdef.RPC_RESPONSE_TYPE_FAIL:
|
||||
error_code = struct.unpack("<5I", response)[2]
|
||||
raise ValueError("RPC Response error {0} ({1})".format(error_code, KNOWN_RPC_ERROR_CODE.get(error_code, error_code)))
|
||||
return request_type
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("YOLO")
|
||||
import windows.rpc
|
||||
UAC_UIID = "201ef99a-7fa0-444c-9399-19ba84f12a1a"
|
||||
client = windows.rpc.find_alpc_endpoint_and_connect(UAC_UIID)
|
||||
iid = client.custom_bind(UAC_UIID)
|
||||
client.custom_call(iid, 0, "")
|
||||
return request_type
|
||||
@@ -69,14 +69,14 @@ def explode_alpc_tower(tower):
|
||||
if not (lhs[0] == 0xd):
|
||||
raise ValueError("Floor 0: IID expected")
|
||||
iid = windows.com.IID.from_buffer_copy(lhs[1:17])
|
||||
object = windows.rpc.RPC_SYNTAX_IDENTIFIER(iid, lhs[17], lhs[18])
|
||||
object = windows.rpc.RPC_IF_ID(iid, lhs[17], lhs[18])
|
||||
|
||||
# Floor 1
|
||||
lhs, rhs = parse_floor(stream)
|
||||
if not (lhs[0] == 0xd):
|
||||
raise ValueError("Floor 0: IID expected")
|
||||
iid = windows.com.IID.from_buffer_copy(lhs[1:17])
|
||||
syntax = windows.rpc.RPC_SYNTAX_IDENTIFIER(iid, lhs[17], lhs[18])
|
||||
syntax = windows.rpc.RPC_IF_ID(iid, lhs[17], lhs[18])
|
||||
|
||||
# Floor 2
|
||||
lhs, rhs = parse_floor(stream)
|
||||
@@ -100,11 +100,11 @@ def construct_alpc_tower(object, syntax, protseq, endpoint, address):
|
||||
if protseq != "ncalrpc":
|
||||
raise NotImplementedError("Construct ALPC Tower with protseq != 'ncalrpc'")
|
||||
# Floor 0
|
||||
floor_0_lsh = TOWER_PROTOCOL_IS_UUID + bytearray(object.SyntaxGUID) + struct.pack("<BB", object.MajorVersion, object.MinorVersion)
|
||||
floor_0_lsh = TOWER_PROTOCOL_IS_UUID + bytearray(object.Uuid) + struct.pack("<BB", object.MajorVersion, object.MinorVersion)
|
||||
floor_0_rsh = TOWER_EMPTY_RHS
|
||||
floor_0 = craft_floor(floor_0_lsh, floor_0_rsh)
|
||||
# Floor 1
|
||||
floor_1_lsh = TOWER_PROTOCOL_IS_UUID + bytearray(object.SyntaxGUID) + struct.pack("<BB", object.MajorVersion, object.MinorVersion)
|
||||
floor_1_lsh = TOWER_PROTOCOL_IS_UUID + bytearray(object.Uuid) + struct.pack("<BB", object.MajorVersion, object.MinorVersion)
|
||||
floor_1_rsh = TOWER_EMPTY_RHS
|
||||
floor_1 = craft_floor(floor_1_lsh, floor_1_rsh)
|
||||
# Floor 2
|
||||
@@ -127,10 +127,10 @@ def endpoint_map_alpc(targetiid, version=(1,0), nb_response=1, sid=gdef.WinLocal
|
||||
|
||||
# Compute request tower
|
||||
## object
|
||||
rpc_object = windows.rpc.RPC_SYNTAX_IDENTIFIER(targetiid, *version)
|
||||
rpc_object = windows.rpc.RPC_IF_ID(targetiid, *version)
|
||||
## Syntax
|
||||
syntax_iid = windows.com.IID.from_string("8a885d04-1ceb-11c9-9fe8-08002b104860")
|
||||
rpc_syntax = windows.rpc.RPC_SYNTAX_IDENTIFIER(syntax_iid, 2, 0)
|
||||
rpc_syntax = windows.rpc.RPC_IF_ID(syntax_iid, 2, 0)
|
||||
## Forge tower
|
||||
tower_array_size, towerarray = construct_alpc_tower(rpc_object, rpc_syntax, "ncalrpc", "", None)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user