代码审计入门总结
字数 2146 2025-08-29 08:31:47
PHP代码审计入门与常见漏洞总结
0x00 简介
本文是基于seay《PHP代码审计》一书的学习总结,旨在为代码审计初学者提供一个系统的学习框架和常见漏洞函数参考。通过学习,读者应能够独立完成对CMS系统的代码安全检测。
0x01 代码审计整体思路
-
通读全文代码:从功能函数代码开始阅读,如
include文件夹下的common_fun.php等关键文件。 -
查看配置文件:查找带有
config关键字的文件,特别是数据库连接文件如mysql.class.php中的connect()函数。 -
跟踪首页文件:从
index.php入手,了解程序运作时调用的函数和文件。 -
扩展阅读:以
index.php为起点,层层扩展阅读包含的文件,了解其功能后进入功能文件夹的首页文件继续深入。
0x02 常见漏洞类型及审计方法
A. 文件操作漏洞
安全原则:
- 尽量避免使用用户可控的文件名参数
- 严格区分用户权限
- 禁止传入
..、/、\等特殊字符 - 对传入参数进行检查和限制
1. 文件包含漏洞
-
本地文件包含:常见于模块加载、模板加载、cache调用
- 关键函数:
include()/include_once()、require()/require_once() - 审计重点:寻找可控变量
- 关键函数:
-
远程文件包含:需
allow_url_include = on -
文件包含截断:
- PHP版本<5.3时可用
- 截断方式:问号(伪截断)、点(.)、反斜杠(/)
2. 文件读取(下载)漏洞
- 关键函数:
file_get_contents(), highlight_file(), fopen(), readfile(), fread(), fgetss(), fgets(), parse_ini_file(), show_source(), file()
3. 文件上传漏洞
-
关键函数:
move_uploaded_file() -
常见绕过方式:
- 未过滤或本地过滤:直接上传PHP文件
- 黑名单绕过:
- 利用IIS默认支持的扩展名(.asp, .cdx, .asa, .cer等)
- 文件名后加空格(如
1.php)
- 文件头验证绕过:
- 伪造
GIF89a文件头绕过getimagesize() - 控制
$_FILES["file"]["type"]值
- 伪造
-
防范措施:
- 使用
in_array()或===严格比较扩展名 - 重命名规则:
md5(time() + rand(1,1000))
- 使用
4. 文件删除漏洞
- 关键函数:
unlink() - 经典案例:Metinfo任意文件删除漏洞
target.com/recovery.php?&action=delete&filename=../../index.php
B. 代码执行漏洞
1. 代码执行函数
-
关键函数:
eval(), assert(), preg_replace(), call_user_func(), call_user_func_array(), array_map() -
特殊用法:
preg_replace()的e修饰符:$replacement会被当作PHP代码执行call_user_func():第一个参数为回调函数,第二个为参数eval()与assert()区别:eval("phpinfo();"); // 正确 assert("phpinfo();"); // 正确 eval("phpinfo()"); // 错误(缺少分号) assert("phpinfo()"); // 正确
2. 动态函数执行
- 后门示例:
<?php $_GET['a']($_GET['b']); ?>
3. 命令执行函数
-
关键函数:
system(), exec(), shell_exec(), passthru(), pcntl_exec(), popen(), proc_open() -
特殊用法:
popen()示例:popen('whoami >> /path/1.txt', 'r');- 反引号执行:
echo `whoami`;
-
双引号与单引号区别:
$a = 1; echo "$a"; // 输出1(解析变量) echo '$a'; // 输出$a(不解析)
C. 变量覆盖漏洞
1. 危险函数
extract():从数组导入变量到当前符号表parse_str():将字符串解析为多个变量import_request_variables():导入GET/POST/Cookie变量
2.
\[变量覆盖 - 示例: ```php foreach($_GET as $key => $value) { \]
key = $value; // 可能导致变量覆盖
}
### D. 逻辑漏洞
#### 1. 等于与存在判断绕过
- `in_array()`:比较前自动转换类型
- `is_numeric()`:HEX输入可通过检查
- `==`与`===`区别:双等于会类型转换,三等于严格比较
#### 2. 越权问题
- **水平越权**:同权限用户间的越权
- **垂直越权**:低权限用户获取高权限
#### 3. 常见问题
- 缺少`exit`/`return`/`die`:
```php
if(file_exists('install.lock')) {
header("Location:xxx.com");
// 缺少exit
}
echo "test"; // 仍会执行
4. 支付漏洞
- 客户端修改单价/总价/数量
- 服务端未严格校验
- 重复发包利用时间差
5. 危险函数
str_replace()可能被绕过:$a = addslashes($_GET['a']); $b = addslashes($_GET['b']); $c = str_replace($a,'',$b); // 可能被绕过
E. 会话认证漏洞
1. COOKIE验证问题
- 敏感信息直接保存在COOKIE中
- 加密算法可逆
2. 安全建议
- 优先使用SESSION而非COOKIE
- SHA1比MD5更安全(解密网站更少)
- 限制用户单IP登录
F. 二次漏洞
1. 特点
- 不是逻辑问题,而是可信问题
- 业务越复杂,触发率越高
- 常见场景:购物车、订单、引用数据、文章编辑
2. 常见技巧
-
GPC转义绕过:
$_SERVER不受GPC保护- GBK宽字节注入:
%df'→運'
-
字符串问题:
- 空字符截断(PHP<5.3)
iconv转换截断:$a = '1'.chr(130).'2'; echo iconv("UTF-8", "GBK", $a); // 输出1
-
php://流利用:
include($_GET['file']); // 利用:file=php://filter/convert.base64-encode/resource=example.txt
3. PHP解析标签
<script language="php">...</script><?...?>(PHP3.0.4+)<%...%>(需asp_tags=on)
4. 正则问题
- 缺少
^和$限定匹配位置 - 特殊字符未转义
5. 报错注入
- Windows FindFirstFile利用:
- 搜索
12345.txt可用1<<或12<<代替 - 不能单独使用
<或>
- 搜索
0x03 总结
代码审计需要结合开发知识,理解业务逻辑和代码执行流程。本文总结了PHP代码审计中的常见漏洞类型、危险函数和审计方法,可作为初学者入门参考。实际审计时应结合具体代码上下文,灵活运用这些知识。