3.1 SQLMAP详解

SQLMap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定URL的SQL注入漏洞,内置了很多绕过插件,支持的数据库有:
MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,IBM DB2,SQLite,Firebird,Sybase和SAP MaxDB。
SQLMap采用了一下5种独特的SQL注入技术:

  1. 基于布尔类型的盲注:即可以根据返回页面判断条件真假的注入。
  2. 基于时间的盲注:即不能根据页面返回的内容判断任何信息,要用条件语句查看时间延迟的语句是否已经执行(即页面返回时间是否增加)来判断。
  3. 基于报错注入:即页面会返回错误信息,或者把注入的语句的结果直接返回到页面中。
  4. 联合查询注入:在可以使用的Union的情况下的注入。
  5. 堆查询注入:可以同时执行多条语句时的注入。

3.1.1 安装SQLMap

SQLMap的安装需要Python环境(不支持Python3),这里我使用的是Python2.7.3,具体的安装教程这里不再赘述。
安装教程这里挂个链接,大家可以自己去看(Windows环境)

3.1.2 SQLMap入门

1.判断是否存在注入
假设目标注入点是:

http://localhost/sql/Less-1/?id=1

判断其是否存在注入的命令如下所示:

sqlmap.py -u http://localhost/sql/Less-1/?id=1

这里的目标URL是我之前在本地搭建的SQL注入练习平台,如果你没有读前面的文章,或者不会搭建SQL注入环境,可以去看我的这些文章:环境搭建
当我们通过GET方式请求为1时,回显如下:
id=1
SQLMap查询是否存在注入
还有一种情况,当注入点后面的参数大于等于两个时,需要加入双引号,如下所示:

sqlmap.py -u http://localhost/sql/Less-1/?id=1&uid=2 "

可以看到,运行完判断的是否存在注入的语句后面,“爆出”一大段代码,下面来分析代码反馈给我们的信息。这里有三处需要选择的地方:

第一处的意思为检测到数据库可能是MySQL,是否需要跳过检测其他数据库
第二处的意思为在“leave1,risk1”的情况下,是否使用MySQL对应的所有Payload进行检测
第三出的意思是参数ID存在漏洞,是否要继续检测其他参数,一般按默认回车即可

三段信息

2.判断文本中的请求是否存在注入
从文件中加载HTTP请求,SQLMap可以从一个文本文件中获取HTTP请求,这样就可以不设置其他参数(如cookie,POST)
txt文件中的内容为Web数据包:
Burp Suite抓包
我们将抓到的包中的数据放到文本文件中
txt文件中的内容
判断是否存在注入的命令如下所示

sqlmap.py -r /Users/macbook/Desktop/1.txt # -r 一般在存在cookie注入时使用

查询是否存在注入

3.查询当前用户下的所有数据库
该命令是确定网站存在注入后,用户查询当前用户下的所有数据库的库名。

sqlmap.py -u http://localhost/sql/Less-1/?id=1 --dbs

如果当前用户有权限读取包含数据库列表信息的表,使用该命令就可以列出所有的数据库
其意思是在XXX数据库中继续查询其他数据
--dbs
从图中可以看出,查询出了8个数据库以及所有数据库的库名。当继续注入时,--dbs 缩写成 -D xxx

4.获取数据库中的表名
该命令的作用是查询完数据库之后,查询指定数据库中的所有表明
如果在该命令中不加入 -D 参数来指定某一个具体的数据库,那么SQLMap会列出数据库中所有的表

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" -D mysql --tables

实例1
实例2
实例3
我们拿实例1来说,可以看到mysql数据库中拥有31个表名,当继续注入时, --tables缩写成 -T
意思是在某表中继续查询。

5.获取表中的字段名
该命令的作用是查询完表名后,查询该表中所有的字段名,如下所示。

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" -D mysql -T user --columns运行该命令的结果如图:

这里我爆的是dvwa数据库中users表中的字段
users表中的字段
可以看到一共有8个字段,在后续注入中, --columns 缩写成 -C

6.获取字段内容
该命令是查询完字段之后,获取该字段中具体的数据信息,如下所示:

sqlmap -u "http://localhost/sql/Less-1/?id=1" 
-D dvwa -T users -C uesr_id,password --dump

查看具体的字段信息

7.获取数据库的所有用户
该命令的作用是列出数据库所有的用户,如下所示。在当前用户有权限读取包含所有用户的表的权限时,使用该命令就可以列出所有管理用户:

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --users

可以看到,当前用户账号是root:
列出数据库的用户

8.获取数据库用户的密码
该命令的作用是列出数据库用户的的密码,如下所示。如果当前用户有读取包含用户密码的权限,SQLMap会先列举出用户,然后列出Hash,并尝试破解。

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --passwords

查询数据库的密码

9.获取当前网站数据库的名称
使用该命令可以列出当前网站使用的数据库,如下所示:

sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --current-db

从图中可以看到数据库是"security"
列出当前网站的数据库

10.获取当前网站数据库的用户名称
使用该命令可以列出当前网站使用的数据库用户,如下所示:
sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --current-user
从图中可以看到,用户是root
列出当前数据库的用户

3.1.3SQLMap进阶:参数讲解

  1. --level5: 探测等级
    参数--level5指需要执行的测试等级,一共有5个等级(1~5),可以不加level,默认是1.SQLMap使用的Payload可以在xml/payload.xml中看到,也可以根据相应的格式根据相应的格式添加到自己的Payload,其中5级包含的Payload最多,会破解出cookie,XFF等头部注入。

这个参数会影响测试的注入点,GET和POST的数据都会进行测试,HTTP cookie在level2时就会进行测试,HTTP User-Agent/Referer头在level3时就会测试。总之,在不确定哪个Payload或参数作为注入点时,为了保证全面性,建议使用高level值

  1. --is-dba: 当前用户是否为管理权限
    该命令用于查看当前账户是否为数据库管理员账户,如下所示,在本次实例中输入该命令,会返回False,如图:

    sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --is-dba

    查看当前账户是否为数据库管理员账户

  2. --roles: 列出数据库管理员角色
    该命令用于查看数据库用户的角色,如果当前用户有权限读取包含所有用户的表,输入该命令会列举出每个用户的角色,也可以用- U参数指定想看哪个用户的角色,该命令仅适用于当前数据库是Oracle的数据。

查看当前数据库用户的角色

  1. --referer: HTTP Referer头
    SQLMap可以在请求中伪造HTTP中的referer。当 --level参数设定为3或者3以上时,会尝试对referer注入。可以使用referer命令来欺骗,如:
    --referer http://www.baidu.com
  2. --sql-shell:运行自定义SQL语句
    该命令用于执行的SQL语句,如下所示,假设执行:
    select * from users limit 0,1
    结果如下:
    sqlmap.py -u "http://localhost/sql/Less-1/?id=1" --sql-shell
    执行指定的SQL语句
  3. --os-cmd,os-shell; 运行任意操作系统命令
    在数据库为MySQL,Postgre SQL或Microsoft SQL Server,并且当前用户有权限使用特定的函数时。

1.如果数据库为MySQL,Postgre SQL ,SQLMap上传一个二进制库,包含用户自定义的函数sys_exec()和sys_eval(),那么创建的这两个函数就可以执行系统命令。
2.如果数据库为Microsoft SQL Server,SQLMap将使用xp_cmdshell存储过程,如果被禁用(在Microsoft SQL Server)
中,在2005版本及其以上被禁用,则SQLMap会重新启用它;如果不存在,会自动创建。
用--os-shell参数可以模拟一个真实的shell,输入想要执行的命令。当不能执行多个语句时(比如PHP或ASP的后端数据库为MySQl),仍然可以用INTO OUTFILE写进可写的目录,创建一个Web后门。
--os-shell支持ASP,ASP.NET,JSP和PHP四种语言(要想执行该参数,需要有数据库管理员权限,也就是--is-dba的值为True)

  1. --file-read: 从数据库服务器中读取文件
    该命令用于读取执行文件,当数据库为MySQL,Postgre SQL或Microsoft SQL Server,并且当前用户有权限使用特定的函数时,读取的文件可以是文本,也可以是二进制文件。
  2. --file-write --file-dest: 长传文件到数据库服务器中
    该命令用于写入本地文件到服务器中,当数据库为MySQL,Postgre SQL或Microsoft SQL Server,并且当前用户拥有权限使用特定的函数时,长传的文件可以是文件,也可以是二进制文件。

3.1.4 SQLMap自带绕过脚本tamper的讲解

SQLMap在默认情况下除了使用CHAR()函数防止出现单引号,没有对注入的数据进行修改,读者还可以使用--tamper参数对数据做修改来绕过WAF等设备,其中大部分脚本主要用正则模块替换攻击载荷字符编码的方式尝试绕过WAF的检测规则,命令如下所示。

sqlmap.py xxxx--tamper "模块名"

目前官方提供了几十个绕过脚本,下面是一个tamper脚本的格式

# sqlmap/tamper/escapequotes.py
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST
def dependencies():
    pass
def tamper(payload, **kwargs):
    return payload.replace("'", "\\'").replace('"','\\"')

不难看出,一个最小的的tamper脚本结构为priority变量定义和dependencies,tamper函数定义。

priority定义脚本的优先级,用于有多个tamper脚本的情况。
dependencies函数声明该脚本适用/不适用的范围,可以为空

下面以一个转大写字符绕过的脚本为例,tamper绕过脚本主要由dependcies和tamper两个函数构成。
def tamper(payload,kwargs)函数接受payload和kwargs返回一个Payload。下面这段代码的意思是通过正则匹配所有字符,将所有攻击载荷中的字符转换成大写字母。

def tamper(payload, **kwargs):
    retVal = payload
if payload:
    for match in re.findter(r"[A-Za-z]+", retVal):
        word = match.group()
        if word.upper() in kb.keywords:
            retVal = retVal.replace(word, word.upper())
return retVal
最后修改:2021 年 10 月 29 日 09 : 24 PM
如果觉得这篇文章不错,不妨赏我碎银几两。