Saltar al contenido

Integrating SQLMap in CI/CD with OWASP DefectDojo

agosto 11, 2019

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:

Executing our customized sqlmap.

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.

Go to the option to create a new Test Type.
Create a new Test Type «SQLMap Scan».

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="&amp;", 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!