Add missing psid.py + some rpc fix + alpc sample + wincli

This commit is contained in:
Clement Rouault
2017-05-24 17:49:46 +02:00
parent a89854a045
commit 1a73fe713b
6 changed files with 289 additions and 4 deletions
+40
View File
@@ -0,0 +1,40 @@
import multiprocessing
import windows.alpc
from windows.generated_def import LPC_CONNECTION_REQUEST, LPC_REQUEST
PORT_NAME = r"\RPC Control\YOLOPORT"
def alpc_server():
server = windows.alpc.AlpcServer(PORT_NAME)
print("[SERV] PORT CREATED")
attrs, msg = server.wait_data()
print("[SERV] Message type = {0:#x}".format(msg.u2.s2.Type))
print("[SERV] Received data: <{0}>".format(msg.data))
if msg.u2.s2.Type & LPC_CONNECTION_REQUEST:
print("[SERV] Connection request")
msg.data = "WOKAY"
server.accept_connection(msg)
attrs, msg = server.wait_data()
print("[SERV] Received message")
print("[SERV] Message type = {0:#x}".format(msg.u2.s2.Type))
if msg.u2.s2.Type & LPC_REQUEST:
print("[SERV] ALPC request: <{0}>".format(msg.data))
server.reply(msg, "REQUEST '{0}' DONE".format(msg.data))
def alpc_client():
client = windows.alpc.AlpcClient()
connect_response = client.connect_to_port(PORT_NAME, "COUCOU")
print("[CLIENT] Connected: {0}".format(connect_response.data))
print("[CLIENT] Send Message <POUET>")
attr, response = client.send_receive("POUET")
print("[CLIENT] Server response: <{0}>".format(response.data))
if __name__ == "__main__":
proc = multiprocessing.Process(target=alpc_server, args=())
proc.start()
import time; time.sleep(0.5)
alpc_client()
print("BYE")
+219
View File
@@ -0,0 +1,219 @@
import argparse
import os.path
import windows
import windows.generated_def as gdef
def find_processes_from_kwargs(pid=None, name=None, **kwargs):
if pid is None and name is None:
return windows.system.processes
if pid is not None:
return [p for p in windows.system.processes if p.pid == pid]
return [p for p in windows.system.processes if p.name.lower() == name.lower()]
def find_one_process_from_kwargs(pid=None, name=None, **kwargs):
if pid is not None:
targets = [p for p in windows.system.processes if p.pid == pid]
if not len(targets):
raise ValueError("Could not find process with pid <{0}>".format(pid))
assert len(targets) == 1
return targets[0]
targets = [p for p in windows.system.processes if p.name.lower() == name.lower()]
if not len(targets):
raise ValueError("Could not find a process with name <{0}>".format(name))
# Ask to choose a process
if len(targets) == 1:
return targets[0]
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 > ")
try:
return targets[choice]
except IndexError:
raise
def proc_command_list(**kwargs):
print("Listing processes")
for proc in find_processes_from_kwargs(**kwargs):
print (proc)
def proc_command_shell(**kwargs):
target = find_one_process_from_kwargs(**kwargs)
pfw_path = os.path.dirname(windows.__path__[0])
print("Using PythonForWindows at <{0}>".format(pfw_path))
try:
target.execute_python("import sys; sys.path.append(r'{0}')".format(pfw_path))
target.execute_python("import windows; windows.utils.pop_shell()")
except Exception as e:
print("Error while injecting python code: <{0!r}>".format(e))
raise
def proc_command_kill(**kwargs):
target = find_one_process_from_kwargs(**kwargs)
print(target.exit(0))
print(target)
def proc_command_killall(**kwargs):
targets = find_processes_from_kwargs(**kwargs)
for target in targets:
target.exit(0)
print(target)
PAGE_PROTECTIONS = [
gdef.PAGE_NOACCESS,
gdef.PAGE_READONLY,
gdef.PAGE_READWRITE,
gdef.PAGE_WRITECOPY,
gdef.PAGE_EXECUTE,
gdef.PAGE_EXECUTE_READ,
gdef.PAGE_EXECUTE_READWRITE,
gdef.PAGE_EXECUTE_WRITECOPY,
gdef.PAGE_GUARD,
gdef.PAGE_NOCACHE,
gdef.PAGE_WRITECOMBINE,
]
PAGE_PROTECTIONS_MAPPER = {x:x for x in PAGE_PROTECTIONS}
MEMORY_STATE = [gdef.MEM_COMMIT,
gdef.MEM_RESERVE,
gdef.MEM_DECOMMIT ,
gdef.MEM_RELEASE,
gdef.MEM_FREE,
gdef.MEM_PRIVATE,
gdef.MEM_MAPPED,
gdef.MEM_RESET,
gdef.MEM_TOP_DOWN ,
gdef.MEM_WRITE_WATCH,
gdef.MEM_PHYSICAL,
gdef.MEM_ROTATE,
gdef.MEM_LARGE_PAGES,
gdef.MEM_4MB_PAGES]
MEMORY_STATE_MAPPER = {x:x for x in MEMORY_STATE}
def proc_command_addr(**kwargs):
target = find_one_process_from_kwargs(**kwargs)
print(target)
for addr in kwargs["addresses"]:
print("== Address <{0:#x}> ==".format(addr, target))
data = target.query_memory(addr)
print("* BaseAddress = {0:#x}".format(data.BaseAddress))
print("* RegionSize = {0:#x}".format(data.RegionSize))
print("* State = {0}".format(MEMORY_STATE_MAPPER.get(data.RegionSize, data.RegionSize)))
print("* Protect = {0}".format(PAGE_PROTECTIONS_MAPPER.get(data.Protect, data.Protect)))
print('* MappedFile = "{0}"'.format(target.get_mapped_filename(addr)))
x = work_set = target.query_working_setex([addr])
attrs = x[0].VirtualAttributes
if attrs.valid:
print('* Shared = {0}'.format(bool(attrs.shared)))
# Module
for mod in target.peb.modules:
if mod.baseaddr <= addr < mod.baseaddr + mod.SizeOfImage:
break
else:
print("Not in a module")
return
print("Part of {0}".format(mod))
print(" * {0} + {1:#x}".format(mod.name, addr - mod.baseaddr))
exports = mod.pe.exports
res = (0xfffffff, "NOTFOUND")
for name, exportaddr in exports.items():
if isinstance(name, (int, long)):
continue
if exportaddr > addr:
continue
dist = addr - exportaddr
res = min((dist, name), res)
if dist == 0:
break
if res[1] != "NOTFOUND":
print(" * {0}!{1}+{2:#x}".format(mod.name, res[1], dist))
# Services
def find_services_from_kwargs(name=None, **kwargs):
if name is None:
return windows.system.services
return [p for p in windows.system.services if p.name.lower() == name.lower()]
def find_one_service_from_kwargs(name=None, **kwargs):
targets = [s for s in windows.system.services if s.name.lower() == name.lower()]
if not len(targets):
raise ValueError("Could not find a service with name <{0}>".format(name))
# Ask to choose a process
if len(targets) == 1:
return targets[0]
print("Multiple services with name {0}, please choose:".format(name))
for i, serv in enumerate(targets):
print(" {0}) {1}".format(i, serv))
choice = raw_input("Number > ")
try:
return targets[choice]
except IndexError:
raise
def serv_command_list(**kwargs):
print("Listing services")
for serv in find_services_from_kwargs(**kwargs):
print (serv)
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',)
# Processes commandes
proc_parser = subparsers.add_parser('proc')
proc_parser.set_defaults(func=proc_command_list)
group = proc_parser.add_mutually_exclusive_group()
group.add_argument('--pid', type=int, help='The pid of the process')
group.add_argument('--name', help='The name of the process')
proc_subparsers = proc_parser.add_subparsers(description='valid subcommands',)
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)
proc_inject_parser = proc_subparsers.add_parser('killall')
proc_inject_parser.set_defaults(func=proc_command_killall)
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')
# Services commandes
serv_parser = subparsers.add_parser('serv')
serv_parser.set_defaults(func=proc_command_list)
group = serv_parser.add_mutually_exclusive_group()
group.add_argument('--name', help='The name of the service')
serv_subparsers = serv_parser.add_subparsers(description='valid subcommands',)
serv_list_parser_ = serv_subparsers.add_parser('list')
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)
if __name__ == "__main__":
res = parser.parse_args()
res.func(**res.__dict__)
+2 -2
View File
@@ -1,3 +1,3 @@
from client import RPC_SYNTAX_IDENTIFIER, RPCClient
import ndr
from epmapper import find_alpc_endpoint_and_connect, construct_alpc_tower
from client import RPC_SYNTAX_IDENTIFIER, RPCClient
from epmapper import find_alpc_endpoint_and_connect, endpoint_map_alpc, construct_alpc_tower
+3 -1
View File
@@ -41,7 +41,9 @@ KNOW_RESPONSE_TYPE = {
KNOWN_RPC_ERROR_CODE = {
1783 : "RPC_X_BAD_STUB_DATA",
1717 : "RPC_S_UNKNOWN_IF"
1717 : "RPC_S_UNKNOWN_IF",
1745 : "RPC_S_PROCNUM_OUT_OF_RANGE"
}
NOT_USED = 0xBAADF00D
+6 -1
View File
@@ -34,7 +34,7 @@ class NdrUniquePTR(object):
def pack(self, data):
subpack = self.subcls.pack(data)
if subpack is None:
return dword_pad(0)
return pack_dword(0)
return pack_dword(0x02020202) + subpack
def pack_in_struct(self, data, id):
@@ -75,6 +75,11 @@ class NdrWString(object):
result += data
return dword_pad(result)
# @classmethod
# def unpack(self, stream):
# maxcount, offset, count = stream.partial_unpack("<3I")
# return maxcount, offset, count
class NdrLong(object):
@classmethod
def pack(cls, data):
+19
View File
@@ -0,0 +1,19 @@
from windows.generated_def import PSID
from windows import winproxy
class EPSID(PSID):
def __repr__(self):
return '<Sid "{0}" at {1:#8x}>'.format(str(self), id(self))
def __str__(self):
sid_str = LPCSTR()
winproxy.ConvertSidToStringSidA(self, sid_str)
result = sid_str.value
winproxy.LocalFree(sid_str)
return result
@classmethod
def from_string(cls, sidstr):
self = cls()
winproxy.ConvertStringSidToSidA(sidstr, self)
return self