Tests injecting python in remote process now check that target python is installed

This commit is contained in:
hakril
2018-03-28 23:14:41 +02:00
parent 9e1400e4ad
commit e918d735a1
8 changed files with 59 additions and 21 deletions
+8 -1
View File
@@ -1,6 +1,13 @@
TODO:
=== CRITICAL BEFORE 0.4 ===
=== CRITICAL BEFORE 0.5 ===
- Add news features to index.html
- Document / fix / release:
- windows.bits
- evtlog
- kernobj
- window
======
-1
View File
@@ -60,7 +60,6 @@ else:
class HandleDebugger(object):
def __init__(self, pid):
self.pid = pid
+32 -2
View File
@@ -1,6 +1,7 @@
import os.path
import pytest
import windows
import windows
import windows.generated_def as gdef
is_process_32_bits = windows.current_process.bitness == 32
@@ -24,4 +25,33 @@ check_for_gc_garbage = pytest.mark.usefixtures("check_for_gc_garbage")
check_for_handle_leak = pytest.mark.usefixtures("check_for_handle_leak")
test_binary_name = "notepad.exe"
DEFAULT_CREATION_FLAGS = gdef.CREATE_NEW_CONSOLE
DEFAULT_CREATION_FLAGS = gdef.CREATE_NEW_CONSOLE
# Python Injection check fixture
python_is_installed = {
windows.current_process.bitness: True
}
if windows.current_process.bitness == 32:
with windows.utils.DisableWow64FsRedirection():
python_is_installed[64] = os.path.exists(r"C:\Windows\system32\python27.dll")
if windows.current_process.bitness == 64:
python_is_installed[32] = os.path.exists(r"C:\Windows\SysWOW64\python27.dll")
@pytest.fixture
def check_injected_python_installed(request):
# Find the process parameter
procparams = [argname for argname in request.funcargnames if argname.startswith("proc")]
if len(procparams) != 1:
raise ValueError("Could not find the fixture name of the injected python")
procparam = procparams[0]
proc = request.getfuncargvalue(procparam)
if not python_is_installed[proc.bitness]:
pytest.skip("Python {0}b not installed -> skipping test with python injection into {0}b process".format(proc.bitness))
return None
python_injection = pytest.mark.usefixtures("check_injected_python_installed")
+3
View File
@@ -353,6 +353,8 @@ def test_memory_breakpoint_exec(proc32_64_debug):
# breakpoint remove
import threading
@python_injection
@pytest.mark.parametrize("bptype", [windows.debug.FunctionParamDumpHXBP, windows.debug.FunctionParamDumpBP])
def test_standard_breakpoint_self_remove(proc32_64_debug, bptype):
data = []
@@ -379,6 +381,7 @@ def test_standard_breakpoint_self_remove(proc32_64_debug, bptype):
d.loop()
assert data == [u"FILENAME1", u"FILENAME2"]
@python_injection
@pytest.mark.parametrize("bptype", [windows.debug.FunctionParamDumpHXBP, windows.debug.FunctionParamDumpBP])
def test_standard_breakpoint_remove(proc32_64_debug, bptype):
data = []
+1
View File
@@ -80,6 +80,7 @@ def test_self_iat_hook_multithread():
assert len(calling_thread) == 2
x.disable()
@python_injection
@check_for_gc_garbage
def test_remote_iat_hook(proc32_64):
proc32_64.execute_python("import windows")
+6 -1
View File
@@ -10,6 +10,8 @@ import windows
windows.pipe.send_object("{pipe}", {{'Hello': 2}})
"""
@python_injection
def test_ipc_pipe(proc32_64):
with windows.pipe.create(PIPE_NAME) as np:
proc32_64.execute_python(rcode_test_ipc_pipe.format(pipe=PIPE_NAME))
@@ -20,13 +22,14 @@ def test_ipc_pipe(proc32_64):
rcode_test_echo_pipe = """
import windows
with windows.pipe.create("{pipe}") as np:
np.wait_connection()
obj = np.recv()
np.send(obj)
"""
@python_injection
def test_pipe_echo_server(proc32_64):
t = proc32_64.execute_python_unsafe(rcode_test_echo_pipe.format(pipe=PIPE_NAME))
time.sleep(0.5)
@@ -37,6 +40,8 @@ def test_pipe_echo_server(proc32_64):
echoobj = pipe.recv()
assert obj == echoobj
@python_injection
def test_pipe_recv_object(proc32_64):
# not the good way to do the exchange (race possible)
# Just for the sake of the test
+8 -15
View File
@@ -71,6 +71,10 @@ class TestCurrentProcessWithCheckGarbage(object):
image_path_from_module = windows.current_process.peb.modules[0].fullname.lower()
assert image_path_from_process_params == image_path_from_module
@check_for_gc_garbage
class TestProcessWithCheckGarbage(object):
def test_pop_proc_32(self, proc32):
@@ -127,7 +131,6 @@ class TestProcessWithCheckGarbage(object):
assert proc32_64.read_wstring(addr) == test_string
# Test native execution
def test_execute_to_proc32(self, proc32):
with proc32.allocated_memory(0x1000) as addr:
shellcode = x86.MultipleInstr()
@@ -151,26 +154,16 @@ class TestProcessWithCheckGarbage(object):
qword = proc64.read_qword(addr)
assert qword == 0x4242424243434343
# Python execution
def _skip_if_injection_dll_not_found(self, target):
if windows.current_process.bitness == target.bitness:
return # Should never fail if we have the same bitness
try:
windows.injection.validate_python_dll_presence_on_disk(target)
except IOError as e:
pytest.skip("Python DLL to inject not installed")
@python_injection
def test_execute_python(self, proc32_64):
self._skip_if_injection_dll_not_found(proc32_64)
with proc32_64.allocated_memory(0x1000) as addr:
proc32_64.execute_python('import ctypes; ctypes.c_uint.from_address({0}).value = 0x42424242'.format(addr))
dword = proc32_64.read_dword(addr)
assert dword == 0x42424242
@python_injection
def test_execute_python_suspended(self, proc32_64_suspended):
self._skip_if_injection_dll_not_found(proc32_64_suspended)
proc = proc32_64_suspended
with proc.allocated_memory(0x1000) as addr:
proc.execute_python('import ctypes; ctypes.c_uint.from_address({0}).value = 0x42424242'.format(addr))
@@ -193,7 +186,7 @@ class TestProcessWithCheckGarbage(object):
import time; time.sleep(0.1)
assert proc32_64.peb.modules[0].name == test_binary_name
@python_injection
def test_parse_remote_pe(self, proc32_64):
# Wait for PEB initialization
# Yeah a don't know but on 32bits system the parsing might begin before
@@ -228,8 +221,8 @@ class TestProcessWithCheckGarbage(object):
assert exe.baseaddr == exe_by_module.baseaddr
assert exe.bitness == exe_by_module.bitness
@python_injection
def test_execute_python_raises(self, proc32_64):
self._skip_if_injection_dll_not_found(proc32_64)
res = proc32_64.execute_python("import time;time.sleep(0.1); 2")
assert res == True
with pytest.raises(windows.injection.RemotePythonError) as ar:
+1 -1
View File
@@ -27,7 +27,7 @@ class TestSyswowCurrentProcess(object):
wow64 = [m for m in peb64.modules if m.name == "wow64.dll"][0]
assert "Wow64LdrpInitialize" in wow64.pe.exports
@python_injection
@windows_64bit_only
class TestSyswowRemoteProcess(object):
def test_remote_pebsyswow(self, proc32):