summaryrefslogtreecommitdiff
path: root/hypodermic/process.py
diff options
context:
space:
mode:
authorjakob <jakob@memeware.net>2017-10-22 15:01:36 -0400
committerjakob <jakob@memeware.net>2017-10-22 15:01:36 -0400
commitebe7dd1682f79edae434b3440516f694b43bee79 (patch)
tree361e9e1b0ad67f47dc46ace4b2a5eb41bf5341f8 /hypodermic/process.py
parent33542bda8ee6d0a75c89522daf1c20d580894a01 (diff)
Initial calling to internal _dl_openHEADmaster
Diffstat (limited to 'hypodermic/process.py')
-rw-r--r--hypodermic/process.py85
1 files changed, 55 insertions, 30 deletions
diff --git a/hypodermic/process.py b/hypodermic/process.py
index 35b8c1d..4740062 100644
--- a/hypodermic/process.py
+++ b/hypodermic/process.py
@@ -456,20 +456,71 @@ class Process(object):
if not self.rtld:
raise OSError("Process does not have a usable RTLD")
+ self.path_caller_check()
if self.arch == "x64":
+ ret = self.get_register("rip")
old_rax = self.get_register("rax")
- self.run_code(dlopen_shellcode(self.rtld_dl_open_addr, path),
- preserve=["rax"])
+ shellcode = dlopen_shellcode(self.rtld_dlsym("_dl_open"), ret, path)
+ self.run_code(shellcode, preserve=["rax"])
addr = self.get_register("rax")
self.set_register("rax", old_rax)
else:
+ ret = self.get_register("eip")
old_eax = self.get_register("eax")
- self.run_code(dlopen_shellcode(self.rtld_dl_open_addr, path,
- arch="i386"), preserve=["eax"])
+ shellcode = dlopen_shellcode(self.rtld_dlsym("_dl_open"), ret, path,
+ arch="i386")
+ self.run_code(shellcode, preserve=["eax"])
addr = self.get_register("eax")
self.set_register("eax", old_eax)
return addr
+ def patch_caller_check(self):
+ """Patches out a caller check security measure in the RTLD.
+
+ Note:
+ This is requried before making any invocations to `dlopen`.
+
+ Raises:
+ OSError: If the process either has no RTLD, or the caller
+ check cannot be found.
+ """
+ if not self.rtld:
+ raise OSError("Process does not have a usable RTLD")
+
+ if self.arch == "x64":
+ caller_check = self.rtld_dlsym("_dl_check_caller")
+ shellcode = assemble("movq $0x00, %rax; ret;")
+ self.write_bytes(caller_check, shellcode)
+ else:
+ caller_check = self.rtld_dlsym("_dl_check_caller")
+ shellcode = assemble("movl $0x00, %eax; ret;")
+ self.write_bytes(caller_check, shellcode)
+
+ def rtld_dlsym(self, sym: str) -> int:
+ """Obtain the absolute address of an RTLD symbol in main memory.
+
+ Raises:
+ OSError: If either the process has no instance of the RTLD,
+ or the RTLD lacks sufficient symbols.
+
+ Returns:
+ An integer containing the address.
+ """
+ if self.rtld is None:
+ raise OSError("Process has no RTLD instance")
+
+ with open(self.rtld.path, "rb") as rtld:
+ elf = ELFFile(rtld)
+ symtab = elf.get_section_by_name(".symtab")
+
+ if not isinstance(symtab, SymbolTableSection):
+ raise OSError("RTLD has no usable symbol table")
+
+ res = symtab.get_symbol_by_name(sym)
+ if len(res) < 1:
+ raise OSError("RTLD has no {} symbol".format(sym))
+ return self.rtld.start + res[0].entry.st_value
+
def page_start(self, addr: int) -> int:
return addr & ~(self.page_size - 1)
@@ -501,32 +552,6 @@ class Process(object):
return "x64" if self._isamd64 else "x86"
@property
- def rtld_dl_open_addr(self) -> int:
- """Obtain the absolute address of _dl_open in main memory.
-
- Raises:
- OSError: If either the process has no instance of the RTLD,
- or the RTLD lacks sufficient symbols.
-
- Returns:
- An integer containing the address.
- """
- if self.rtld is None:
- raise OSError("Process has no RTLD instance")
-
- with open(self.rtld.path, "rb") as rtld:
- elf = ELFFile(rtld)
- symtab = elf.get_section_by_name(".symtab")
-
- if not isinstance(symtab, SymbolTableSection):
- raise OSError("RTLD has no usable symbol table")
-
- res = symtab.get_symbol_by_name("_dl_open")
- if len(res) < 1:
- raise OSError("RTLD has no _dl_open symbol")
- return self.rtld.start + res[0].entry.st_value
-
- @property
def maps(self) -> list:
"""Obtain the process' memory map.