一直听说sqlmapapi很好用,最近决定写个sql注入的探测器之类的东西,可以从web界面把URL喂给sqlmap,然后坐等结果就行了。后期可以加上被动式扫描的部分,用代理(类似burp的方法,好像有burp的sqlmap插件)或浏览器插件的方式读URL,然后自动喂给后端,只管看结果就行了。

关于sqlmapapi

这个东西好像没啥资料,翻了翻网上其他人的文章,从源码里找到了几个用于交互的方法:

# 用户方法
@get("/task/new") Create new task ID. 
@get("/task/<taskid>/delete") Delete own task ID. 

# 管理函数
@get("/admin/<taskid>/list") List task pull. 
@get("/admin/<taskid>/flush") Flush task spool (delete all tasks). 

# 核心交互函数
@get("/option/<taskid>/list") List options for a certain task ID
@post("/option/<taskid>/get") Get the value of an option (command line switch) for a certain task ID
@post("/option/<taskid>/set") Set an option (command line switch) for a certain task ID
@post("/scan/<taskid>/start") Launch a scan
@get("/scan/<taskid>/stop") Kill a scan
@get("/scan/<taskid>/status") Return status of a scan
@get("/scan/<taskid>/data") Retrieve the data of a scan
@get("/scan/<taskid>/log/<start>/<end>") Retrieve a subset of log messages
@get("/scan/<taskid>/log") Retrieve the log messages
@get("/download/<taskid>/<target>/<filename:path>") Download a certain file from the file system

具体的用法也从源码中的注释中摘录了出来,这些方法都在sqlmap/lib/utils/api.py中,可以自己去详细翻阅。

开启sqlmapapi

sqlmapapi-1
从图中可以看到,我们需要使用-s参数让sqlmapapi以server模式运行。有时需要指定-H和-P参数,这里我们只使用-s参数
sqlmapapi-2
可以看到sqlmapapi运行在8775端口,后端使用的bottle,一个python web框架,十分精简。Admin ID是用来管理task所用的,每次开启sqlmapapi都会改变,可以通过修改源码的方式将其固定,或是写入文件供其他程序读取。

基本用法

这些api的使用方法还是比较简单的,注意其中有几个api是post的方法。调用过程大概如下:

  1. 创建新任务
  2. 指定参数
  3. 开始扫描
  4. 轮询扫描是否结束
  5. 如果结束则获取结果

1 创建新任务

使用@get("/task/new")方法创建一个新的任务。
sqlmapapi-3
返回信息中的taskid就是刚刚创建的任务的id,是我们后面需要用的id。

2 指定参数

使用@post("/option/<taskid>/set")方法设置参数,注意是POST方法,使用GET方法的话会返回405状态码(Method not allowed)
sqlmapapi-4
在这里设置一下测试的URL,使用sqli-labs做测试。如果想获取全部的设置列表,可以使用@get("/option//list")来获取,如果想获取指定的某项设置,可以使用@post("/option//get")来获取。
上图中的URL有误,应为:http://127.0.0.1/sqli-labs/Less-1/?id=1

3 开始扫描

使用@post("/scan/<taskid>/start")方法开始扫描。
sqlmapapi-5
在开始的时候也可以指定参数,也可以将上一步中的设置扫描URL放在这里,发送一次请求就可以。

r = requests.post('http://127.0.0.1:8775/scan/4d0a2f20778d9f6a/start', data=json.dumps({'url':'http://127.0.0.1/sqli-labs/Less-1/?id=1'}), headers={'Content-Type':'application/json'})

4 获取探测是否结束

使用@get("/scan/<taskid>/status")获取探测是否结束
sqlmapapi-6
从图中可以看到,结果是terminated,表示探测已经结束了。如果未结束,则结果为running。

5 获取探测结果

使用@get("/scan/<taskid>/data")获取探测结果,如果不能注入,则获取到的结果为空,可能是这样:

{u'data': [], u'success': True, u'error': []}

如果可以注入,则可能是下面这个样子:
sqlmapapi-7
如果想获取更多的信息,可以通过设置选项的接口来设置各种参数,例如dbs、banner、tables等。