<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    原文地址:http://drops.wooyun.org/tips/12681

                    0x00 簡介


                    分布式掃描好多人都寫過,例如:

                    burp的sqli插件

                    Matt前輩的http://zone.wooyun.org/content/24172

                    豬豬俠前輩的http://zone.wooyun.org/content/21289

                    Ver007前輩的http://zone.wooyun.org/content/24333

                    0x_Jin前輩的http://zone.wooyun.org/content/24341

                    填上個坑填的心煩,想著也造個輪子,忙活了幾天,寫了一個簡單的雛形

                    Github: https://github.com/liuxigu/ScanSqlTestchromeExtensions

                    在此感謝bstaint、sunshadow的幫助

                    Sqlmapapi本來就是為了實現分布式注入寫的,在被動掃描的基礎上 加節點就實現分布式了

                    最初想的是用chrome插件來實現代碼注入

                    1. 用js來獲取<a>標簽的同域url,用js是防止一些站的反爬蟲措施,還有對于a href指向相對鏈接的的情況,用js會自動補全域名.
                    2. Chrome webRequest API OnBeforeRequest獲取即將請求的url

                    設想獲取url后 喂給sqlmapapi, 將能注入的url寫入到文本里,js 的 FileSystemObject gg.. 本來是準備用php實現文件io的…

                    talk is cheap show me the code.

                    0x01 Chrome manifest.json


                    #!js
                    {  
                      "name": "sqlInjectionTest",  
                      "version": "0.1",  
                      "description": "you know...",  
                      "manifest_version": 2,
                    
                      "content_scripts": [{
                        "matches":["*://*/*"],
                        "js": ["inject.js"]
                        }],
                    
                      "permissions": [
                        "*://*/*",
                        "webRequest", 
                        "webRequestBlocking"
                        ],
                    
                    
                      "browser_action": {  
                        "default_icon": "icon.png" ,
                        "default_title": "scan url inject"
                        }  
                    }
                    

                    0x02 Sqlmapapi.py code


                    一:固定Admin Id

                    Sqlmapapi啟動后 是這樣子:

                    #!bash
                    [email protected]:~/桌面/sqlmap# python sqlmapapi.py -s
                    [22:02:17] [INFO] Running REST-JSON API server at '127.0.0.1:8775'..
                    [22:02:17] [INFO] Admin ID: 7c4be58c7aab5f38cb09eb534a41d86b
                    [22:02:17] [DEBUG] IPC database: /tmp/sqlmapipc-5JVeNo
                    [22:02:17] [DEBUG] REST-JSON API server connected to IPC database
                    

                    AdminID每次都會變,這樣導致任務管理不方便,我們更改一下sqlmap的源碼

                    定位到/sqlmap/lib/utils/api.py 的server函數

                    p1

                    看到644行的os.urandom,直接改成一個固定字符串就行了

                    例如 我改成了DataStore.admin_id = hexencode('wooyun')

                    以后就固定是Admin ID: 776f6f79756e

                    還有個更簡單的辦法

                    p2

                    p3

                    return True

                    二:sqlmap掃描任務結束自動寫入文本

                    判斷當前任務是否掃描完成 訪問http://127.0.0.1:8775/admin/ss/list

                    #!python
                    {
                        "tasks": {
                            "4db4e3bd4410efa9": "terminated"
                        }, 
                        "tasks_num": 1, 
                        "success": true
                    }
                    

                    Terminated代表任務已終止,

                    http://127.0.0.1:8775/scan/4db4e3bd4410efa9/data

                    #!python
                    {
                        "data": [], 
                        "success": true, 
                        "error": []
                    }
                    

                    “data”存放了sqlmapapi檢測時用的payload, “data”非空就代表當前任務是可注入的,sqlmapapi并沒有自帶回調方式…輪詢浪費開銷,這里我選擇修改源碼

                    p4

                    定位到scan_data函數 ,可以看到,假如可注入,就會從data表檢索數據并寫入到json_data_message,表名為data, 代碼向上翻,定位到將數據入庫的代碼

                    在StdDbOut類里,第230行,在insert前 插入

                    #!python
                    with open('/tmp/'+str(self.taskid)+'.txt','a+') as fileHandleTemp,\
                                        closing(requests.get('http://127.0.0.1:8775/option/'+str(self.taskid)+'/list', stream=True)) as reqTemp:
                    
                                            fileHandleTemp.write(
                                                    json.loads(reqTemp.text)['options']['url']+'\n'+
                                                    json.loads(reqTemp.text)['options']['data']+'\n'+
                                                    json.loads(reqTemp.text)['options']['Cookie']+'\n'+
                                                    json.loads(reqTemp.text)['options']['Referer']+'\n'
                                                )
                    

                    記得加載三個模塊

                    #!python
                    import json
                    import requests
                    from contextlib import closing
                    

                    本意是獲取能注入的url寫入到文本里,在源碼里沒找到繼承這個類的地方…懶得去找了

                    訪問http://127.0.0.1:8775/option/id/list

                    #!python
                    Response:
                    {
                        "options": {
                            ......
                            "url": http://58.59.39.43:9080/wscgs/xwl.do?smid=02&bgid=01&bj=8
                            ……
                            }
                        "success":{
                            ...
                        }
                    

                    p5

                    0x03 inject.js code


                    1.

                    那么要過濾掉javascript::偽協議和無sql操作的href

                    看到有這樣寫的:

                    #!js
                    if re.match('^(javascript|:;|#)',_url) or _url is None or re.match('.(jpg|png|bmp|mp3|wma|wmv|gz|zip|rar|iso|pdf|txt|db)$',_url):
                    

                    甚至這樣的:

                    #!js
                    filename=urlpath[i+1:len(urlpath)]
                    ????print?"Filename:?",filename
                    ????res=filename.split('.')
                    ????if(len(res)>1):
                    ????????extname=res[-1]
                    ????????ext=["css","js","jpg","jpeg","gif","png","bmp","html","htm","swf","ico","ttf","woff","svg","cur","woff2"]
                    ????????for?blacklist?in?ext:
                    ????????????if(extname==blacklist):
                    ????????????????return?False
                    

                    這兩種方式假如遇到這樣的url: http://xxx/aaa/ ,就會造成無意義的開銷.

                    判斷是否可以進行get注入測試,其實只需要

                    str.match(/[\?]/); 無get參數的頁面會返回null

                    我們這樣寫: /http(s)?:\/\/ ([\w\W-]+\/)+ ([\w\W]+\?)+/;

                    再加上同域過濾,js中沒有php那樣可以在字符串中用{}引用變量的值,要在正則中拼接變量需要用RegExp對象:

                    #!js
                    var urlLegalExpr="http(s)?:\/\/"+document.domain+"([\\/\\w\\W]+\\?)+";
                    var objExpr=new RegExp(urlLegalExpr,"gi");
                    

                    2.

                    Js是在http response后執行的,要進行post注入,必須在OnBeforeRequest之前獲取,chrome提供了相關的api,這個沒什么可說的 ,看代碼吧

                    inject.js code:

                    #!js
                    main();
                    
                    function main(){
                    
                        var urlLegalExpr="http(s)?:\/\/"+document.domain+"([\\/\\w\\W]+\\?)+";
                        var objExpr=new RegExp(urlLegalExpr,"gi");
                        urlArray=document.getElementsByTagName('a');
                    
                        for(i=0;i<urlArray.length;i++){
                            if(objExpr.test(urlArray[i].href)){
                                sqlScanTest(urlArray[i].href);
                            }
                        }
                    
                    }
                    
                    function sqlScanTest(url,payload){
                    
                    
                        sqlmapIpPort="http://127.0.0.1:8775";
                        var payload=arguments[1] ||'{"url": "'+url+'","User-Agent":"wooyun"}';
                    
                        Connection('GET',sqlmapIpPort+'/task/new','',function(callback){
                    
                                var response=JSON.parse(callback);      
                    
                                if(response.success){
                                    Connection('POST',sqlmapIpPort+'/scan/'+response.taskid+'/start',payload,function(callback){
                                            var responseTemp=JSON.parse(callback);
                                            if(!responseTemp.success){
                                                alert('url send to sqlmapapi error');
                                            }
                                        }
                                    )
                                }
                                else{
                                    alert('sqlmapapi create task error');
                                }
                            }
                        )
                    }
                    
                    
                    function Connection(Sendtype,url,content,callback){ 
                        if (window.XMLHttpRequest){ 
                            var xmlhttp=new XMLHttpRequest(); 
                        } 
                        else{ 
                            var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
                        } 
                        xmlhttp.onreadystatechange=function(){ 
                            if(xmlhttp.readyState==4&&xmlhttp.status==200) 
                            { 
                                callback(xmlhttp.responseText); 
                            } 
                        } 
                        xmlhttp.open(Sendtype,url,true); 
                        xmlhttp.setRequestHeader("Content-Type","application/json"); 
                        xmlhttp.send(content); 
                    } 
                    
                    
                    
                    function judgeUrl(url){
                        var objExpr=new RegExp(/^http(s)?:\/\/127\.0\.0\.1/);
                        return objExpr.test(url);
                    }
                    
                    var payload={};
                    
                    chrome.webRequest.onBeforeRequest.addListener(
                        function(details){ 
                    
                            if(details.method=="POST" && !judgeUrl(details.url)){
                                var saveParamTemp="";
                                for(var i in details.requestBody.formData){
                    
                                    saveParamTemp+="&"+i+"="+details.requestBody.formData[i][0];
                                }
                                saveParamTemp=saveParamTemp.replace(/^&/,'');
                                //console.log(saveParamTemp);
                                payload["url"]=details.url;
                                payload["data"]=saveParamTemp;
                            }
                            //console.log(details);
                        },
                        {urls: ["<all_urls>"]},
                        ["requestBody"]);
                    
                    
                    chrome.webRequest.onBeforeSendHeaders.addListener(
                        function(details) {
                            if(details.method=="POST" && !judgeUrl(details.url)){
                                //var cookieTemp="",uaTemp="",refererTemp="";
                    
                                for(var ecx=0;ecx<details.requestHeaders.length;ecx++){
                    
                    
                                    switch (details.requestHeaders[ecx].name){
                                        case "Cookie":
                                            payload["Cookie"]=details.requestHeaders[ecx].value;
                                            break;
                                        case "User-Agent":
                                            payload["User-Agent"]=details.requestHeaders[ecx].value;
                                            break;
                                        case "Referer":
                                            payload["Referer"]=details.requestHeaders[ecx].value;
                                            break;
                                        default:
                                            break;
                                    }
                    
                                }
                                sqlScanTest("test",JSON.stringify(payload));
                                return {requestHeaders: details.requestHeaders};
                            }
                    
                        },
                        {urls: ["<all_urls>"]},
                        ["requestHeaders"]);
                    

                    Sqlmap能用的選項都可以在http://ip:port/option/taskid/list里查看,用到哪項寫到payload里就行了,最好是做成實時刷新代理,之前寫過爬蟲的時候寫過一個python版的,有空的話會改成js加入到inject.js里.

                    p6

                    0x04 參考文獻



                    p7

                    馬上2016了,希望在年前把上個坑填完

                    也祝各位心想事成

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频