GithubHelp home page GithubHelp logo

davidbuchanan314 / dlinject Goto Github PK

View Code? Open in Web Editor NEW
759.0 24.0 76.0 47 KB

Inject a shared library (i.e. arbitrary code) into a live linux process, without ptrace

License: MIT License

Python 100.00%
shellcode ld-preload python3 assembly x86-64 linux procfs shellcode-injection ptrace

dlinject's Introduction

dlinject.py

Inject a shared library (i.e. arbitrary code) into a live linux process, without ptrace. Inspired by Cexigua and linux-inject, among other things.

asciicast

Usage

    .___.__  .__            __               __
  __| _/|  | |__| ____     |__| ____   _____/  |_  ______ ___.__.
 / __ | |  | |  |/    \    |  |/ __ \_/ ___\   __\ \____ <   |  |
/ /_/ | |  |_|  |   |  \   |  \  ___/\  \___|  |   |  |_> >___  |
\____ | |____/__|___|  /\__|  |\___  >\___  >__| /\|   __// ____|
     \/              \/\______|    \/     \/     \/|__|   \/

source: https://github.com/DavidBuchanan314/dlinject

usage: dlinject.py [-h] [--stopmethod {sigstop,cgroup_freeze,none}]
                   pid /path/to/lib.so

Inject a shared library into a live process.

positional arguments:
  pid                   The pid of the target process
  /path/to/lib.so       Path of the shared library to load (note: must be
                        relative to the target process's cwd, or absolute)

optional arguments:
  -h, --help            show this help message and exit
  --stopmethod {sigstop,cgroup_freeze,none}
                        How to stop the target process prior to shellcode
                        injection. SIGSTOP (default) can have side-effects.
                        cgroup freeze requires root. 'none' is likely to cause
                        race conditions.

Why?

  • Because I can.

  • There are various anti-ptrace techniques, which this evades by simply not using ptrace.

  • I don't like ptrace.

  • Using LD_PRELOAD can sometimes be fiddly or impossible, if the process you want to inject into is spawned by another process with a clean environment.

How it Works

  • Send the stop signal to the target process. (optional)

  • Locate the _dl_open() symbol.

  • Retreive RIP and RSP via /proc/[pid]/syscall.

  • Make a backup of part of the stack, and the code we're about to overwrite with our shellcode, by reading from /proc/[pid]/mem.

  • Generate primary and secondary shellcode buffers.

  • Insert primary shellcode at RIP, by writing to /proc/[pid]/mem.

  • The primary shellcode:

    • Pushes common registers to the stack.
    • Loads the secondary shellcode via mmap().
    • Jumps to the secondary shellcode.
  • The secondary shellcode:

    • Restores the stack and program code to their original states.
    • Pivots the stack (so we don't touch the original one at all).
    • Calls _dl_open() to load the user-specified library. Any constructors will be executed on load, as usual.
    • Restores register state, un-pivots the stack, and jumps back to where it was at the time of the original SIGSTOP.

Limitations:

  • Sending SIGSTOP may cause unwanted side-effects, for example if another thread is waiting on waitpid(). The --stopmethod=cgroup_freeze option avoids this, but requires root (on most distros, at least).

  • I'm not entirely sure how this will interact with complex multi-threaded applications. There's certainly potential for breakage.

  • x86-64 Linux only (for now - 32-bit support could potentially be added).

  • Requires root, or relaxed YAMA configuration (echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope is useful when testing).

  • If the target process is sandboxed (e.g. seccomp filters), it might not have permission to mmap() the second stage shellcode, or to dlopen() the library.

dlinject's People

Contributors

cclauss avatar davidbuchanan314 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dlinject's Issues

Can't remove cgroup freeze directory

https://github.com/DavidBuchanan314/dlinject/blob/master/dlinject.py#L256

Traceback (most recent call last):
  File "./dlinject.py", line 283, in <module>
    dlinject(args.pid, args.lib_path, args.stopmethod or "sigstop")
  File "./dlinject.py", line 258, in dlinject
    os.rmdir(freeze_dir)
OSError: [Errno 16] Device or resource busy: '/sys/fs/cgroup/freezer/dlinject_19dc059e2ea46b80'

I believe this fails because the /tasks file still has a running process in. I guess I need to figure out how to remove tasks.

EPERM when deleting the stage2 file when launched with sudo

For obvious reasons, the stage2*.bin file will be created as root when launching the script with sudo. In this case, the shellcode (that will run as non privileged user) won't be able to delete the stage2*.bin file (EPERM).

I guess that the file should be chowned so the owner becomes the non-root user.

A quick fix is adding this snippet as soon as the file is created.

if os.getuid() == 0:
    uid = int(os.environ.get("SUDO_UID"))
    guid = int(os.environ.get("SUDO_GID"))
    os.chown(stage2_path, uid, guid)

error while loading shared libraries: dlopen: invalid caller

hey
I tested this code and got this error.

error while loading shared libraries: dlopen: invalid caller

My environment:
centos7 64bit + ld-2.17.so + glibc-2.17-260.el7_6.6.x86_64 + kernel 3.10.0-957.27.2.el7.x86_64
image

image

I think this error comes from __check_caller in glibc

What should I do so that I can successfully test, or the experimental environment of the person who successfully tested. thinks

Question: reading ELF image from disk vs memory

Hi,

First of all, thanks for putting this example together and documenting it.

I've been fooling around with injecting code on my own and in my experiments I've faced an issue that I can't seem to explain yet. What I found interesting is that you've chosen a different approach and I'm wondering if you could elaborate on why. Here goes.

In this project after reading the memory map, you're reading the actual shared library from disk. In my code I'm trying to read the library from the processes' memory by reading corresponding regions. However, what I'm seeing is that the resulting ELF image is corrupted (the headers section offset points past EOF). I'm wondering if you saw something similar and chose to fix/work around by reading from disk. If so, were you able to find an explanation as to why this was happening?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.