写在前面
命令注入漏洞和SQL注入、XSS漏洞很相似,也是由于开发人员考虑不周造成的,在使用web应用程序执行系统命令的时候对用户输入的字符未进行过滤或过滤不严格导致的,常发生在具有执行系统命令的web应用中,如内容管理系统(CMS)等。
也就是在cmd等等命令行执行位置可以使用一些trick,自然你也会想到在CTF中会伴随一些关键字的屏蔽,当然也有一些绕过技巧。
这里主要是dvwa上的命令注入和一道CTF例题来说明
DVWA命令注入
后台代码并未对用户输入的参数ip的值进行过滤就直接与ping命令进行拼接并执行 ,因此我们可以使用常见的命令拼接字符对命令进行拼接,如使用“&”,“|”,“&&”,“||”
等,linux系统下还可以使用“;”,“``”
。
对于shell1 & shell2
,既执行shell1的命令也执行shell2的命令;
对于shell1 && shell2
,在shell1执行成功的情况下执行shell2,shell1执行失败就不会执行shell2,和逻辑与一样;
对于shell1 | shell2
,“|”为管道符,它将shell1执行的结果作为shell2的输入,因此无论shell1执行结果如何,都会执行shell2;
对于shell1 || shell2
,在shell1执行失败的情况下执行shell2,shell1执行成功则不会执行shell2,和逻辑或一样;
对于shell1;shell2
,在Linux系统下会将shell1和shell2都执行;
对于shell1 `shell2`,shell2的执行结果会在shell1的报错信息中显示。
这里的资料原文链接:https://blog.csdn.net/qq_32261191/article/details/101686779
dvwa-low
源码:
Command Execution Source
<?php
if( isset( $_POST[ 'submit' ] ) ) {
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec( 'ping ' . $target );
echo '<pre>'.$cmd.'</pre>';
} else {
$cmd = shell_exec( 'ping -c 3 ' . $target );
echo '<pre>'.$cmd.'</pre>';
}
}
?>
能够直接执行命令,没有什么过滤,我们使用上面的方法即可获取更多信息
dvwa-medium
源码:
Command Execution Source
<?php
if( isset( $_POST[ 'submit'] ) ) {
$target = $_REQUEST[ 'ip' ];
// Remove any of the charactars in the array (blacklist).
$substitutions = array(
'&&' => '',
';' => '',
);
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec( 'ping ' . $target );
echo '<pre>'.$cmd.'</pre>';
} else {
$cmd = shell_exec( 'ping -c 3 ' . $target );
echo '<pre>'.$cmd.'</pre>';
}
}
?>
这里具有了黑名单过滤,但是黑名单明显不完全,同时还可以混写绕过
比如
127.0.0.1&;&ls
127.0.0.1&ls
dvwa-high
由于我的版本问题,在high情况下已经无法进行注入,是写好了的版本
源码:
Command Execution Source
<?php
if( isset( $_POST[ 'submit' ] ) ) {
$target = $_REQUEST["ip"];
$target = stripslashes( $target );
// Split the IP into 4 octects
$octet = explode(".", $target);
// Check IF each octet is an integer
if ((is_numeric($octet[0])) && (is_numeric($octet[1])) && (is_numeric($octet[2])) && (is_numeric($octet[3])) && (sizeof($octet) == 4) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0].'.'.$octet[1].'.'.$octet[2].'.'.$octet[3];
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec( 'ping ' . $target );
echo '<pre>'.$cmd.'</pre>';
} else {
$cmd = shell_exec( 'ping -c 3 ' . $target );
echo '<pre>'.$cmd.'</pre>';
}
}
else {
echo '<pre>ERROR: You have entered an invalid IP</pre>';
}
}
?>
这个验证首先能够去除输入值中的反斜杠,同时以.
作为标志对payload进行拆分为数组,然后对每一个小节确认是否为数组,并且最后一个小结还会限制长度。
这也是一种防范的写法。
例题:buuctf pingpingping
打开之后是一个典型的查ip的界面,能够写ls
等命令
在探测中,可以感觉到有对敏感词进行屏蔽,并且是检测到就会报错,并不能混写或者双写绕过
最关键的是对flag关键字进行了屏蔽
还有一个index文件,但是屏蔽了空格。
所以补充知识:
在bash中绕过空格可以有以下姿势
①<>
②%20(space)
③%09(tab)
④$IFS$9
这里经测试只能用第4种了,所谓IFS,就是分隔符。
payload:
127.0.0.1;cat$IFS$1index.php
关于flag的正则,就是不能在flag中进行多写,比如 fllag就不行
payload:
?ip=123;a=ag;b=fl;cat$IFS$9$b$a.php
注意要先写ag再写fl哦