From ea82e4f3f9187fe90c9f9d8c3c3eb6de59d0a63c Mon Sep 17 00:00:00 2001 From: jakob Date: Wed, 30 Aug 2017 21:36:20 -0400 Subject: Improved interface for getting a process RTLD --- README.md | 5 ++++- hypodermic/main.py | 5 +++++ hypodermic/ptrace.py | 26 ++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7b42eca..ceee2bc 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,8 @@ memory is far more complicated than calling mmap(2) on the file. The second iteration also involves injecting code into the inferior process, but instead maps the Linux runtime linker into memory to make use of its existing -GOT/PLT setup functionality. +GOT/PLT setup functionality. This involves injecting auxiliary vectors onto the +stack in an attempt to trick the RTLD. ## Important Resources @@ -40,6 +41,7 @@ GOT/PLT setup functionality. * [Runtime Process Infection][5] * [ELF Program Header][6] * [Dynamic Loader Operation][7] +* [About ELF Auxiliary Vectors][8] [1]: https://github.com/gaffe23/linux-inject @@ -49,3 +51,4 @@ GOT/PLT setup functionality. [5]: http://phrack.org/issues/59/8.html [6]: http://www.sco.com/developers/gabi/latest/ch5.pheader.html [7]: https://sourceware.org/glibc/wiki/DynamicLoader +[8]: http://articles.manugarg.com/aboutelfauxiliaryvectors diff --git a/hypodermic/main.py b/hypodermic/main.py index 0f77de5..635e3a7 100644 --- a/hypodermic/main.py +++ b/hypodermic/main.py @@ -55,8 +55,13 @@ def main(): usage="%(prog)s [-a pid] [-c path] [options]", description="Don't share needles, brah!" ) + parser._positionals.title = "Positional Arguments" parser._optionals.title = "Optional Arguments" + parser.add_argument( + "target", + help="The target shared object to inject." + ) parser.add_argument( "-q", "--quiet", diff --git a/hypodermic/ptrace.py b/hypodermic/ptrace.py index c77fb8e..714b567 100644 --- a/hypodermic/ptrace.py +++ b/hypodermic/ptrace.py @@ -19,8 +19,9 @@ import ctypes import os.path +import re -from hypodermic.memory import maps +from hypodermic.memory import Region, maps class Process(object): @@ -103,5 +104,26 @@ class Process(object): raise OSError("Could not continue") @property - def maps(self): + def maps(self) -> list: + """Obtain the process' memory map. + + Returns: + A list of Region objects. + """ return maps(self.pid) + + # FIXME: This approach does not work outside of seeing if the + # process has an RTLD page. The reality is that the RTLD is + # broken up into independent several pages. + @property + def rtld(self) -> Region: + """Obtain the region of memory for the process' RTLD, if it + exists. + + Returns: + The Region object belonging to the RTLD, or None if no + RTLD was found. + """ + for region in self.maps: + if re.search(r"ld.+\.so", region.path): + return region -- cgit v1.3