【Writeup】SECCON Beginners CTF 2024
投稿日: 更新日:
結果
スコアは219pt、399/962位でした!
Welcome
Discordにフラグがあるのでそれを入れる。
ctf4b{Welcome_to_SECCON_Beginners_CTF_2024}
crypto
Safe Prime
ソースコードが与えられたので読むと以下の部分がある。
while True:
p = getPrime(512)
q = 2 * p + 1
if isPrime(q):
break
素数にはという関係がある。
なので以下のように式変形すると2次方程式を解くことになる。
よって二分探索で答えを求める。
from Crypto.Util.number import long_to_bytes
n =
c =
e = 65537
ok = 0
ng = n
while ng - ok > 1:
mid = (ok+ng)//2
if 2*mid*mid + mid <= n:
ok = mid
else:
ng = mid
p = ok
q = n // p
phi = (p-1) * (q-1)
d = pow(e, -1, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
ctf4b{R3l4ted_pr1m3s_4re_vuLner4ble_n0_maTt3r_h0W_l4rGe_p_1s}
pwnable
simpleoverflow
ソースコードをみると、バッファーよりも大きな量を読み取ろうとしていることが分かる。
char buf[10] = {0};
int is_admin = 0;
printf("name:");
read(0, buf, 0x10);
なので適当に~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
など入れてis_admin
の領域を上書きする。
ctf4b{0n_y0ur_m4rk}
misc
getRank
できるだけ大きな値をサーバーに送ればよいようだ。
与えられたコードを読むと、以下の部分で送られてきた文字列を数値に変換している。目標はranking関数に10^255よりも大きな値を入れることである。そのまま10進数で大きな値を入れても文字数制限ではじかれてしまう。
parseIntは最初に0xとつければ16進数として解釈してくれる。そのためFを出来る限り並べた文字列を送る。そうすると、parseIntの結果がInfinityとなり10で100回割られる部分の処理も無力化することができる。
function chall(input: string): Res {
if (input.length > 300) {
return {
rank: -1,
message: "Input too long",
};
}
let score = parseInt(input);
if (isNaN(score)) {
return {
rank: -1,
message: "Invalid score",
};
}
if (score > 10 ** 255) {
// hmm...your score is too big?
// you need a handicap!
for (let i = 0; i < 100; i++) {
score = Math.floor(score / 10);
}
}
return ranking(score);
}
以下のコードを書いた。
import requests
url = 'https://getrank.beginners.seccon.games/'
s = "0x" + ("F" * 298)
resu = requests.post(url, json = { 'input': s }, )
print(resu.text)
ctf4b{15_my_5c0r3_700000_b1g?}