Pr0mise · 2016/02/05 10:10
0 x00 profile
Distributed scanning has been written about by many people, for example:
Burp sqLI plugin
Matt predecessors zone.wooyun.org/content/241…
Pigpigman predecessors zone.wooyun.org/content/212…
Ver007 predecessors zone.wooyun.org/content/243…
0 x_jin predecessors zone.wooyun.org/content/243…
Fill up a pit fill of upset, thinking also build a wheel, busy for a few days, wrote a simple rudiment
Making: github.com/liuxigu/Sca…
Thanks to Bstaint, Sunshadow for their help
Sqlmapapi is originally for the realization of distributed injection write, add nodes on the basis of passive scan to achieve distributed
The original idea was to use the Chrome plugin for code injection
- Get it in js
<a>
Tags of the same domain URL, using JS is to prevent some anti-crawler measures, and for the case of a href pointing to relative links, using JS will automatically complete the domain name. - The Chrome webRequest API OnBeforeRequest gets the URL to be requested
Imagine getting the URL and feeding it to sqlMAPAPI, write the url that can be injected into the text, FileSystemObject gg.. Originally was ready to use PHP file 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" } }Copy the code
0x02 Sqlmapapi.py code
One: The Admin Id is fixed
Sqlmapapi starts like this:
#! bash[email protected]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 databaseCopy the code
AdminID changes every time, which makes task management inconvenient. Let’s change the source code of SQLMap
Locate the server function at /sqlmap/lib/utils/api.py
Look at Os. urandom on line 644 and just change it to a fixed string
For example, I changed it to datastore. admin_id = hexencode(‘wooyun’)
Admin ID: 776F6F79756E
There’s an easier way
return True
Two: Text is automatically written after the SQLMap scan task ends
Judge whether the current task the scan is complete to http://127.0.0.1:8775/admin/ss/list
#! python { "tasks": { "4db4e3bd4410efa9": "terminated" }, "tasks_num": 1, "success": true }Copy the code
Terminated indicates that the task is Terminated.
http://127.0.0.1:8775/scan/4db4e3bd4410efa9/data
#! python { "data": [], "success": true, "error": [] }Copy the code
“Data” stores the payload used by the sqlmapapi. If the “data” is not empty, it indicates that the current task is injectable. Polling is a waste of overhead. Here I choose to modify the source code
Navigate to the scan_data function and see that, if injectable, it retrieves the data from the data table and writes it to jSON_data_message, named DATA, and scrolls up to the code that put the data into the library
In the StdDbOut class, line 230, before 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' )Copy the code
Remember to load three modules
#! python import json import requests from contextlib import closingCopy the code
I can’t find a place to inherit this class in the source code… I’m too lazy to look
Go to 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":{ ... }Copy the code
0x03 inject.js code
1.
Filter out javascript:: protocols and href with no SQL operations
I saw this:
#! 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):Copy the code
Even this:
#! 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 FalseCopy the code
Both methods can cause meaningless overhead if you encounter a URL like http://xxx/aaa/.
To determine if you can do get injection tests, you just need to
str.match(/[\?] /); Pages with no GET parameter return NULL
Let’s write: / HTTP (s)? :\/\/ ([\w\W-]+\/)+ ([\w\W]+\?) + /;
In addition to local filtering, js does not have PHP’s way of referring to the value of a variable in a string with {}. To concatenate variables in a re, use the RegExp object:
#! js var urlLegalExpr="http(s)? :\/\/"+document.domain+"([\\/\\w\\W]+\\?) + "; var objExpr=new RegExp(urlLegalExpr,"gi");Copy the code
2.
Javascript is executed after HTTP response. To do post injection, you must get it before OnBeforeRequest. Chrome provides an API for this
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"]);Copy the code
Sqlmap can use options can check in http://ip:port/option/taskid/list, which use written content in the line, it is best to make it real time refresh agent, wrote the crawler written before a python version, If free, it will change to JS and add inject.js.
0x04 References
- The mass scanning using sqlmapapi. Py practice drops.wooyun.org/tips/6653
- The chrome webRequest API “developer.chrome.com/extensions/…
Soon 2016, hope to fill the last hole before the year
I wish you all the best