Showing posts with label sqlmap. Show all posts
Showing posts with label sqlmap. Show all posts

Saturday, April 13, 2013

Unofficial SQLmap RESTful API documentation

This isn't comprehensive, just the most useful methods. I haven't found any docs on the API yet but wanted to play with it. :)

The full list of methods available are:
@get("/task/new")
@get("/task/<taskid>/delete")
@get("/admin/<taskid>/list")
@get("/admin/<taskid>/flush")
@get("/option/<taskid>/list")
@post("/option/<taskid>/get")
@post("/option/<taskid>/set")
@post("/scan/<taskid>/start")
@get("/scan/<taskid>/stop")
@get("/scan/<taskid>/kill")
@get("/scan/<taskid>/status")
@get("/scan/<taskid>/data")
@get("/scan/<taskid>/log/<start>/<end>")
@get("/scan/<taskid>/log")
@get("/download/<taskid>/<target>/<filename:path>")


These are the methods I have been using
GET /task/new
Response:
{
    "taskid": "1d47d7f046df1504"
}



GET /task/<task_id>/delete
Response:
{
    "success": true
}



GET /option/<task_id>/list Response:
{
    "options": {
        "crawlDepth": null, 
        "osShell": false, 
        "getUsers": false, 
        "getPasswordHashes": false, 
        "excludeSysDbs": false, 
        "uChar": null, 
        "regData": null, 
        "cpuThrottle": 5, 
        "prefix": null, 
        "code": null, 
        "googlePage": 1, 
        "query": null, 
        "randomAgent": false, 
        "delay": 0, 
        "isDba": false, 
        "requestFile": null, 
        "predictOutput": false, 
        "wizard": false, 
        "stopFail": false, 
        "forms": false, 
        "taskid": "73674cc5eace4ac7", 
        "skip": null, 
        "dropSetCookie": false, 
        "smart": false, 
        "risk": 1, 
        "sqlFile": null, 
        "rParam": null, 
        "getCurrentUser": false, 
        "notString": null, 
        "getRoles": false, 
        "getPrivileges": false, 
        "testParameter": null, 
        "tbl": null, 
        "charset": null, 
        "trafficFile": null, 
        "osSmb": false, 
        "level": 1, 
        "secondOrder": null, 
        "pCred": null, 
        "timeout": 30, 
        "firstChar": null, 
        "updateAll": false, 
        "binaryFields": false, 
        "checkTor": false, 
        "aType": null, 
        "direct": null, 
        "saFreq": 0, 
        "tmpPath": null, 
        "titles": false, 
        "getSchema": false, 
        "identifyWaf": false, 
        "checkWaf": false, 
        "regKey": null, 
        "limitStart": null, 
        "loadCookies": null, 
        "dnsName": null, 
        "csvDel": ",", 
        "oDir": null, 
        "osBof": false, 
        "invalidLogical": false, 
        "getCurrentDb": false, 
        "hexConvert": false, 
        "answers": null, 
        "host": null, 
        "dependencies": false, 
        "cookie": null, 
        "proxy": null, 
        "regType": null, 
        "optimize": false, 
        "limitStop": null, 
        "mnemonics": null, 
        "uFrom": null, 
        "noCast": false, 
        "testFilter": null, 
        "eta": false, 
        "threads": 1, 
        "logFile": null, 
        "os": null, 
        "col": null, 
        "rFile": null, 
        "verbose": 1, 
        "aCert": null, 
        "torPort": null, 
        "privEsc": false, 
        "forceDns": false, 
        "getAll": false, 
        "api": true, 
        "url": null, 
        "invalidBignum": false, 
        "regexp": null, 
        "getDbs": false, 
        "freshQueries": false, 
        "uCols": null, 
        "smokeTest": false, 
        "pDel": null, 
        "wFile": null, 
        "udfInject": false, 
        "tor": false, 
        "forceSSL": false, 
        "beep": false, 
        "saveCmdline": false, 
        "configFile": null, 
        "scope": null, 
        "dumpAll": false, 
        "torType": "HTTP", 
        "regVal": null, 
        "dummy": false, 
        "commonTables": false, 
        "search": false, 
        "skipUrlEncode": false, 
        "referer": null, 
        "liveTest": false, 
        "purgeOutput": false, 
        "retries": 3, 
        "extensiveFp": false, 
        "dumpTable": false, 
        "database": "/tmp/sqlmapipc-EmjjlQ", 
        "batch": true, 
        "headers": null, 
        "flushSession": false, 
        "osCmd": null, 
        "suffix": null, 
        "dbmsCred": null, 
        "regDel": false, 
        "shLib": null, 
        "nullConnection": false, 
        "timeSec": 5, 
        "msfPath": null, 
        "noEscape": false, 
        "getHostname": false, 
        "sessionFile": null, 
        "disableColoring": true, 
        "getTables": false, 
        "agent": null, 
        "lastChar": null, 
        "string": null, 
        "dbms": null, 
        "tamper": null, 
        "hpp": false, 
        "runCase": null, 
        "osPwn": false, 
        "evalCode": null, 
        "cleanup": false, 
        "getBanner": false, 
        "profile": false, 
        "regRead": false, 
        "bulkFile": null, 
        "safUrl": null, 
        "db": null, 
        "dumpFormat": "CSV", 
        "alert": null, 
        "user": null, 
        "parseErrors": false, 
        "aCred": null, 
        "getCount": false, 
        "dFile": null, 
        "data": null, 
        "regAdd": false, 
        "ignoreProxy": false, 
        "getColumns": false, 
        "mobile": false, 
        "googleDork": null, 
        "sqlShell": false, 
        "pageRank": false, 
        "tech": "BEUSTQ", 
        "textOnly": false, 
        "commonColumns": false, 
        "keepAlive": false
    }
}



POST /option/<task_id>/set -- Content-Type:application/json
Request:
{ "msfPath" : "/path/to/metasploit/framework" }
Response:
{
    "success": true
}



POST /scan/<task_id>/start -- Content-Type:application/json
Request (optional):
{ "url" : "192.168.1.250/index.php?wut=injectable" }
Response:
{
    "engineid": 16784, 
    "success": true
}



GET /scan/<task_id>/log
Response:
{
    "log": [
        {
            "message": "testing connection to the target URL", 
            "level": "INFO", 
            "time": "14:11:23"
        }, 
        {
            "message": "testing if the target URL is stable. This can take a couple of seconds", 
            "level": "INFO", 
            "time": "14:11:24"
        }, 
        {
            "message": "target URL is stable", 
            "level": "INFO", 
            "time": "14:11:26"
        }, 
        {
            "message": "no parameter(s) found for testing in the provided data (e.g. GET parameter 'id' in 'www.site.com/index.php?id=1')", 
            "level": "CRITICAL", 
            "time": "14:11:26"
        }, 
        {
            "message": "testing connection to the target URL", 
            "level": "INFO", 
            "time": "14:17:30"
        }, 
        {
            "message": "testing if the target URL is stable. This can take a couple of seconds", 
            "level": "INFO", 
            "time": "14:17:31"
        }, 
        {
            "message": "target URL is not stable. sqlmap will base the page comparison on a sequence matcher. If no dynamic nor injectable parameters are detected, or in case of junk results, refer to user's manual paragraph 'Page comparison' and provide a string or regular expression to match on", 
            "level": "WARNING", 
            "time": "14:17:33"
        }, 
        {
            "message": "testing if GET parameter 'PAGE' is dynamic", 
            "level": "INFO", 
            "time": "14:17:33"
        }, 
        {
            "message": "confirming that GET parameter 'PAGE' is dynamic", 
            "level": "INFO", 
            "time": "14:17:33"
        }, 
        {
            "message": "GET parameter 'PAGE' does not appear dynamic", 
            "level": "WARNING", 
            "time": "14:17:33"
        }, 
        {
            "message": "reflective value(s) found and filtering out", 
            "level": "WARNING", 
            "time": "14:17:33"
        }, 
        {
            "message": "heuristic (basic) test shows that GET parameter 'PAGE' might not be injectable", 
            "level": "WARNING", 
            "time": "14:17:33"
        }, 
        {
            "message": "testing for SQL injection on GET parameter 'PAGE'", 
            "level": "INFO", 
            "time": "14:17:34"
        }, 
        {
            "message": "testing 'AND boolean-based blind - WHERE or HAVING clause'", 
            "level": "INFO", 
            "time": "14:17:34"
        }, 
        {
            "message": "testing 'MySQL >= 5.0 AND error-based - WHERE or HAVING clause'", 
            "level": "INFO", 
            "time": "14:17:34"
        }, 
        {
            "message": "testing 'PostgreSQL AND error-based - WHERE or HAVING clause'", 
            "level": "INFO", 
            "time": "14:17:34"
        }, 
        {
            "message": "testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause'", 
            "level": "INFO", 
            "time": "14:17:34"
        }, 
        {
            "message": "testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'", 
            "level": "INFO", 
            "time": "14:17:35"
        }, 
        {
            "message": "testing 'MySQL inline queries'", 
            "level": "INFO", 
            "time": "14:17:35"
        }, 
        {
            "message": "testing 'PostgreSQL inline queries'", 
            "level": "INFO", 
            "time": "14:17:35"
        }, 
        {
            "message": "testing 'Microsoft SQL Server/Sybase inline queries'", 
            "level": "INFO", 
            "time": "14:17:35"
        }, 
        {
            "message": "testing 'Oracle inline queries'", 
            "level": "INFO", 
            "time": "14:17:35"
        }, 
        {
            "message": "testing 'SQLite inline queries'", 
            "level": "INFO", 
            "time": "14:17:35"
        }, 
        {
            "message": "testing 'MySQL > 5.0.11 stacked queries'", 
            "level": "INFO", 
            "time": "14:17:36"
        }, 
        {
            "message": "testing 'PostgreSQL > 8.1 stacked queries'", 
            "level": "INFO", 
            "time": "14:17:36"
        }, 
        {
            "message": "testing 'Microsoft SQL Server/Sybase stacked queries'", 
            "level": "INFO", 
            "time": "14:17:36"
        }, 
        {
            "message": "testing 'MySQL > 5.0.11 AND time-based blind'", 
            "level": "INFO", 
            "time": "14:17:36"
        }, 
        {
            "message": "testing 'PostgreSQL > 8.1 AND time-based blind'", 
            "level": "INFO", 
            "time": "14:17:37"
        }, 
        {
            "message": "testing 'Microsoft SQL Server/Sybase time-based blind'", 
            "level": "INFO", 
            "time": "14:17:37"
        }, 
        {
            "message": "testing 'Oracle AND time-based blind'", 
            "level": "INFO", 
            "time": "14:17:37"
        }, 
        {
            "message": "testing 'MySQL UNION query (NULL) - 1 to 10 columns'", 
            "level": "INFO", 
            "time": "14:17:37"
        }, 
        {
            "message": "testing 'Generic UNION query (NULL) - 1 to 10 columns'", 
            "level": "INFO", 
            "time": "14:17:38"
        }, 
        {
            "message": "using unescaped version of the test because of zero knowledge of the back-end DBMS. You can try to explicitly set it using option '--dbms'", 
            "level": "WARNING", 
            "time": "14:17:38"
        }, 
        {
            "message": "GET parameter 'PAGE' is not injectable", 
            "level": "WARNING", 
            "time": "14:17:39"
        }, 
        {
            "message": "all tested parameters appear to be not injectable. Try to increase '--level'/'--risk' values to perform more tests. Also, you can try to rerun by providing either a valid value for option '--string' (or '--regexp')", 
            "level": "CRITICAL", 
            "time": "14:17:40"
        }, 
        {
            "message": "HTTP error codes detected during run:\n404 (Not Found) - 183 times", 
            "level": "WARNING", 
            "time": "14:17:40"
        }
    ]
}

GET /scan/<task_id>/status
Response:
{
    "status": "terminated", 
    "returncode": 0
}

Sunday, May 20, 2012

Automating SQLMap with data from wapiti

Wapiti is really fast at finding possible sql injection points in a web application or website. SQLMap is great at figuring out how to exploit these possible injection points. The following script runs Wapiti on a host to find possible injection points, then passes that data to SQLMap to try and exploit. Tested on BadStore and running SVN latest of both Wapiti and SQLMap. You can play around with the arguments I am passing to SQLMap and make the scans a bit more thorough, but at the expense of speed.
#!/usr/bin/env ruby
 
require 'active_support/secure_random'
require 'rexml/document'
 
wapiti_path = '/home/bperry/tools/wapiti/trunk/src/'
sqlmap_path = '/home/bperry/tools/sqlmap/'
 
wapiti_report_path = '/tmp/wapiti_report_' + SecureRandom.uuid + '.xml'
 
remote_host = ARGV[0]
 
p "Running wapiti..."
`#{wapiti_path}wapiti.py #{ARGV[0]} -f xml -o #{wapiti_report_path}`
 
p "Report saved to #{wapiti_report_path}"
 
p "Parsing results"
 
results = []
 
report = ::File.open(wapiti_report_path, "rb")
doc = REXML::Document.new report.read
 
doc.elements.each('/report/bugTypeList/bugType') do |element|
        bug_type = element.attributes["name"]
 
        next if bug_type != "SQL Injection"
 
        p "Parsing " + bug_type
 
        result = {}
        element.elements.each("bugList/bug") do |bug|
                result[:type] = bug_type
               
                bug.elements.each do |child|
                        if child.name == "url"
                                result[:url] = child.text
                        elsif child.name == "parameter"
                                result[:parameter] = child.text
                        end
                end
                results << result
                result = {}
        end
end
 
results.each do |result|
        next if result[:type] !~ /SQL Injection/
        p "Running sqlmap"
       
        if result[:url].index(result[:parameter])
                url = result[:url].gsub("%BF%27%22%28", "abcd")
       
                params = result[:url].split("?")[1].split("&")
 
                skipped_params = []
                params.each do |param|
                        skipped_params << param.split("=")[0] if not param.index("%BF%27%22%28")
                end
                       
                p "Running GET sql injection test on url: " + url
                sqlmap_command = "#{sqlmap_path}sqlmap.py -u \"#{url}\" --smart --skip=\"#{skipped_params.join(",")}\" --technique=EUS --flush-session --fresh-queries --level=2 --batch"
                out = `#{sqlmap_command}`
                printf out
        else
                url = result[:url]
                p "Running POST sql injection test on url: " + url
                p "With data: " + result[:parameter]
 
                parameter = result[:parameter].gsub("%BF%27%22%28", "abcd")
 
                params = result[:parameter].split("&")
 
                skipped_params = []
                params.each do |param|
                        skipped_params << param.split("=")[0] if not param.index("%BF%27%22%28")
                end
 
                sqlmap_command = "#{sqlmap_path}sqlmap.py -u \"#{url}\" --data=\"#{parameter}\"  --skip=\"#{skipped_params.join(",")}\" --smart --technique=EUS --flush-session --fresh-queries --level=2 --batch"
                p sqlmap_command
                sqlmap_output = `#{sqlmap_command}`
               
                printf sqlmap_output
        end
end