标签:
友链: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代码如下:
<?php
class 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->doGet