Index

5/3 Small N

RSA の q だけが getPrime(32) で生成されている。n = p * q に 32-bit の小さい素因数が混ざるため、n はそのまま分解できる。

> sage -c "print(factor(28576441902831457590427748668696557474043630372677632241672926869035931925834848020457746529998588578832822195110996090327253913633985879817257290686867076047319213))"
2563568311 * 11147134944761554899103193302305006326021647555260965402717106245676295507085025759806151126198169243492736478560331248503739955004454679349973167415575483

分解後は通常の RSA 復号でよい。phi = (p - 1) * (q - 1) を計算し、d = e^{-1} mod phi から c^d mod n を戻す。

5/4 secret-table-2

/loginusernamepassword を直接 SQL に埋め込んでいるのでSQLiを考える。 返却に user[0] が表示されるため、UNION-based SQLi で1列目に見たい値を置けば結果を画面に出せる。

欲しいtable/column 名は固定ではないが、SQLite では sqlite_schema から schema を取得できる。まず secret_%CREATE TABLE 文を読んで table/column 名を特定し、その名前を使って中身を取り出す。

' UNION SELECT sql, name FROM sqlite_schema WHERE name LIKE 'secret_%'--
' UNION SELECT {column_name}, '' FROM {table_name}--

5/5 do the math

chall.sh は入力を [[ "$GUESS" -eq "$SECRET" ]] で比較している。 当てたところでflagは得られないのでコマンド実行できないか考える。

Bash の -eq は実際には両辺を評価する。配列添字などを使うことでコマンドを実行でき、socat の設定により stderr 側の出力も接続へ返ってくることを利用する。

a[$(cat /flag.txt >&2)]

5/6 func-array

vuln() は stack 上の alpaca_functions[3] を、入力した choice で境界チェックなしに呼び出す。choice は正方向の OOB で saved RBP や saved return address 側を関数ポインタとして読める。遠くないはずなので適当に5 を選ぶとそのまま win() に流れシェルが取れた。

5/7 permission denied 3

chal.sh は root で flag.txt を作った後、すぐに rm *chal.shflag.txt を削除してから shell を起動する。ファイル名としては消えているため、普通に cat flag.txt しても読めない。

ただし bash chal.sh の親プロセスは、実行中の script を fd 255 として開いたまま残している。/proc/$PPID/fd/255 を読むと、unlink 済みのフラグの書かれた chal.sh 本体を参照できる。

5/8 Vending Machine