网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。
目录
[1. PHP代码审计流程](#1. PHP代码审计流程)
[2. ThinkPHP框架审计 vs 原生PHP](#2. ThinkPHP框架审计 vs 原生PHP)
[3. PHP原生敏感函数及搜索关键字](#3. PHP原生敏感函数及搜索关键字)
[4. 反序列化链魔术方法入口点](#4. 反序列化链魔术方法入口点)
[5. SSRF漏洞原理与利用](#5. SSRF漏洞原理与利用)
[6. SSRF修复建议](#6. SSRF修复建议)
[7. PHP === 与 == 的区别](#7. PHP === 与 == 的区别)
[8. PHP入口函数与路由方法](#8. PHP入口函数与路由方法)
[9. PHP变量覆盖漏洞](#9. PHP变量覆盖漏洞)
[10. 文件包含漏洞防御](#10. 文件包含漏洞防御)
[11. SQL注入防御(PHP vs Java)](#11. SQL注入防御(PHP vs Java))
[12. 二次注入与防御](#12. 二次注入与防御)
长某亭科技-安全服务工程师(二面)
拿到一份php代码做审计,审计的流程大概是怎么样的 给的源码时ThinkPHP框架的话,审计起来和没有使用框架的有什么不同,从流程上或者关注的点上有什么不同 php原生的敏感函数有哪些,比如搜索关键字的话会搜哪些 反序列化的时候,unserialize()反序列的一个字符串的时候,对象会有一些魔术方法会被自动调用到,在找反序列化的链时,有哪些魔术方法是可以作为一个入手点去找的 有没有审计过实际的项目,比如github上一些开源的cms SSRF这类的漏洞熟悉吗,说一下原理和利用方式 我们利用SSRF可以做什么,达到什么效果 在php环境下,怎么最大程度的利用SSRF,拿到shell或者进入内网 怎么利用内网的机器请求内网中的服务 ssrf漏洞的修复建议,修复的时候需要注意哪些细节 如果用白名单策略修复ssrf,从用户输入的变量里拿出要访问的目标,这个需要注意哪些,因为一些url会通过特殊的字符做白名单绕过,对取变量这个操作有哪些需要注意的细节 php三个等号与俩个等号的区别 php代码常见的入口函数 一些php的开发框架可以帮我们做一下ur路由,对这些路由的方法熟悉吗 php的变量覆盖 有一个php的程序,本身就允许文件包含的操作,同时想要避免文件包含漏洞,写代码的时候注意哪些 远程文件包含和本地文件包含,这俩种涉及的php设置是什么 本地文件包含能不能通过php配置限制文件包含的路径(不通过代码直接通过配置项来解决) php做sql注入防御有哪些方法 java 做sql注入防御有哪些方法 sql的二次注入 如何防御二次注入
1. PHP代码审计流程
核心步骤
- 环境分析
确认PHP版本(如5.6/7.4/8.0)、框架版本(ThinkPHP 3.2/5.0/6.0)及依赖库(如Guzzle HTTP),检查是否存在已知CVE漏洞(如ThinkPHP 5.0.23 RCE)。- 敏感函数追踪
全局搜索eval()
、system()
、file_put_contents()
等函数,结合用户输入(如$_GET['id']
)判断是否可控。- 动态调试
使用Xdebug跟踪关键参数(如路由参数、数据库查询语句),验证过滤逻辑是否绕过。- 框架特性审计
针对框架的中间件、模板引擎(如Smarty)、ORM(如Eloquent)检查配置错误(如调试模式开启)。示例
若发现
$id = input('id'); Db::query("SELECT * FROM table WHERE id=$id");
,可能存在SQL注入,因未使用预处理。
2. ThinkPHP框架审计 vs 原生PHP
维度 ThinkPHP 原生PHP 路由安全 检查 route.php
中是否开放危险路由(如/admin/*
)直接通过 $_GET['page']
调用脚本输入过滤 框架自带 input()
过滤,但可能被绕过(如数组注入)依赖开发者手动调用 htmlspecialchars()
历史漏洞 需关注框架漏洞(如5.x反序列化链、6.x路由RCE) 常见于文件包含、命令执行原生函数滥用 数据库操作 ORM可能自动过滤,但复杂查询仍需手动处理 直接拼接SQL导致注入风险高
3. PHP原生敏感函数及搜索关键字
- 代码执行 :
eval()
、assert()
、create_function()
- 命令执行 :
system()
、exec()
、passthru()
、反引号(ls
)- 文件操作 :
file_get_contents()
、fopen()
、include
/require
(动态路径时)- 数据库注入 :
mysql_query()
、mysqli_query()
(未过滤拼接语句)- 反序列化 :
unserialize()
搜索技巧 :用正则匹配如
(\$_(GET|POST|COOKIE).*?){.*?(eval|system)
,定位用户输入到敏感函数的链路。
4. 反序列化链魔术方法入口点
__destruct()
:对象销毁时触发,常用于释放资源或调用其他方法(如关闭文件、删除缓存)。__wakeup()
:反序列化时自动调用,可能初始化危险操作(如连接数据库)。__toString()
:对象被转为字符串时触发(如echo $obj
),可能触发链式调用。__call()
:调用不存在方法时触发,动态执行代码(如$obj->run()
触发__call('run')
)。实战案例 :ThinkPHP 5.x反序列化漏洞中,通过
__destruct()
触发delete()
方法删除文件,进一步构造链式调用执行命令。
5. SSRF漏洞原理与利用
原理
服务端未校验用户提供的URL,直接发起请求(如
file_get_contents($_GET['url'])
),导致攻击者操控服务端访问内网或本地资源。利用方式
- 协议利用 :
file:///etc/passwd
:读取本地文件。gopher://:3306/_...
:攻击内网MySQL(发送恶意SQL包)。- 端口扫描 :通过响应时间差异判断内网端口开放状态(如
http://192.168.1.1:8080
)。- 绕过限制 :
- 使用
[::]
绕过IP格式检测(如http://[::]:80@192.168.1.1:8080/
)。- 短域名重定向(如
http://tinyurl.com/redirect-to-localhost
)。PHP最大化利用
- 开启
allow_url_fopen=On
和allow_url_include=On
时,结合php://input
执行代码。- 利用
expect://
协议执行系统命令(需安装PECL扩展)。
6. SSRF修复建议
白名单策略关键点
- 解析规范化 :
使用parse_url()
解析URL后,严格校验host
和scheme
(如仅允许http(s)://example.com
)。- 防御绕过 :
- 禁止
@
、#
等分隔符(如http://evil.com@trusted.com
)。- 禁用重定向(如
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false)
)。- 协议限制 :禁用
file
、gopher
、dict
等高危协议。代码示例 :php
$url = $_GET['url']; $parsed = parse_url($url); if ($parsed['host'] !== 'allowed.com' || !in_array($parsed['scheme'], ['http', 'https'])) { die('Invalid URL'); }
7. PHP === 与 == 的区别
- 松散比较(
==
) :自动类型转换后比较值。
0 == "0"
→true
false == "0"
→true
- 严格比较(
===
) :值和类型均需相同。
0 === "0"
→false
false === 0
→false
安全影响 :若使用
==
判断用户权限(如if ($_GET['role'] == 'admin')
),攻击者传入0
可能绕过检测。
8. PHP入口函数与路由方法
- 原生PHP入口 :
- 通过
index.php?action=login
调用login()
函数。- 使用
$_SERVER['PATH_INFO']
解析路径(如/user/profile
)。- 框架路由 :
- ThinkPHP :
Route::get('user/:id', 'UserController@profile')
。- Laravel :
Route::post('/api', 'ApiController@handle')
。- 路由安全 :
- 限制HTTP方法(如仅允许GET访问公开接口)。
- 避免路由通配符(如
/admin/*
可能暴露后台路径)。
9. PHP变量覆盖漏洞
常见场景
extract()
滥用 :phpextract($_GET); // 将$_GET键名转为变量,攻击者可覆盖$is_admin if ($is_admin) { ... }
parse_str()
未初始化 :phpparse_str($_SERVER['QUERY_STRING']); // 变量未初始化,导致覆盖
防御 :禁用
extract()
,或设置EXTR_SKIP
参数拒绝覆盖已有变量。
10. 文件包含漏洞防御
代码层面
固定文件后缀:
include $_GET['page'] . '.php';
。映射用户输入到白名单:php
$allowed = ['home', 'about']; $page = $_GET['page']; if (in_array($page, $allowed)) { include "$page.php"; }
配置层面
open_basedir = /var/www/html
:限制PHP可访问的目录。allow_url_include = Off
:禁止远程文件包含。
11. SQL注入防御(PHP vs Java)
语言 防御方案 示例 PHP PDO预处理: $stmt->execute([$user])
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
Java PreparedStatement: ps.setString(1, user)
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name = ?");
注意:
- PHP的
mysqli_real_escape_string()
需正确指定字符集(如mysqli_set_charset($conn, 'utf8')
)。- Java的ORM框架(如MyBatis)需使用
#{}
而非${}
(防止拼接)。
12. 二次注入与防御
原理
数据首次存入时未过滤(如
INSERT INTO users (name) VALUES ('admin\'-- ')
),后续查询时被拼接(如SELECT * FROM users WHERE name='$name'
),触发注入。防御
- 统一过滤 :入库前和出库后均转义(如
htmlspecialchars()
+ 预处理语句)。- 数据分类:区分"可信数据"(如系统生成)和"不可信数据"(如用户输入),即使来自数据库也重新过滤。
示例 :php
// 从数据库读取数据后重新转义 $name = htmlspecialchars($db->getUserName($id), ENT_QUOTES); $sql = "SELECT * FROM posts WHERE author = '$name'";
总结
- 框架审计:优先检查历史漏洞和路由配置,对比原生PHP更依赖框架机制理解。
- SSRF利用:协议和内网探测是关键,修复需多层级校验(协议、域名、路径)。
- 安全编码:始终遵循最小权限原则,结合白名单、预处理、严格类型比较。