Two Sides of a Coin
oioki
Bulletin Board where you can buy or sell cool stuff. Check it out:
https://two-sides-of-a-coin.pwn.institute
まずはエンドポイントを試す
/
色々出てくる/add
-> Sorry, new advertisements are temporarily not allowed.- ですよねー
- READONLYはtrueのようだ
/view/bctf0eua8o7nl8uv9bpn6yho41p52wel
普通に表示される
んー、これ環境変数書き換えないとダメじゃないか?
Writeup
CTFtime.org / BalCCon2k20 CTF / Two Sides of a Coin / Writeup
ソースコードをよく読みましょう。
ID推測
/view/<_id>
のエンドポイントを見る。
SELECT id_viewer, id_editor, posted_at, title, text_viewer, text_editor FROM board WHERE id_viewer = ? OR id_editor = ? LIMIT 1'
というSQL文になっていて、?にはどちらも指定のIDが入る。
id_editor側でヒットさせることができれば、追加情報が手に入る。
サイト側で使われているのは、id_viewerの方である。
id_viewerからid_editorを推測することはできないだろうか。
/add
のエンドポイントを見ると、使うことはできないが、idの作成方法が書いてある。
def get_random_id(): alphabet = list(string.ascii_lowercase + string.digits) return ''.join([random.choice(alphabet) for _ in range(32)]) ... posted_at = round(time.time(), 4) random.seed(posted_at) id_viewer = get_random_id() id_editor = get_random_id()
見ると時間をシードとして、IDを取得している。
時間は取得できるので、コードを参考にしてIDを復元してみよう。
time.timeはエポック秒を小数で返す。roundで小数点4位までにして、シードに使っている。
エポック秒については、
Will code for food If you're interested, drop me a message. Posted at 2020-09-22 21:09 UTC
というところから、秒を0-59で全探索すれば見つかる。
小数点部分についても全探索をして、指定の時間を見つけていこう。
例えば、2020-09-22 21:09:00
は1600808940
であり、00.0000-59.9999の間を全探索しよう。
すると見つかる。
フラグはWill code for food
の記事にあるので、以下スクリプトでid_editorを見つけ出して、GETしよう。
/view/k6wfi4zwhdcwqtqgay57djxpcv9gb7fk
とするとフラグが得られる。
BCTF{numb3rs_from_PRNG_are_n0t_really_rand0m}
import string import random from tqdm import tqdm def get_random_id(): alphabet = list(string.ascii_lowercase + string.digits) return ''.join([random.choice(alphabet) for _ in range(32)]) ans = 'cfddcxulrhohtilq03qke9v0iqwddmvz' epo = 1600808940 * 10000 for i in tqdm(range(1011010)): random.seed((epo + i) / 10000) id_viewer = get_random_id() id_editor = get_random_id() if id_viewer == ans: tqdm.write(f'find! {id_editor}') exit(0)