The Acunetix API allows you to programmatically manage your Acunetix tasks, including triggering scans for targets, checking the status of your scans, and retrieving a list of vulnerabilities found by your scans. This example can serve as a primer for building such programmatic tools.

In this example, you will create a Bash script that uses cURL to make requests to the Acunetix REST API.
Every API call must be authenticated by providing the API Key in the HTTP request headers. Therefore, each request is made with the following headers:

  • Content-Type: application/json
  • X-Auth: <the_api_key>

You can get the API key from the Acunetix profile page.

Anatomy of the Script

The script has the following structure:

  • The cleanup function is a recovery function to delete the scan and target created by the script if an invalid scan status is detected:
    • The remove_scan API call requires a DELETE request to the /scans/{scan_id} endpoint; the scan ID is retrieved during the main part of the script described below
    • The remove_target API call requires a DELETE request to the /targets/{target_id} endpoint; the target ID is retrieved during the main part of the script described below
  • The starting global variables are declared to be used throughout the script:
    • MyAXURL is the base URL for your Acunetix API, which is typically:
      • On-premises: https://:3443/api/v1
      • Online: https://online.acunetix.com/api/v1
    • MyAPIKEY is the API key, which can be retrieved from the profile page
    • MyTargetURL is the URL of the target to be scanned
    • MyTargetDESC is the friendly description for the target
    • FullScanProfileID is the profile ID for the default Full Scan; this default scan profile always has a value of 11111111-1111-1111-1111-111111111111
  • The target is created:
    • The API documentation for the add_target function shows that:
      • We have to make a POST request to the /targets endpoint
      • The body should be in JSON format minimally containing 4 keys: address, description, type, criticality; in our example:
        { "address": "http://testphp.vulnweb.com/",
        "description": "Test PHP Site - created via my script",
        "type": "default",
        "criticality": 10 }
        
      • The response will also be in JSON format; the critical information we want to extract from the response is the value of the target_id key
  • The scan is scheduled:
    • The API documentation for the schedule_scan function shows that:
      • We have to make a POST request to the /scans endpoint
      • The body should be in JSON format; in our example:
        { "profile_id": "11111111-1111-1111-1111-111111111111",
        "incremental": false,
        "schedule": { "disable": false,
                      "start_date": null,
                      "time_sensitive": false },
        "user_authorized_to_scan": "yes",
        "target_id": "TargetID_from_previous_step" }
        
      • The response will be in JSON format; the critical information (the scan ID) we want to extract, however, is not delivered in the response but in the HTTP response header called Location
  • A loop is created that checks the status of the scan every 30 seconds and waits for the scan status to become completed:
    • The API documentation for the get_scan function shows that:
      • We have to make a GET request to the /scans/{scan_id} endpoint, where the scan_id is obtained from the previous step
      • The response will be in JSON format; the critical information (the scan status) we want to extract is the value of the status key inside the nested JSON object with key current_session
      • If the scan status is processing or scheduled, the script continues to wait; when the scan status changes to completed, the script continues processing; if a scan status of one of these 3 values is not received, then the scan status is considered invalid and the cleanup function is called, and the script ends
  • We need to obtain the scan session ID; the response to the get_scan API call also contains the scan session ID; the critical information we want to extract is the value of the scan_session_id key inside the nested JSON object with key current_session
  • We need to obtain the Scan Result ID; to obtain the Scan Result ID:
    • The API documentation for the get_scan_result_history API call shows that:
      • We have to make a GET request to the /scans/{scan_id}/results endpoint, where the scan_id was obtained from a previous step
      • The response is in JSON format; the critical information (the scan result ID) we want to extract is the value of the result_id key inside one of the array of JSON objects forming the value for the results key; since the script creates a single scan for a single target, the situation is simplified such that we only expect to get a single JSON object nested inside the results key
  • We need to obtain the list of vulnerabilities generated by the scan:
    • The API documentation for the get_scan_vulnerabilities api call shows that:
      • We have to make a GET request to the /scans/{scan_id}/results/{result_id}/vulnerabilities endpoint, where the scan_id and the result_id were obtained from previous steps
      • The response is in JSON format and contains 2 keys:
        • The vulnerabilities key contains an array of all the vulnerabilities (up to 100) found for the scan scheduled previously
        • The pagination key contains information about the number of pages and how to retrieve subsequent pages in the case that the number of vulnerabilities is indeed more than 100

Bash Script

  1. #!/bin/bash

  2. # requires "jq" to be installed; on a debian system, uncomment the following line

  3. # apt install -y jq > /dev/null

  4. # Declare functions

  5. cleanup(){

  6. # delete the scan

  7. Dummy=`curl -sS -k -X DELETE "$MyAXURL/scans/{$MyScanID}" -H "Accept: application/json" -H "X-Auth: $MyAPIKEY"`

  8. # delete the target

  9. Dummy=`curl -sS -k -X DELETE "$MyAXURL/targets/{$MyTargetID}" -H "Accept: application/json" -H "X-Auth: $MyAPIKEY"`

  10. }

  11. # Declare Variables

  12. MyAXURL="https://qgen-004.qgengroup.local:3443/api/v1"

  13. MyAPIKEY="1986abcdefabcdefd7028d5f3c06e936c2a54cb301c8342b8b047b25985b4205f"

  14. MyTargetURL="http://testphp.vulnweb.com/"

  15. MyTargetDESC="Test PHP Site - created via ax-bash-api.sh"

  16. FullScanProfileID="11111111-1111-1111-1111-111111111111"

  17. # Create our intended target

  18. MyTargetID=`curl -sS -k -X POST $MyAXURL/targets -H "Content-Type: application/json" -H "X-Auth: $MyAPIKEY" --data "{"address":"$MyTargetURL","description":"$MyTargetDESC","type":"default","criticality":10}" | grep -Po '"target_id": *K"[^"]*"' | tr -d '"'`

  19. # Trigger a scan on the target

  20. MyScanID=`curl -i -sS -k -X POST $MyAXURL/scans -H "Content-Type: application/json" -H "X-Auth: $MyAPIKEY" --data "{"profile_id":"$FullScanProfileID","incremental":false,"schedule":{"disable":false,"start_date":null,"time_sensitive":false},"user_authorized_to_scan":"yes","target_id":"$MyTargetID"}" | grep "Location: " | sed "s/Location: /api/v1/scans///" | sed "s/r//g" | sed -z "s/n//g"`

  21. while true; do

  22. MyScanStatus=`curl -sS -k -X GET "$MyAXURL/scans/{$MyScanID}" -H "Accept: application/json" -H "X-Auth: $MyAPIKEY"`

  23. if [[ "$MyScanStatus" == *""status": "processing""* ]]; then

  24. echo "Scan Status: Processing - waiting 30 seconds"

  25. elif [[ "$MyScanStatus" == *""status": "scheduled""* ]]; then

  26. echo "Scan Status: Scheduled - waiting 30 seconds"

  27. elif [[ "$MyScanStatus" == *""status": "completed""* ]]; then

  28. echo "Scan Status: Completed"

  29. # Break out of loop

  30. break

  31. else

  32. echo "Invalid Scan Status: Aborting"

  33. # Clean Up and Exit script

  34. cleanup

  35. exit 1

  36. fi

  37. sleep 30

  38. done

  39. # Obtain the Scan Session ID

  40. MyScanSessionID=`echo "$MyScanStatus" | grep -Po '"scan_session_id": *K"[^"]*"' | tr -d '"'`

  41. # Obtain the Scan Result ID

  42. MyScanResultID=`curl -sS -k -X GET "$MyAXURL/scans/{$MyScanID}/results" -H "Accept: application/json" -H "X-Auth: $MyAPIKEY" | grep -Po '"result_id": *K"[^"]*"' | tr -d '"'`

  43. # Obtain Scan Vulnerabilities

  44. MyScanVulnerabilities=`curl -sS -k -X GET "$MyAXURL/scans/{$MyScanID}/results/{$MyScanResultID}/vulnerabilities" -H "Accept: application/json" -H "X-Auth: $MyAPIKEY"`

  45. echo

  46. echo "Target ID: $MyTargetID"

  47. echo "Scan ID: $MyScanID"

  48. echo "Scan Session ID: $MyScanSessionID"

  49. echo "Scan Result ID: $MyScanResultID"

  50. echo

  51. echo

  52. echo "Scan Vulnerabilities"

  53. echo "===================="

  54. echo

  55. echo $MyScanVulnerabilities | jq

THE AUTHOR
Kevin Attard Compagno
Technical Writer

Kevin Attard Compagno is a Technical Writer working for Acunetix. A technical writer, translator, and general IT buff for over 30 years, Kevin used to run Technical Support teams and create training documents and other material for in-house technical staff.

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: