Quick guide:
export DEFECTDOJO_HOST=[la URL de tu DefectDojo] export DEFECTDOJO_USER=[tu nombre de usuario] export DEFECTDOJO_APIKEY=[la clave de API de tu usuario] pip install git+https://github.com/kn0wm4d/defectdojo_api git clone https://github.com/kn0wm4d/sqlmap.git cd sqlmap python3 sqlmap.py -u http://testphp.vulnweb.com/AJAX/infotitle.php --cookie login=test%2Ftest --data id=1 --engagement-dojo <ID> --batch
Result:
In this guide we will see how to modify the famous tool for exploiting SQL vulnerabilities to automatically store the results in OWASP DefectDojo (the open-source vulnerability manager of OWASP).
It is necessary to create a new Test Type in DefectDojo which you call «SQLMap Scan». We will only do this once.


From here on we could launch the modified sqlmap of my repository.
In case you want to modify your own sqlmap with this add-on, these are the steps I have followed:
First, modify the sqlmap library that collects the arguments of the program (in the file /lib/parse/cmdline.py) and add a new argument, after the line 716 (–wizard option):
miscellaneous.add_argument("--engagement-dojo", dest="engagementDojo", help="Engagement ID from DefectDojo to upload results")
Then we modify the controllers (in the file /lib/controller/controller.py) and insert the following function that I have called _createDojoFindings():
def _createDojoFindings(): try: from defectdojo_api import defectdojo defect_api = defectdojo.DefectDojoAPI( os.getenv('DEFECTDOJO_HOST'), os.getenv('DEFECTDOJO_APIKEY'), os.getenv('DEFECTDOJO_USER'), debug=False) except ImportError: criticalMsg = "The DefectDojo library is not installed. Install it with 'pip install git+https://github.com/kn0wm4d/defectdojo_api.git'." logger.critical(criticalMsg) return None except TypeError: criticalMsg = "The DefectDojo environment variables are not set." logger.critical(criticalMsg) return None # Get Engagement from DefectDojo engagement = defect_api.get_engagement(conf.engagementDojo) if engagement.response_code == -1: criticalMsg = "This DefectDojo Engagement doesn\'t exist. " logger.critical(criticalMsg) return None # Get the Product ID related to this Engagement product_id = re.match('/api/v1/products/(.*)/', engagement.data['product'])[1] # List all tests on this engagement tests = defect_api.list_tests(engagement_in=engagement.data['id']) # Get list of SQLMap Tests on this engagement tests_sqlmap = [test for test in tests.data['objects'] if test['test_type'] == "SQLMap Scan"] if any(tests_sqlmap): # If an SQLMap Test exists, get the first one test_id = tests_sqlmap[0]['id'] if not any(tests_sqlmap): # If not, create an SQLMap test for this engagement test_type = defect_api.list_test_types(name="SQLMap Scan") if test_type.count() > 0: # Get SQLMap Test Type ID test_type = test_type.data['objects'][0]['id'] else: # If it doesn't exist, tell the user to create it criticalMsg = "Please first create SQLMap Scan test type on DefectDojo." logger.critical(criticalMsg) return None # Finally, create the SQLMap Test in this Engagement test_id = defect_api.create_test(environment=1, target_start=engagement.data['target_start'], target_end=engagement.data['target_end'], engagement_id=engagement.data['id'], test_type=test_type).data for injection in kb.injections: for stype, sdata in injection.data.items(): title = 'SQL Injection - (%s)' % PAYLOAD.SQLINJECTION[stype] payload = agent.adjustLateValues(sdata.payload) payload = urldecode(payload, unsafe="&", spaceplus=(injection.place != PLACE.GET and kb.postSpaceToPlus)) description = 'Injection Type: %s\nVulnerable URL: %s %s\nCookie: %s\nOriginal Payload: %s\nPayload: %s' % (sdata.title.title(), injection.place, conf.url, conf.cookie, conf.data, payload) severity = "Critical" # Create the Finding on DefectDojo finding = defect_api.create_finding(title, description, severity, cwe=89, date=time.strftime("%Y-%m-%d", time.gmtime()), product_id=product_id, engagement_id=engagement.data['id'], test_id=test_id, user_id=1, impact="Integrity, Confidentiality", active="True", verified="True", mitigation="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet", references="https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet").data infoMsg = 'uploaded finding to DefectDojo: %sfinding/%s' % (os.getenv('DEFECTDOJO_HOST'), finding) logger.info(infoMsg)
We insert it just before the _showInjections() function, which will take care of launching it when we pass the new argument –engagement-dojo to sqlmap.
To launch our function we add a condition within _showInjections() (line 168).
def _showInjections(): if conf.wizard and kb.wizardMode: kb.wizardMode = False if conf.engagementDojo: _createDojoFindings()
Now the question is, how does sqlmap know to which DefectDojo sends the vulnerabilities found?
export DEFECTDOJO_HOST=[la URL de tu DefectDojo] export DEFECTDOJO_USER=[tu nombre de usuario] export DEFECTDOJO_APIKEY=[la clave de API de tu usuario]
When you start these environment variables with the data of our DefectDojo, sqlmap will send us the vulnerabilities to it. If you have Windows instead of ‘export’, use ‘SET’.
Finally we installed the defectivejo_api library of my repository. And we perform an SQL injection to http://testphp.vulnweb.com.
pip install git+https://github.com/kn0wm4d/defectdojo_api python3 sqlmap.py -u http://testphp.vulnweb.com/AJAX/infotitle.php --cookie login=test%2Ftest --data id=1 --engagement-dojo <ID> --batch
After finding the injection, we automatically create a test of the type SQLMap Scan and fill it with the details of our vulnerabilities.
That’s it, I hope you liked this little «tweak» to this famous tool.
See you in the next post!