Guía rápida:
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
Resultado:
En esta guía veremos cómo modificar la famosa tool de explotación de vulnerabilidades SQL para almacenar de manera automática los resultados en OWASP DefectDojo (el gestor de vulnerabilidades open-source de OWASP).
Es necesario crear un nuevo Test Type en DefectDojo al que llaméis «SQLMap Scan». Esto sólo lo realizaremos una vez.
A partir de aqui podríamos lanzar el sqlmap modificado de mi repositorio.
En caso de que queráis modificar vuestro propio sqlmap con este «add-on», estos son los pasos que he seguido:
Modificamos la librería de sqlmap que recoge los argumentos del programa (en el archivo /lib/parse/cmdline.py) y le añadimos uno nuevo, después de la línea 716 (opción –wizard):
miscellaneous.add_argument("--engagement-dojo", dest="engagementDojo", help="Engagement ID from DefectDojo to upload results")
Después modificamos los controladores (en el archivo /lib/controller/controller.py) y insertamos la siguiente función a la que he llamado _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)
La insertamos justo antes de la función _showInjections(), que se encargará de lanzarla cuando le pasemos a sqlmap el nuevo argumento –engagement-dojo.
Para que lance nuestra función añadimos una condición dentro de _showInjections() (línea 168).
def _showInjections(): if conf.wizard and kb.wizardMode: kb.wizardMode = False if conf.engagementDojo: _createDojoFindings()
Ahora la pregunta es, cómo sabe sqlmap a que DefectDojo enviar las vulnerabilidades encontradas?
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]
Al iniciar estas variables de entorno con los datos de nuestro DefectDojo, sqlmap nos enviará las vulnerabilidades al mismo. Si tienes Windows en lugar de ‘export’, usa ‘SET’.
Por último instalamos la librería defectdojo_api de mi repositorio. Y realizamos una inyección SQL a 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
Tras encontrar la inyección, se nos crea automáticamente un test del tipo SQLMap Scan y lo rellena con los detalles de nuestras vulnerabilidades.
Eso es todo, espero que os haya gustado este pequeño «tweak» a esta famosa herramienta.
Nos vemos en el siguiente post!