Exemple #1
0
    def load_library(self, libpath):
        libpath = os.path.abspath(libpath)
        libpath_len = align_up(len(libpath) + 1, 0x200)
        LoadLibraryA = self.k32.GetProcAddress(
            self.k32.GetModuleHandleA("kernel32.dll"), "LoadLibraryA")
        RemotePage = self.k32.VirtualAllocEx(self.handle, None,
                                             len(libpath) + 1,
                                             flags("MEM_COMMIT"),
                                             flags("PAGE_EXECUTE_READWRITE"))
        if not RemotePage:
            raise WindowsProcessError(
                'Error: failed to allocate space for library name in the target process'
            )
        self.k32.WriteProcessMemory(self.handle, RemotePage, libpath,
                                    len(libpath), None)
        RemoteThread = self.k32.CreateRemoteThread(self.handle, None, 0,
                                                   LoadLibraryA, RemotePage, 0,
                                                   None)
        self.k32.WaitForSingleObject(RemoteThread, -1)

        exitcode = wintypes.DWORD(0)
        self.k32.GetExitCodeThread(RemoteThread, ctypes.byref(exitcode))
        self.k32.VirtualFreeEx(self.handle, RemotePage, len(libpath),
                               flags("MEM_RELEASE"))
        if exitcode.value == 0:
            raise WindowsProcessError('Error: failed to load: ' +
                                      repr(libpath))
        self._update_maps()
        return exitcode.value
Exemple #2
0
    def __init__(self, os_name=None):
        """
		:param str os_name: The name of the Windows operating system for which to resolve syscall names to numbers.
		"""
        if process_is_wow64():
            raise RuntimeError('python running in WOW64 is not supported')

        self._syscall_db_con = None
        if os_name is None:
            os_name = self.__name_map.get(platform.platform())
        if os_name is not None:
            self._syscall_db_con = sqlite3.connect(self._syscall_db_path,
                                                   check_same_thread=False)
            if not self._syscall_db_con.execute(
                    'SELECT COUNT(os_name) FROM syscalls WHERE arch = ? AND os_name = ?',
                (
                    self._syscall_arch,
                    os_name,
                )).fetchone()[0]:
                raise ValueError(
                    'no syscall numbers available in the database for ' +
                    os_name)
        self.os_name = os_name

        process_h = WindowsProcess(pid=-1)
        shellcode_sz = align_up(len(self._syscall_stub), 1024)
        self.address = process_h.allocate(size=shellcode_sz)
        process_h.write_memory(self.address, self._syscall_stub)
        process_h.protect(self.address,
                          size=shellcode_sz,
                          permissions='PAGE_EXECUTE_READ')
        self._syscall = self._syscall_prototype(self.address)
Exemple #3
0
def main():
	parser = argparse.ArgumentParser(
		description='syringe: library & shellcode injection utility',
		conflict_handler='resolve',
		epilog='The PID argument can be specified as -1 to inject into the context of the syringe process.'
	)
	parser.add_argument('-l', '--load', dest='library', action='store', help='load the library in the target process')
	shellcode_group = parser.add_mutually_exclusive_group()
	shellcode_group.add_argument('-i', '--inject', dest='shellcode', action='store', help='inject code into the process')
	shellcode_group.add_argument('-f', '--inject-file', dest='shellcode_file', type=argparse.FileType('rb'), help='inject code from a file into the process')
	parser.add_argument('-d', '--decode', dest='decode', action='store', choices=('b64', 'hex', 'raw'), default='b64', help='decode the shellcode prior to execution')
	parser.add_argument('pid', action='store', type=int, help='process to control')
	arguments = parser.parse_args()

	try:
		process_h = NativeProcess(pid=arguments.pid)
	except ProcessError as error:
		print("[-] {0}".format(error.msg))
		return
	print("[+] Opened a handle to pid: {0}".format(arguments.pid))

	if arguments.library:
		try:
			lib_h = process_h.load_library(arguments.library)
		except ProcessError as error:
			print("[-] {0}".format(error.msg))
		else:
			print("[+] Loaded {0} with handle 0x{1:08x}".format(arguments.library, lib_h))

	if arguments.shellcode or arguments.shellcode_file:
		if arguments.shellcode:
			shellcode = arguments.shellcode
		else:
			shellcode = arguments.shellcode_file.read()
			arguments.shellcode_file.close()
		if arguments.decode == 'b64':
			shellcode = shellcode.decode('base64')
		elif arguments.decode == 'hex':
			shellcode = shellcode.decode('hex')
		stub = "" # no stub by default
		if architecture_is_32bit(process_h.arch):
			stub = "\x8b\x44\x24\x04" # mov eax,[esp+4]
		elif architecture_is_64bit(process_h.arch):
			stub = "\x48\x8b\x44\x24\x08" # mov rax,[rsp+8]

		shellcode_sz = align_up(len(stub + shellcode), 1024)
		address = process_h.allocate(size=shellcode_sz, address=0)
		print("[+] Allocated {0} bytes at 0x{1:08x}".format(shellcode_sz, address))
		process_h.protect(address, size=shellcode_sz)
		process_h.write_memory(address, stub + shellcode)
		thread_id = process_h.start_thread(address, (address + len(stub)))
		print("[+] Started thread at 0x{0:08x}".format(address))
		print("[*] Waiting for thread to complete...")
		try:
			process_h.join_thread(thread_id)
			print("[+] Thread completed")
		except ProcessError as err:
			print("[-] {0} {1}".format(err.__class__.__name__, err.msg))

	process_h.close()
Exemple #4
0
def main():
    parser = argparse.ArgumentParser(
        description='memgrep: memory search utility',
        conflict_handler='resolve')
    parser.add_argument('pid',
                        action='store',
                        type=int,
                        help='process to control')
    parser.add_argument('search_data',
                        action='store',
                        help='data to search for')
    parser.add_argument('-e',
                        '--encoding',
                        default='utf-8',
                        help='the encoding of search_data')
    arguments = parser.parse_args()

    search_data = arguments.search_data.encode(arguments.encoding)
    if len(search_data) < 4:
        print(
            '[-] searching for less than 4 bytes will yield too many results')
        return 0

    process_h = NativeProcess(pid=arguments.pid)
    print("[*] searching {0} regions of memory".format(len(process_h.maps)))

    num_matches = 0
    num_skips = 0
    num_errors = 0

    for mem_region in process_h.maps.values():
        print("[*] searching 0x{0:08x} - 0x{1:08x} (0x{2:08x} bytes)".format(
            mem_region.addr_low, mem_region.addr_high, mem_region.size))
        if not mem_region.is_readable:
            print("[-] skipped unreadable region at 0x{0:08x}".format(
                mem_region.addr_low))
            num_skips += 1
            continue
        try:
            data = process_h.read_memory(mem_region.addr_low, mem_region.size)
        except ProcessError as error:
            print("[-] encountered {0} while reading at 0x{1:08x}".format(
                error.__class__.__name__, mem_region.addr_low))
            num_errors += 1
            continue
        cursor = data.find(search_data)
        while cursor != -1:
            data_slice = data[align_down(cursor):align_up(cursor +
                                                          len(search_data))]
            low_addr = align_down(mem_region.addr_low + align_down(cursor))
            print("[+] found match at 0x{0:08x}".format(mem_region.addr_low +
                                                        cursor))
            num_matches += 1
            print_hexdump(data_slice, low_addr)
            cursor = data.find(search_data, cursor + 1)

    process_h.close()
    print("[*] summary - matches: {0} errors: {1} skipped regions: {2}".format(
        num_matches, num_errors, num_skips))
Exemple #5
0
	def __init__(self, syscall_map=None):
		self.syscall_map = syscall_map

		process_h = WindowsProcess(pid=-1)
		shellcode_sz = align_up(len(syscall_stub), 1024)
		self.address = process_h.allocate(size=shellcode_sz)
		process_h.write_memory(self.address, syscall_stub)
		process_h.protect(self.address, size=shellcode_sz, permissions='PAGE_EXECUTE_READ')
		self._syscall = syscall_prototype(self.address)
def main():
	parser = ArgumentParser(description='python_injector: inject python code into a process', conflict_handler='resolve')
	parser.add_argument('shellcode', action='store', help='python code to inject into the process')
	parser.add_argument('pid', action='store', type=int, help='process to inject into')
	arguments = parser.parse_args()

	if not sys.platform.startswith('win'):
		print('[-] This tool is only available on Windows')
		return

	# get a handle the the process
	try:
		process_h = NativeProcess(pid=arguments.pid)
	except ProcessError as error:
		print("[-] {0}".format(error.msg))
		return
	print("[+] Opened a handle to pid: {0}".format(arguments.pid))

	# find and inject the python library
	python_lib = "python{0}{1}.dll".format(sys.version_info.major, sys.version_info.minor)
	python_lib = ctypes.util.find_library(python_lib)
	if python_lib:
		print("[*] Found Python library at: {0}".format(python_lib))
	else:
		print('[-] Failed to find the Python library')
		return

	print('[*] Injecting Python into the process...')
	try:
		python_lib_h = process_h.load_library(python_lib)
	except ProcessError as error:
		print("[-] {0}".format(error.msg))
		return
	else:
		print("[+] Loaded {0} with handle 0x{1:08x}".format(python_lib, python_lib_h))

	# resolve the necessary functions
	k32 = ctypes.windll.kernel32
	local_handle = k32.GetModuleHandleA(python_lib)
	py_initialize_ex = python_lib_h + (k32.GetProcAddress(local_handle, 'Py_InitializeEx') - local_handle)
	py_run_simple_string = python_lib_h + (k32.GetProcAddress(local_handle, 'PyRun_SimpleString') - local_handle)
	print('[*] Resolved address:')
	print("  - Py_InitializeEx:    0x{0:08x}".format(py_initialize_ex))
	print("  - PyRun_SimpleString: 0x{0:08x}".format(py_run_simple_string))

	# call remote functions to initialize and run via remote threads
	thread_h = process_h.start_thread(py_initialize_ex, 0)
	process_h.join_thread(thread_h)

	shellcode = arguments.shellcode
	shellcode_addr = process_h.allocate(size=align_up(len(shellcode)), permissions='PAGE_READWRITE')
	process_h.write_memory(shellcode_addr, shellcode)
	thread_h = process_h.start_thread(py_run_simple_string, shellcode_addr)
	process_h.join_thread(thread_h)

	process_h.close()
Exemple #7
0
	def load_library(self, libpath):
		libpath = os.path.abspath(libpath)
		libpath_len = align_up(len(libpath) + 1, 0x200)
		LoadLibraryA = self.k32.GetProcAddress(self.k32.GetModuleHandleA("kernel32.dll"), "LoadLibraryA")
		RemotePage = self.k32.VirtualAllocEx(self.handle, None, len(libpath) + 1, flags("MEM_COMMIT"), flags("PAGE_EXECUTE_READWRITE"))
		if not RemotePage:
			raise WindowsProcessError('Error: failed to allocate space for library name in the target process')
		self.k32.WriteProcessMemory(self.handle, RemotePage, libpath, len(libpath), None)
		RemoteThread = self.k32.CreateRemoteThread(self.handle, None, 0, LoadLibraryA, RemotePage, 0, None)
		self.k32.WaitForSingleObject(RemoteThread, -1)

		exitcode = wintypes.DWORD(0)
		self.k32.GetExitCodeThread(RemoteThread, ctypes.byref(exitcode))
		self.k32.VirtualFreeEx(self.handle, RemotePage, len(libpath), flags("MEM_RELEASE"))
		if exitcode.value == 0:
			raise WindowsProcessError('Error: failed to load: ' + repr(libpath))
		self._update_maps()
		return exitcode.value
Exemple #8
0
def main():
	parser = ArgumentParser(description='memgrep: memory search utility', conflict_handler='resolve')
	parser.add_argument('pid', action='store', type=int, help='process to control')
	parser.add_argument('search_data', action='store', help='data to search for')
	arguments = parser.parse_args()

	search_data = arguments.search_data
	if len(search_data) < 4:
		print('[-] searching for less than 4 bytes will yield too many results')
		return 0

	process_h = NativeProcess(pid=arguments.pid)
	print("[*] searching {0} regions of memory".format(len(process_h.maps)))

	num_matches = 0
	num_skips = 0
	num_errors = 0

	mem_region_keys = process_h.maps.keys()
	mem_region_keys.sort()
	for mr in mem_region_keys:
		mem_region = process_h.maps[mr]
		print("[*] searching 0x{0:04x} bytes at 0x{1:08x}".format(mem_region.size, mem_region.addr_low))
		if not mem_region.is_readable:
			print("[-] skipped unreadable region at 0x{0:08x}".format(mem_region.addr_low))
			num_skips += 1
			continue
		try:
			data = process_h.read_memory(mem_region.addr_low, mem_region.size)
		except ProcessError as err:
			print("[-] encountered {0} while reading at 0x{1:08x}".format(err.__class__.__name__, mem_region.addr_low))
			num_errors += 1
			continue
		cursor = data.find(search_data)
		while cursor != -1:
			data_slice = data[align_down(cursor):align_up(cursor + len(search_data))]
			low_addr = align_down(mem_region.addr_low + align_down(cursor))
			print("[+] found match at 0x{0:08x}".format(mem_region.addr_low + cursor))
			num_matches += 1
			print_hexdump(data_slice, low_addr)
			cursor = data.find(search_data, cursor + 1)

	process_h.close()
	print("[*] summary - matches: {0} errors: {1} skipped regions: {2}".format(num_matches, num_errors, num_skips))
Exemple #9
0
	def __init__(self, os_name=None):
		"""
		:param str os_name: The name of the Windows operating system for which to resolve syscall names to numbers.
		"""
		if process_is_wow64():
			raise RuntimeError('python running in WOW64 is not supported')

		self._syscall_db_con = None
		if os_name is not None:
			self._syscall_db_con = sqlite3.connect(self._syscall_db_path, check_same_thread=False)
			if not self._syscall_db_con.execute('SELECT COUNT(os_name) FROM syscalls WHERE arch = ? AND os_name = ?', (self._syscall_arch, os_name,)).fetchone()[0]:
				raise ValueError('no syscall numbers available in the database for ' + os_name)
		self.os_name = os_name

		process_h = WindowsProcess(pid=-1)
		shellcode_sz = align_up(len(self._syscall_stub), 1024)
		self.address = process_h.allocate(size=shellcode_sz)
		process_h.write_memory(self.address, self._syscall_stub)
		process_h.protect(self.address, size=shellcode_sz, permissions='PAGE_EXECUTE_READ')
		self._syscall = self._syscall_prototype(self.address)
Exemple #10
0
def main():
    parser = argparse.ArgumentParser(
        description='syringe: library & shellcode injection utility',
        conflict_handler='resolve',
        epilog=
        'The PID argument can be specified as -1 to inject into the context of the syringe process.'
    )
    parser.add_argument('-l',
                        '--load',
                        dest='library',
                        action='store',
                        help='load the library in the target process')
    shellcode_group = parser.add_mutually_exclusive_group()
    shellcode_group.add_argument('-i',
                                 '--inject',
                                 dest='shellcode',
                                 action='store',
                                 help='inject code into the process')
    shellcode_group.add_argument(
        '-f',
        '--inject-file',
        dest='shellcode_file',
        type=argparse.FileType('rb'),
        help='inject code from a file into the process')
    parser.add_argument('-d',
                        '--decode',
                        dest='decode',
                        action='store',
                        choices=('b64', 'hex', 'raw'),
                        default='b64',
                        help='decode the shellcode prior to execution')
    parser.add_argument('pid',
                        action='store',
                        type=int,
                        help='process to control')
    arguments = parser.parse_args()

    try:
        process_h = NativeProcess(pid=arguments.pid)
    except ProcessError as error:
        print("[-] {0}".format(error.msg))
        return
    print("[+] Opened a handle to pid: {0}".format(arguments.pid))

    if arguments.library:
        try:
            lib_h = process_h.load_library(arguments.library)
        except ProcessError as error:
            print("[-] {0}".format(error.msg))
        else:
            print("[+] Loaded {0} with handle 0x{1:08x}".format(
                arguments.library, lib_h))

    if arguments.shellcode or arguments.shellcode_file:
        if arguments.shellcode:
            shellcode = arguments.shellcode
        else:
            shellcode = arguments.shellcode_file.read()
            arguments.shellcode_file.close()
        if arguments.decode == 'b64':
            shellcode = shellcode.decode('base64')
        elif arguments.decode == 'hex':
            shellcode = shellcode.decode('hex')
        stub = ''  # no stub by default
        if architecture_is_32bit(process_h.arch):
            stub = b'\x8b\x44\x24\x04'  # mov eax,[esp+4]
        elif architecture_is_64bit(process_h.arch):
            stub = b'\x48\x8b\x44\x24\x08'  # mov rax,[rsp+8]

        shellcode_sz = align_up(len(stub + shellcode), 1024)
        address = process_h.allocate(size=shellcode_sz, address=0)
        print("[+] Allocated {0} bytes at 0x{1:08x}".format(
            shellcode_sz, address))
        process_h.protect(address, size=shellcode_sz)
        process_h.write_memory(address, stub + shellcode)
        thread_id = process_h.start_thread(address, (address + len(stub)))
        print("[+] Started thread at 0x{0:08x}".format(address))
        print("[*] Waiting for thread to complete...")
        try:
            process_h.join_thread(thread_id)
            print("[+] Thread completed")
        except ProcessError as err:
            print("[-] {0} {1}".format(err.__class__.__name__, err.msg))

    process_h.close()
Exemple #11
0
def main():
    parser = argparse.ArgumentParser(
        description='python_injector: inject python code into a process',
        conflict_handler='resolve')
    parser.add_argument('script_path',
                        action='store',
                        help='python script to inject into the process')
    parser.add_argument('procname',
                        action='store',
                        help='process to inject into')
    parser.epilog = 'The __name__ variable will be set to "__mayhem__".'
    arguments = parser.parse_args()

    if not sys.platform.startswith('win'):
        print('[-] This tool is only available on Windows')
        return

    proc_pid = getpid(arguments.procname)
    if proc_pid is None:
        print("Cant find process")
        sys.exit(1)
    else:
        print(f"PID is : {proc_pid}")
    # get a handle the the process
    try:
        process_h = WindowsProcess(pid=proc_pid)
    except ProcessError as error:
        print("[-] {0}".format(error.msg))
        return
    print("[+] Opened a handle to pid: {0}".format(proc_pid))

    # find and inject the python library
    python_lib = "python{0}{1}.dll".format(sys.version_info.major,
                                           sys.version_info.minor)
    python_lib = ctypes.util.find_library(python_lib)
    if python_lib:
        print("[*] Found Python library at: {0}".format(python_lib))
    else:
        print('[-] Failed to find the Python library')
        return

    print('[*] Injecting Python into the process...')
    try:
        python_lib_h = process_h.load_library(python_lib)
    except ProcessError as error:
        print("[-] {0}".format(error.msg))
        return
    else:
        print("[+] Loaded {0} with handle 0x{1:08x}".format(
            python_lib, python_lib_h))

    # resolve the necessary functions
    local_handle = m_k32.GetModuleHandleW(python_lib)
    py_initialize_ex = python_lib_h + (
        m_k32.GetProcAddress(local_handle, b'Py_InitializeEx') - local_handle)
    py_run_simple_string = python_lib_h + (m_k32.GetProcAddress(
        local_handle, b'PyRun_SimpleString') - local_handle)
    print('[*] Resolved addresses:')
    print("  - Py_InitializeEx:    0x{0:08x}".format(py_initialize_ex))
    print("  - PyRun_SimpleString: 0x{0:08x}".format(py_run_simple_string))

    # call remote functions to initialize and run via remote threads
    thread_h = process_h.start_thread(py_initialize_ex, 0)
    process_h.join_thread(thread_h)
    print('[*] Initialized Python in the host process')

    print("[*] Waiting for client to connect on \\\\.\\pipe\\{0}".format(
        PIPE_NAME))
    injection_stub = INJECTION_STUB_TEMPLATE
    injection_stub = injection_stub.format(path=_escape(
        os.path.abspath(arguments.script_path)),
                                           pipe_name=PIPE_NAME)
    injection_stub = injection_stub.encode('utf-8') + b'\x00'

    alloced_addr = process_h.allocate(size=utilities.align_up(
        len(injection_stub)),
                                      permissions='PAGE_READWRITE')
    process_h.write_memory(alloced_addr, injection_stub)
    thread_h = process_h.start_thread(py_run_simple_string, alloced_addr)
    client = NamedPipeClient.from_named_pipe(PIPE_NAME)
    print('[*] Client connected on named pipe')
    while True:
        message = client.read()
        if message is None:
            break
        sys.stdout.write(message.decode('utf-8'))
    client.close()
    process_h.join_thread(thread_h)
    process_h.close()
Exemple #12
0
def main():
	parser = argparse.ArgumentParser(description='python_injector: inject python code into a process', conflict_handler='resolve')
	parser.add_argument('script_path', action='store', help='python script to inject into the process')
	parser.add_argument('pid', action='store', type=int, help='process to inject into')
	parser.epilog = 'The __name__ variable will be set to "__mayhem__".'
	arguments = parser.parse_args()

	if not sys.platform.startswith('win'):
		print('[-] This tool is only available on Windows')
		return

	# get a handle the the process
	try:
		process_h = WindowsProcess(pid=arguments.pid)
	except ProcessError as error:
		print("[-] {0}".format(error.msg))
		return
	print("[+] Opened a handle to pid: {0}".format(arguments.pid))

	# find and inject the python library
	python_lib = "python{0}{1}.dll".format(sys.version_info.major, sys.version_info.minor)
	python_lib = ctypes.util.find_library(python_lib)
	if python_lib:
		print("[*] Found Python library at: {0}".format(python_lib))
	else:
		print('[-] Failed to find the Python library')
		return

	print('[*] Injecting Python into the process...')
	try:
		python_lib_h = process_h.load_library(python_lib)
	except ProcessError as error:
		print("[-] {0}".format(error.msg))
		return
	else:
		print("[+] Loaded {0} with handle 0x{1:08x}".format(python_lib, python_lib_h))

	# resolve the necessary functions
	local_handle = m_k32.GetModuleHandleW(python_lib)
	py_initialize_ex = python_lib_h + (m_k32.GetProcAddress(local_handle, b'Py_InitializeEx') - local_handle)
	py_run_simple_string = python_lib_h + (m_k32.GetProcAddress(local_handle, b'PyRun_SimpleString') - local_handle)
	print('[*] Resolved addresses:')
	print("  - Py_InitializeEx:    0x{0:08x}".format(py_initialize_ex))
	print("  - PyRun_SimpleString: 0x{0:08x}".format(py_run_simple_string))

	# call remote functions to initialize and run via remote threads
	thread_h = process_h.start_thread(py_initialize_ex, 0)
	process_h.join_thread(thread_h)
	print('[*] Initialized Python in the host process')

	print("[*] Waiting for client to connect on \\\\.\\pipe\\{0}".format(PIPE_NAME))
	injection_stub = INJECTION_STUB_TEMPLATE
	injection_stub = injection_stub.format(
		path=_escape(os.path.abspath(arguments.script_path)),
		pipe_name=PIPE_NAME
	)
	injection_stub = injection_stub.encode('utf-8') + b'\x00'

	alloced_addr = process_h.allocate(size=utilities.align_up(len(injection_stub)), permissions='PAGE_READWRITE')
	process_h.write_memory(alloced_addr, injection_stub)
	thread_h = process_h.start_thread(py_run_simple_string, alloced_addr)
	client = NamedPipeClient.from_named_pipe(PIPE_NAME)
	print('[*] Client connected on named pipe')
	while True:
		message = client.read()
		if message is None:
			break
		sys.stdout.write(message.decode('utf-8'))
	client.close()
	process_h.join_thread(thread_h)
	process_h.close()