Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support injecting into containers in linux #18

Open
kmaork opened this issue Jul 4, 2023 · 4 comments
Open

Support injecting into containers in linux #18

kmaork opened this issue Jul 4, 2023 · 4 comments
Labels
enhancement New feature or request

Comments

@kmaork
Copy link
Owner

kmaork commented Jul 4, 2023

Can check if the target process has a different /proc/<pid>/task/<pid>/ns/mnt. If it does, create the shared library in /proc/pid/root instead in the current filesystem. Python's tempfile module doesn't support searching for a tempdir in a different filesystem, and it caches it for the whole process once it's found. So maybe we can create a subprocess, nsenter the target filesystem, and then continue normally. Alternatively, just copy the logic in tempfile or assume that /tmp is writable.

@kmaork kmaork added the enhancement New feature or request label Jul 4, 2023
@cakemanny
Copy link

Hi, I think this sounds really useful.

I think there may also need to be a change to the pyinjector.inject(...) API. Currently it checks that the shared library exists before injecting.

A couple of ideas came to mind already but neither are too satisfying:

pyinjector could relativize the path when it sees that it starts with /proc/<pid>/root

pyinjector.inject(123, '/proc/123/root/path/to/lib.so')

# ->

injector.inject(b'/path/to/lib.so')

Or it could double check /proc/<pid>/root when the path is not initially found

pyinjector.inject(123, '/path/to/lib.so')

# ->

if ... and not os.path.isfile('/proc/123/root/path/to/lib.so'):
   raise ...

@kmaork
Copy link
Owner Author

kmaork commented Jul 22, 2024

Hmmm how about just always using /proc/pid/root both for the shared library tmpdir in hypno and for the existence check in pyinjector?

@cakemanny
Copy link

Ahh, you mean NamedTemporaryFile(..., dir=f'/proc/{pid}/root') instead of NamedTemporaryFile(..., dir=f'/proc/{pid}/root/tmp') ? I think it's quite common to mount / as readonly. I think it's less common to not have /tmp mounted read/write. But maybe I've misunderstood.
...

I was thinking over this some more this morning and I think I've perhaps come up with a clearer API for pyinjector

def inject(pid: int, library_path: AnyStr, uninject: bool = False,
           process_root: AnyStr = "") -> int:
           ...

which would be called, in those examples, like so

    injector.inject(b'/path/to/lib.so', process_root=b'/proc/123/root')

This has the advantage that it extends generally to any kind of chroot jail and that pyinjector doesn't have to bake in any knowledge about Linux's /proc filesystem.
The caller is responsible for making it clear at what path they expect the target process to see the library.

@kmaork
Copy link
Owner Author

kmaork commented Jul 22, 2024

In hypno I just meant that it's possible to always look for a tempdir in the target process' fs using /proc/pid/root, regardless if it's the same or not as /.

In pyinjector, I like your suggestion, but I think that it'd also be useful to always check for existence of the shared library in the target process' fs (again using /proc/pid/root) by default. The additional argument you suggested could still be used to override this default behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants