概况
在pakachu的靶场里,有 exec “ping” 的远程命令执行演练。 但需要注意的是: 我们的演练环境是搭建在docker系统里面的,docker相对来说比较精简,可能是没有ping命令存在的。
在 docker里运行
apt install iputils-ping

完成ping命令的安装。
漏洞初探
来到页面

页面要求我们输入一个ip地址,然后代码会调用系统的ping命令来执行,最后反馈结果:
开脑洞
页面提供了ping命令的数据输入,也就是我们有了一个与系统交换数据的机会。在php的页面里,能够直接调用系统底仓执行命令的函数有哪些呢?
php命令执行函数
代码执行与命令执行执行命令的函数高危函数:system()、exec()、shell_exec()、passthru()、pctnl_exec()、popen()、proc_open()
- system()—执行shell命令也就是向dos发送一条指令
- shell_exec()—通过shell环境执行命令,并且将完整的输出以字符串的方式返回
- exec()—执行外部程序
- passthru()—执行外部程序并且显示原始输出
所以,我们推测,php后端使用的函数可能是shell_exec()或者passthru() 。
深挖shell_exec()和passthru()
推测
推测码农在写代码的时候,是把外部传入的ip地址直接组合到了代码的内部。以shell_exec来举例子,可能的伪代码形式是:
$ping_data=$_POST[“ip”]; $ret = shell_exec(“ping “. $ping_data); print_r($ret);
投射到系统层,可以类似成:
ping 114.114.114.114
我们可以控制的变量为$ping_data,则是否可以通过修改ping 的数据来构造一个我想要执行的命令,并拿到返回结果。
组合命令
在命令行可以一次执行多个命令,有以下几种方法:
每个命令之间用;隔开
说明:各命令的执行结果,不会影响其它命令的执行。换句话说,各个命令都会执行,但不保证每个命令都执行成功。
命令: ll;ps
每个命令之间用&&隔开
说明:若前面的命令执行成功,才会去执行后面的命令。这样可以保证所有的命令执行完毕后,执行过程都是成功的。
命令:cd /etc/no_this_dir && ps 和 cd /usr/bin && ps

2图对比可以看到&&的执行效果
每个命令之间用||或者|隔开
说明:||是或者的意思,只有前面的命令执行失败后才去执行下一条命令,直到执行成功一条命令为止。
管道符号 | 可以将一个命令的输出导向另一个命令的输入,从而让两个(或者更多命令)像流水线一样连续工作,不断地处理文本流。
命令: cd /etc/no_this_dir || ps 和 cd /etc/no_this_dir | ps 

| 管道命令有时候只是为了取得并行执行的效果,没有真正的想过要将一个命令的输出导向到另外一个命令的输入。此乃“不折手段”
| 符号 | 说明 |
|---|---|
| A;B | A 不论正确与否都会执行 B 命令 |
| A&B | A 后台运行,A 和 B 同时执行 |
| A&&B | A 执行成功时候才会执行 B 命令 |
| A|B | A 执行的输出结果,作为 B 命令的参数,A 不论正确与否都会执行 B 命令 |
| A||B | A 执行失败后才会执行 B 命令 |
漏洞实战
组合1
114.114.114.114 -c 1; cat /etc/passwd
组合2
127.0.0.1 -c 1 && cat /etc/passwd
组合3
1..1.1.1 || cat /etc/passwd
1..1.1.1 | cat /etc/passwd
讨论
windows下和linux下命令行 dos环境和bash环境在命令格式上的区别。
linux下面的ping命令,如果只给ip地址,在正确的情况下,它会一直ping下去。
同学们还能想到哪些?
string system ( string $command [, int &$return_var ] ) string exec ( string $command [, array &$output [, int &$return_var ]] ) void passthru ( string $command [, int &$return_var ] )
注意的是:这三个函数在默认的情况下,都是被禁止了的,如果要使用这几个函数,就要先修改php的配置文件php.ini,查找关键字disable_functions,将这一项中的这几个函数名删除掉,然后注意重启apache。



