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

hamayanhamayan's blog

CTFのWebセキュリティにおけるXSSまとめ(PRSSI, XFS, CSS Injection)

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

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

クロスサイトスクリプティングXSS

  • 名前は歴史的なものらしいので、意味はあまり気にしなくていいと思ってる。正直どこからどこまでをXSSと呼ぶべきか微妙な風に思っているが、とりあえずHTMLコードとかjsコードを埋め込むことができればXSS
  • 攻撃シナリオ
    • CTFではCookieを奪取するシナリオを想定する場合が多い。なので、特に何も情報がなければCookieの抜き出しをXSSで行えばいい
    • セッションハイジャックは一例であり、キーロガーや画面の改ざん、一時期流行ったマイニングといった様々なことが行える
  • 攻撃の種類
  • ソースとシンク
    • ソース:ユーザーから情報を受け取る元
      • formなどのユーザー入力部分
      • httpリクエストヘッダーの中身
      • cookie/LocalStorage
      • URL
      • 間接的にはDB, アップロードファイル
    • シンク:ユーザーから受け取った情報を表示する先
      • 色々あるが、XSSと呼ばれるのはシンクが「画面出力、HTML,CSS,JavaScript」を指す場合である
      • サーバでのコマンド実行ならコマンドインジェクションだし、メール/httpレスポンスヘッダーの中身ならヘッダーインジェクションだし
    • 挿入物

ペイロード

DOM-based XSS

Vue

  • Vue.jsにXSSが入るパターン
    • v-bind
      • v-bind:href
      • v-bind:onmouseover
      • v-bind:onfocus
      • v-bind:onblur
      • v-bind:onerror
    • SSR(Mustache)
      • userにMustanche構文を直接使わせない {{ alert(1) }}のようにMustache構文内部ではjsが直接かける
      • {{ constructor.constructor("alert('css')")() }}というテクもある
    • domProps
    • compile
  • 危険な形
    • new Vue({el:'#app', template: '<div>' + [userinput] + '</div>'})
    • <div v-html="[userinput]"></div>
    • h('div', { domProps: { innerHTML: [userinput] } }) 描画関数を利用する場合
    • <div domPropsInnterHTML=[userinput]></div> JSXによる描画関数を利用する場合
  • 安全な形
    • {{ [userinput] }} Mustache構文という
    • <h1 v-bind:title="[userinput]"></h1>
  • セキュリティドキュメントに明記されてたこと
    • v-bind:hrefjavascript:~については無力なので自力で何とかして
    • フロントエンドとサーバサイドのテンプレートが混在しているとXSSが発動する場面がある
    • Vue.compile()やVue.component(), componentsなどを使ってHTMLを動的に生成するような場合、userの入力値から任意のHTMLタグ、属性、JavaScriptコードが入り込まないようにする
  • スクリプトガジェット
    • とある機能によって無害なHTMLタグや属性を実行可能なJSに変換してしまうようなもの
    • 2017年blackhatの資料によると、人気Webフレームワークの殆どにスクリプトガジェットが存在していたとのこと
      • <div data-bind="value: alert(1)"></div>
      • <img src=x @error="$event.target.ownerDocument.defaultView.alert(1)">
      • <p>{{this.$el.ownerDocument.defaultView.alert(1)}}</p>
        • v-show, v-if, v-for, v-bindでも同様のことが可能

Self XSS

  • これはソーシャルエンジニアリングの1種と認識されてるみたい
  • ユーザーの人力で悪意あるコードが入力されるとXSSが発動する(外部からの入力は防がれている)
    • XSSして、ユーザーがボタンを押して発動するものもSelf XSSと認識されるみたい(ほんと?)
  • 攻撃ケース(大体これだろう)
      1. 投稿用コードがコピーできるボタンを利用者がクリック
      1. 実際には悪意あるコードにすり替えられている
      1. 利用者がそのコードをあまり確認せずに入力して投稿するとSelf-XSS発動
    • 他にもこのコードを投稿したら応募完了みたいな懸賞広告を装うとかね
  • 記事
    • writeups/bug.md at main · asurti6783/writeups · GitHub
      • よくわからないが、X-FRAME-OPTIONSがバイパスできるっぽい
      • 正当な画面を出したすぐあとに異常な画面を出す
        • 1回目の画面を2回目に持ち越すことができるみたい
        • 2回目の画面では異常入力なので送信が押せなくなっているが、画面持ち越しのおかげで送信が押せる
      • ドメイン/#/pathとURLがなっているのでvue.jsっぽいが、この#が原因でこういうことが起きているのかも

CSS Injection

PRSSI

  • 発生個所
    • NG: <link href="../all.css">
    • OK: <link href="/css/all.css">
    • OK: <link href="https://example.com/css/all.css">
  • 発生原因
    • 古いIEはtext/htmlであってもContent Sniffingcssと判定してしまう
      • CSSを外部から注入するテク。Quirks modeという後方互換の描画モードじゃないと発生しない
      • CSSは古いIEだとexpressionというものを使ってjsコードが動かせたり、コンテンツスニッフィングできるから危ない
    • https://example.com/index.phphttps://example.com/index.php/aaa/bbb/ccc/と書いても呼び出せる
      • だが、この状態で相対パス../index.cssを解決しようとするとhttps://example.com/index.php/aaa/bbb/index.cssとなるが、結局、index.phpを見に行くので、自分をもう一度参照することとなる
        • ここで入力がそのまま画面に反映されるようなことがあると、二回目の参照に対して任意の文字列をinjectionでき(主にCSS)、それをCSSとして受け取るため、任意のCSSを実行可能になってしまう
  • 解決方法
    • X-Frame-Options: deny
      • headに<meta http-equiv="X-UA-Compatible"content="IE=EmulateIE7">を入れて、iframeに目的のサイトを入れると、目的のサイトにQuirks modeを強制できる。その抑止
    • モダンなdoctypeをつける<!doctype html>これでquirks modeというのを抑制することでも解決する
    • X-Content-Type-Options: nosniff

XFS (Cross-Frame Scripting)

テク一覧

よくわかってない話