sqlmapapi

为什么要使用SQLMAP API?

由于SQLMAP每检测一个站点都需要开启一个新的命令行窗口或者结束掉上一个检测任务。虽然 -m 参数可以批量扫描URL,但是模式也是一个结束扫描后才开始另一个扫描任务。通过api接口,下发扫描任务就简单了,无需开启一个新的命令行窗口。

sqlmap安装完成后,输入以下命令,返回内容如下图一样,意味着安装成功:

python sqlmap.py -h
深入了解sqlmap_api

sqlmap api

说了那么多,到底api如何使用呢?在下载安装SQLMAP后,你会在sqlmap安装目录中找到一个 sqlmapapi.py 的文件,这个 sqlmapapi.py 文件就是sqlmmap api。sqlmap api分为服务端和客户端,sqlmap api有两种模式,一种是基于HTTP协议的接口模式,一种是基于命令行的接口模式。

sqlmapapi.py的使用帮助

通过以下命令获取sqlmapapi.py的使用帮助:

返回的信息:

开启api服务端

无论是基于HTTP协议的接口模式还是基于命令行的接口模式,首先都是需要开启api服务端的。通过输入以下命令即可开启api服务端:

命令成功后,在命令行中会返回一些信息。以下命令大概的意思是api服务端在本地8775端口上运行,admin token为1acac56427f272e316fceabe5ddff5a5,IPC数据库的位置在/tmp/sqlmapipc-zOIGm_,api服务端已经和IPC数据库连接上了,正在使用bottle 框架wsgiref标准接口。

但是通过上面的这种方式开启api服务端有一个缺点,当服务端和客户端不是一台主机会连接不上,因此如果要解决这个问题,可以通过输入以下命令来开启api服务端:

命令成功后,远程客户端就可以通过指定远程主机IP和端口来连接到API服务端。

固定admin token

如果您有特殊的需求需要固定admin token的话,可以修改文件api.py,该文件在sqlmap目录下的/lib/utils/中,修改该文件的第661行代码,以下是源代码:

sqlmap api的两种模式

命令行接口模式

输入以下命令,可连接api服务端,进行后期的指令发送操作:

如果是客户端和服务端不是同一台计算机的话,输入以下命令:

输入以上命令后,会进入交互模式,如下图所示:

深入了解sqlmap_api

通过在交互模式下输入help命令,获取所有命令,以下是该接口模式的所有命令:

既然了解了命令行接口模式中所有命令,那么下面就通过一个sql注入来演示该模式接口下检测sql注入的流程。

检测GET型注入

通过输入以下命令可以检测GET注入

虽然我们仅仅只指定了-u参数,但是从返回的信息中可以看出,输入new命令后,首先先请求了/task/new,来创建一个新的taskid,后又发起了一个请求去开始任务,因此可以发现该模式实质也是基于HTTP协议的。

深入了解sqlmap_api

通过输入 status 命令,来获取该任务的扫描状态,若返回内容中的status字段为terminated,说明扫描完成,若返回内容中的status字段为run,说明扫描还在进行中。下图是扫描完成的截图:

深入了解sqlmap_api

通过输入 data 命令,来获取扫描完成后注入出来的信息,若返回的内容中data字段不为空就说明存在注入。下图是存在SQL注入返回的内容,可以看到返回的内容有数据库类型、payload、注入的参数等等。

深入了解sqlmap_api

下图是不存在注入返回的内容,data字段为空:

深入了解sqlmap_api

检测POST型、cookie、UA等注入

通过输入以下命令,在data.txt中加入星号,指定注入的位置,来达到检测POST、cookie、UA等注入的目的:

深入了解sqlmap_api

总结

基于命令行的接口模式用起来还是比较方便的,我们只需要通过 new 命令就可以自动创建taskid并开始该任务,但是如果写程序调用的话可能就不是那么友善了,因此笔者会重点介绍下面的一种接口模式,基于HTTP协议的接口模式。

基于HTTP协议的接口模式

下列都是基于HTTP协议API交互的所有方法:提示:“@get”就说明需要通过GET请求的,“@post”就说明需要通过POST请求的;POST请求需要修改HTTP头中的Content-Type字段为application/json。

@get('/error/401')

该接口在我的理解表明首先需要登录(Admin token),不然会返回状态码401。具体代码如下:

深入了解sqlmap_api

@get("/task/new")

该接口用于创建一个新的任务,使用后会返回一个随机的taskid。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/task//delete")

该接口用于删除taskid。在调用时指定taskid,不指定taskid会有问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/admin/list")/@get("/admin//list")

该接口用于返回所有taskid。在调用时指定taskid,不指定taskid会有问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/admin/flush")/@get("/admin//flush")

该接口用于删除所有任务。在调用时指定admin token,不指定admin token可能会有问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/option//list")

该接口可获取特定任务ID的列表选项,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@post("/option//get")

该接口可获取特定任务ID的选项值,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@post("/option//set")

该接口为特定任务ID设置选项值,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@post("/scan//start")

该接口定义开始扫描特定任务,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/scan//stop")

该接口定义停止扫描特定任务,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/scan//kill")

该接口可杀死特定任务,需要指定taskid,不然会出现问题。具体代码如下:

@get("/scan//status")

该接口可查询扫描状态,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/scan//data")

该接口可获得到扫描结果,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:存在SQL注入的返回结果,返回的内容包括payload、数据库类型等等。

深入了解sqlmap_api

@get("/scan//log") /@get("/scan//log//")

该接口可查询特定任务的扫描的日志,调用时请指定taskid,不然会出现问题。具体代码如下:

下图是调用该接口的截图:

深入了解sqlmap_api

@get("/download///")

下载服务端指定任务的文件。具体代码如下:

看完了以上的接口代码,我相信您一定会使用了吧,那么下面就通过一个sql注入来演示该模式接口下检测sql注入的流程。

准备

使用该模式接口需要用到python的两个库文件,一个是requests库,一个是json库。下图是导入库的操作:

深入了解sqlmap_api

检测GET型注入

下面是完整的一次API接口访问,"从创建任务ID,到发送扫描指令,再到查询扫描状态,最后查询结果”的过程。

深入了解sqlmap_api

具体输入输出代码如下:

可能您会被最后返回的结果好奇,ptype、suffix、clause等等都是什么意思呢?下面我给出部分字段的含义:

字段

含义

dbms

数据库类型

Microsoft AccessIBM DB2FirebirdSAP MaxDBMicrosoft SQL ServerMySQLOraclePostgreSQLSQLiteSybaseHSQLDBH2Informix

suffix

在有些时候,需要在注入的payload的后面加一些字符,来保证payload的正常执行。

GENERIC_SQL_COMMENT] AND ([RANDNUM]=[RANDNUM] AND (([RANDNUM]=[RANDNUM] AND ((([RANDNUM]=...太多了,具体可查看xml/boundaries.xml文件。

prefix

在有些时候,需要在注入的payload的前面加一些字符,来保证payload的正常执行。

)')'"...太多了,具体可查看xml/boundaries.xml文件。

clause

payload在哪个语句里生效

0: "Always",1: "WHERE",2: "GROUP BY",3: "ORDER BY",4: "LIMIT",5: "OFFSET",6: "TOP",7: "Table name",8: "Column name",9: "Pre-WHERE (non-query)"

where

以什么样的方式将我们的payload添加进去

ORIGINAL = 1NEGATIVE = 2REPLACE = 3

ptype

parameter type;注入点的类型

1: "Unescaped numeric", 2: "Single quoted string", 3: "LIKE single quoted string", 4: "Double quoted string", 5: "LIKE double quoted string", 6: "Identifier (e.g. column name)",

dbms_version

数据库的粗略版本

>= 5.5>= 5.0.12...

place

请求方式

GETPOST(custom) HEADER

title

当前测试Payload的标题,通过标题就可以了解当前的注入手法与测试的数据库类型。

AND boolean-based blind - WHERE or HAVING clause...

vector

payload向量

AND (SELECT * FROM (SELECT(SLEEP([SLEEPTIME]-(IF([INFERENCE],0,[SLEEPTIME])))))[RANDSTR])...

payload

有效负荷,进行测试的SQL语句

1、news_id=1 AND 6788=6788 2、login_user=1&login_password=-3814' OR 7117=7117#&mysubmit=Login

parameter

哪个参数可以注入

usernamenews_id....

检测POST注入、COOKIE、UA等注入

检测POST注入和检测GET注入类似,但是还是有一定区别的,与GET注入检测区别如下,流程上是一样的,不同的是开启扫描任务的时候,多提交一个data字段。

下面是一次完整的POST注入检测过程

深入了解sqlmap_api

具体输入输出代码如下:

那么如何检测COOKIE注入、UA注入这些呢?下面笔者将列出api接口可接收的所有字段:

若要检测COOKIE注入的话,我们只要在@post("/scan//start")接口中,传入cookie字段; 若要检测referer注入的话,我们只要在@post("/scan//start")接口中,传入referer字段。 若要从注入点中获取数据库的版本、数据库的用户名这些,只要在@post("/scan//start")接口中,传入getBanner字段,并设置为True,传入getUsers字段,并设置为True。

总结

基于HTTP的接口模式用起来可能比较繁琐,但是对于程序调用接口还是很友善的。总之该模式的流程是:1、通过GET请求 http://ip:port/task/new 这个地址,创建一个新的扫描任务; 2、通过POST请求 http://ip:port/scan//start 地址,并通过json格式提交参数,开启一个扫描;通过GET请求 http://ip:port/scan//status 地址,即可获取指定的taskid的扫描状态。这个返回值分为两种,一种是run状态(扫描未完成),一种是terminated状态(扫描完成); 3、扫描完成后获取扫描的结果。

使用Python3编写sqlmapapi调用程序

下面就来编写一个sqlmapapi调用程序,首先我们得再次明确一下流程:

1、通过 sqlmapapi.py -s -H "0.0.0.0" 开启sqlmap api的服务端。服务端启动后,在服务端命令行中会返回一个随机的admin token值,这个token值用于管理taskid(获取、清空操作),在这个流程中不需要amin token这个值,可以忽略。之后,服务端会处于一个等待客户端的状态。 2、通过GET请求 http://ip:port/task/new 这个地址,即可创建一个新的扫描任务,在响应中会返回一个随机的taskid。这个taskid在这个流程中尤为重要,因此需要通过变量存储下来,方便后面程序的调用。 3、通过POST请求 http://ip:port/scan//start 地址,并通过json格式提交参数(待扫描的HTTP数据包、若存在注入是否获取当前数据库用户名),即可开启一个扫描任务,该请求会返回一个enginedid。 4、通过GET请求 http://ip:port/scan//status 地址,即可获取指定的taskid的扫描状态。这个返回值分为两种,一种是run状态(扫描未完成),一种是terminated状态(扫描完成)。 5、判断扫描状态,如果扫描未完成,再次请求 http://ip:port/scan//status 地址 ,直到扫描完成。 6、扫描完成后获取扫描的结果,是否是SQL注入,若不存在SQL注入,data字段为空,若存在SQL注入,则会返回数据库类型、payload等等。

明确了流程后,为了可维护性好和main.py文件代码量少,笔者首先是写了一个类,代码如下:

mian.py

Githun地址:https://github.com/FiveAourThe/sqlmap_api_demo

最后更新于

这有帮助吗?