首页 > 代码库 > 利用sqlmapapi打造自动化SQL注入工具
利用sqlmapapi打造自动化SQL注入工具
友链:http://www.freebuf.com/sectool/74445.html
0×01 前言
各位看官看到标题吐槽帝就开始了:已经有了各种各样的注入工具,为什么还要手工打造一个?
事实上,做为一名苦逼乙方测试工程师以及漏洞盒子屌丝白帽子 ,在疲于应对各种死缠滥打的甲方以及成堆的web测试需求时,我经常遇到以下场景:
(1)有大批量的网站需要检测的场景
乙方工程师工作辛苦劳累从来都不抱怨,有项目一定都是最能抗的,向无数奋斗在一线的乙方工程师致敬!
(2)系统内部业务复杂可能会存在众多测注入点
很多系内部业务复杂,查询功能较多,此时可能会较多的注入点,手工测试时间紧,容易纰漏,此时需要一个提取burpsuit的history记录的工具,来自动帮你分析问题所在。
(3)漏洞盒子测试时间需要争分夺秒
在漏洞盒子进行项目安全测试时,时间就是金钱——谁能以更快的速度挖到漏洞谁就能拿到更多的奖励.
系统框架组成:
[核心检测引擎]Sqlmap[核心信息收集引擎]Python代理[数据库]mysql[Web展示]Bootstrap主题+JQuery(Ajax)
0×02 系统设计过程
先介绍一下Sqlmapi及其用法:
Sqlmapapi在sqlmap中是自带的功能,可能许多人都忽略了.当我们下载到sqlmap源码的适合会发现在根目录下还有一个sqlmapapi.py的文件,此时,使用命令python sqlmapapi.py -s -H 127.0.0.1 -p 8889就可以启动了
启动后会生成一个Admin ID,这个AdminID就是我们用于管理Sqlmapapi使用管理id
但是注意,在新建sqlmap任务的时候,这个AdminID没有什么作用,只是在查看任务和删除任务的时候才有用.这个AdminID也是后面PHP程序对sqlmapapi进行管理的时候使用的AdminID,但是为了方便,我将这一部分代码进行了重写,使得生成的AdminID是唯一的/或者写入一个特定的文件让PHP去读取。
使用的时候需要使用HTTP协议与该API进行交互。新建一个空任务,然后再向该任务POST sql注入的相关参数来启动该任务,/task/new为新建任务,/scan/taskid/start为启动任务接口。
需要使用POST方法向该接口提交json格式的数据,详情可参考后文的req2sqlmap.py
有了sqlmapapi的背景知识后,我们的打造自己的自动sql注入工具之路就开始了:
这款工具后台由Python代理实现且支持Https,启动sqlmapapi进程后,Python代理会截取http请求并将该请求发送给Sqlmapapi,Sqlmap就开始进行注入尝试,Web界面部分负责生成最后的结果便于测试人员直接分析,Web部分由PHP负责监控sqlmapapi并获取注入结果保存入mysql数据库,此处我写了一个单独的类库sqlmapapi.class.php处理,只要实例化一个对象并传入固定的adminid(sqlmap的管理id)就可以对sqlmapapi进程进行管理。
sqlmapapi.class.php代码如下:
<?phpclass sqlmapapi { private $adminid=‘‘; private $sqlmapapi=SQLMAPAPI; private $tasknumber=0; function __construct($adminid=null) { if($adminid!=null){ $this->adminid=$adminid; } $this->AutoTask(); return 0; } //自动处理所有任务 function AutoTask(){ $tasklistarr= $this->getTasklist(); foreach ($tasklistarr as $taskid) { //查询结果并入库 $this->Task2db($taskid); } return TRUE; } function getTasklist($adminid=null){ if($adminid==null){ $adminid=$this->adminid; } $jsonres=$this->doGet("/admin/".$this->adminid."/list"); $jsonobj= json_decode($jsonres); $tasklist=$jsonobj->tasks; $tasknumber=$jsonobj->tasks_num; $this->tasknumber=$tasknumber; print_r($tasklist); return $tasklist; } function flushTask($adminid=null){ if($adminid==null){ $adminid=$this->adminid; } $jsonres=$this->doGet("/admin/".$this->adminid."/list"); $res= json_decode($jsonres); if($res[‘success‘]==true){ return TRUE; }else{ return FALSE; } } function Task2db($taskid){ $jsonres= $this->