参加した。400ptで16位。writeupを書いていく。
CRYPT
Simple Substitution Cipher [10pt]
ROT13するだけ。CyberChef先生にお任せ。
Substitution Cipher [20pt]
ヴィジュネル暗号。これもCyberChef先生がやってくれる。鍵が4文字中2文字隠れているので、flagあたりを見ながら総当たりで解ける。一文字アクセント記号付きの文字が入っていてこれを除去しないとうまくいかなかった。
Administrator Hash (NTLM hash) [20pt]
lsassのダンプが出てくるのでpypykatzにかけると出てくる。
Administrator Password [20pt]
前の問題のNTLMハッシュをCrackStationに投げたら出てきた。
Hash Extension Attack [30pt]
今回唯一?の悪問。ハッシュ伸長攻撃をする想定なんだろうけど、salt単体のハッシュ値からsaltそのものがわかってしまう。なのでハッシュ伸長攻撃をするまでもなく条件を満たすhashとpayloadは出せる(というか無限にパターンがある)が、一番シンプルなのを入れても駄目だった。結局解けずじまい。
想定解はhash_extenderを使うらしいが、それだとフラグを構成するはずの$payload
にNUL文字とかが含まれるんだが…($payload
はURLデコード後のデータのため)
FORENSICS
ここは全部解けた。
The Place of The First Secret Meeting [10pt]
画像ファイルをGoogle Lens(イメージ検索)に食わせると高松城の艮櫓(うしとらやぐら)と出てくる。
The Deleted Confidential File [20pt]
問題画面の順番と違うけど(多分こちらの方が点数が高いせい)先にこちらを解く想定のようなので先に書く。
ディスクイメージのゴミ箱にzipファイルがあるのでその中身を見るとファイル名にフラグが書いてある。
They Cannot Be Too Careful [10pt]
zip2johnでハッシュ作成してhashcatに食わせると答えが出てくる。txtのハッシュだけでOK。
Their Perpetration [20pt]
USBデバイスの情報はレジストリに…と思ったらレジストリファイルがディスクイメージになかった。イベントログはあるのでMicrosoft-Windows-Partition%4Diagnostic.evtx
を見るとデバイスの接続記録が残っている。USBデバイスのうち保全に使ったと言われてるもの以外のシリアルナンバーを答えればいい。
The Taken Out Secrets [30pt]
zipファイルからPDFを取り出して見てみると、フラグの一部がある。選択してコピペで取得するか、pdf2txtで抽出できる。フラグは3つに分かれていて、これはその一番目。
次はPDFの構造を見る。私はiText RUPSを使った。Base64デコードするとフラグの欠片の2つ目になる。
PDF内の画像を抽出して保存する。RUPSでもできるしpdfextractを使ってもいい。抽出したファイルをAperi’Solveにかけると余白に隠れた文字が見えるものがある。これがフラグの欠片の3つ目。全部繋げるとフラグになる。
NW
Transfer [10pt]
問題名からAXFRだろうと思ってやるもフラグは出てこない。詐欺だ。bindのバージョンを調べると出てくる。
Analysis [20pt]
プロキシログを10.200.200.15
でgrepしてGoogleとかYahooとかその他有名どころを除去していくと怪しいのが残る。右端の方の値が接続先IPアドレス。最初flag{}
の形式にしなきゃいけないことを見落としていてなんで違うんだろうと首をひねっていた。
Enumeration [20pt]
Postfixということで25番ポートをスキャンしてもバージョン番号は出てこない。
UDPの161番(SNMP)が開いていてそちらをnmap scriptでスキャンするなりsnmpwalkするなりするとインストールされているパッケージ一覧が出てきてPostfixのバージョンがわかる。
Ladder [30pt]
解けなかった。80番ポートは開いていてログイン画面っぽくなっているもののどことも通信せずに何を入れても「ログイン失敗」と出る罠ページ。3306番ポートも開いていたが自分のIPアドレスからのアクセスはブロックされていた。他には3128番ポートが開いていて、プロキシかと思いきや接続してみたらMySQLだった。多分ここが突入口だと思っていろいろ調べる。nmap script使ってスキャンしたら有効そうなアカウント名が出てきたけれどBrute forceしきる前に時間切れ。アカウントの存在わかってたのにBrute forceしてなかったのが悪い。
PROGRAMMING
Regex Exercise [10pt]
regex 101使ってやると楽。条件にあう正規表現を書いていきましょう。
Mimic Unicode [20pt]
解けなかった。Unicode文字が3種類あるということはわかったのでモールス信号かと思ってやってみるもそれっぽいデータにはならず。そこから先に進めず諦め。
LFSR Period [20pt]
線形帰還シフトレジスタの周期を求める問題。手を抜いてオンラインで計算してくれるところがないか探して2つ見つけた(これとこれ)が、うまくいかず。
最終的にはPyLFSRを見つけてこれを使って周期を求めるプログラムを書いた。と簡単に書いているけど試行錯誤でかなりの時間を溶かした。行き当たりばったりでやってるからね。
import numpy as np
from pylfsr import LFSR
fpoly = [ 20, 15, 11 ]
initstate = [ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1 ]
L = LFSR(fpoly=fpoly,initstate=initstate,conf="fibonacci")
while True:
L.next()
if False in (L.get_initState() == L.get_currentState()):
print("%03d: False" % L.count)
else:
print("%03d: True" % L.count)
break
なお、線形帰還シフトレジスタにはフィボナッチとガロアの2種類があるのだが、値は違うがガロアでやっても周期は求まった。試していないがそちらも正解だったのだろうか。
Grayscale Matrix [30pt]
手を付けず。
PWN
Auth [10pt]
シンプルなスタックオーバーフロー。私はリターンアドレスをputs("Login succeeded!!")
のところに書き換えて飛ばしたけど、入力パスワードがフラグと一致しているかどうかを"true"/"false"
で持ってるバッファが途中にあるのでそこを"true"
に書き換えてやるのでもよかった。
Festival [10pt]
整数オーバーフロー。Flagを3個買おうとすると合計金額がマイナスになるので買える。
Parrot [20pt]
こちらの入力をオウム返ししてくるけれど出力の際にprintf(buf);
とかやってる。このためFoormat String Attackが通る。スタックの中にフラグ文字列へのポインタがあるので、gdbでスタックの状態見ながらスタックの何番目を見ればいいかを確認してやればよい。具体的には%7$s
でフラグが得られる。
Shock [20pt]
YouはShock!
というわけで懐かしのShellShock。実はNW/Transferでゾーン転送したときにShellShockに使われる文字列が出ている。しかしこれは罠である。
() { :]};
じゃなくて() { :;};
が正解。罠なのか素で間違えたのかはわからない。あと、パスが通ってないので組み込みコマンド以外はフルパスで打ってやらないといけない点に注意。ls -> /bin/ls
など。
Noprotect [30pt]
こちらもAuthと同じくシンプルなスタックオーバーフロー名前通り何のセキュリティ機構もないのでflags
関数に飛ばしてやればよい。
TRIVIA
Threat [10pt]
ランサムウェア
Behavior [10pt]
EDR
Inventor [10pt]
Rivestなのでリベスト。RC4の人なのでRは覚えている。Sは何か覚えている。Aは一番忘れがち。ごめんなエーデルマン。
WEB
Basic [10pt]
401が返ってきているところは認証失敗しているのでスルーして、200が返ってきているリクエストのAuthorizationヘッダを見ればよい。
Discovery [10pt]
feroxbusterしたらgames
フォルダがあってその中にadmin.html
があるのがわかったのでアクセスしてフラグゲット。
Bypass [20pt]
"<>"
が"<>"
に変換され、"script"
という文字列が除去される。後者に関しては1回除去されるだけなので"sscriptcript"
などとしてやればよい。前者は年齢欄でXSSを試みることで回避できた。JavaScriptで年齢欄に数字以外が入っていたら怒られるので、リクエストをいじってやる必要がある。
Spray [20pt]
解けなかった。id=1
のユーザ名がuser1
なのでuser1
からuser100
でスプレーしたけどダメだった。user500
まで試してみたけどダメだったのだがメールアドレスのユーザ部がユーザ名だったら泣くぞ。
Location [30pt]
解けなかった。何をしたらいいかわからず。
感想
変な問題はあったけど1問だけで、全体的には自分にはちょうどいい難易度で楽しかった。やっぱり解けると楽しいね。内容も現実の課題に近づけた感じで良かった。去年より順位が下がりまくってしまったけどこれは参加者が増えたからだろうか。来年も時間が取れれば参加しよう。
ピンバック: 防衛省サイバーコンテスト2024 (Feb.) writeup | 愚行録 the Next Generation