Managing Scans using PowerShell and the Acunetix API | Acunetix

0
68

[ad_1]

In the previous installment of this series, we have shown you how to manage Acunetix scans using Bash and the Acunetix API. In this article, you will learn how to do the same using PowerShell. As an example, we will create a PowerShell V7 script that uses Invoke-RestMethod to make requests to the Acunetix REST API.

Every API call must be authenticated by providing the API key in the HTTP request headers, hence each request is made with the following headers:

Content-Type: application/json
X-Auth: <my_api_key>

The API Key can be retrieved from the Acunetix profile page.

Anatomy of the Script

The script has the following structure:

  • First, we declare the cleanup function, which is a recovery function to delete the scan and target that were created by the script if an invalid scan status is detected:
    • The remove_scan API call requires us to make a DELETE request to the /scans/{scan_id} endpoint; the scan ID is retrieved by the main part of the script described below
    • The remove_target API call requires us to make a DELETE request to the /targets/{target_id} endpoint; the target ID is retrieved by the main part of the script described below
  • Then, we declare the starting global variables to be used throughout the script:
    • MyAXURL is the base URL for your Acunetix API, which is typically:
      • On-premises: https://<your_fqdn>: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 eventually be scanned
    • MyTargetDESC is a 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
    • MyRequestHeaders is the array of HTTP request headers (including authentication with the Acunetix API key)
  • Next, we create the target:
    • 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 and contain at least 4 keys: address, description, type, and criticality; in our example:
        { "address": "http://testphp.vulnweb.com/",
        "description": "Test PHP Site - created via ax-powershell-api.ps1",
        "type": "default",
        "criticality": 10 }
        
      • The response will be in JSON format; the critical information we want to extract from the response is the value of the target_id key
  • As a next step, we schedule the scan:
    • 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; however, the critical information (the scan ID) we want to extract is not delivered in the response but in the HTTP response header called Location
  • Then, we create a loop 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 the scan status is not one of these 3 values, it is considered invalid, the cleanup function is called, and the script ends
  • Next, 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
  • Then, we need to obtain the scan result ID; to obtain it, we need to do the following:
    • 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 arrays 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
  • Finally, 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

PowerShell Script

Note: Requires PowerShell Version 7 or later; tested with PowerShell v7.0.3

  1. function cleanup{

  2. # delete the scan

  3. $dummy=Invoke-RestMethod -Uri "$MyAXURL/scans/$MyScanID" -Headers $MyRequestHeaders -Method Delete

  4. # delete the target

  5. $dummy=Invoke-RestMethod -Uri "$MyAXURL/targets/$MyTargetID" -Headers $MyRequestHeaders -Method Delete

  6. }

  7. # Declare Variables

  8. $MyAXURL="https://acunetix.local:3443/api/v1"

  9. $MyAPIKEY="1986abcdefabcdefd7028d5f3c06e936c2a54cb301c8342b8b047b25985b4205f"

  10. $MyTargetURL="http://testphp.vulnweb.com/"

  11. $MyTargetDESC="Test PHP Site - created via ax-powershell-api.ps1"

  12. $FullScanProfileID="11111111-1111-1111-1111-111111111111"

  13. $MyRequestHeaders[email protected]{

  14. 'X-Auth' = $MyAPIKEY

  15. 'Content-Type' = 'application/json'

  16. }

  17. # Create our intended target - Target ID is in the JSON response

  18. $MyRequestBody='{"address":"' + $MyTargetURL + '","description":"' + $MyTargetDESC + '","type":"default","criticality":10}'

  19. $MyTargetID=(Invoke-RestMethod -Uri $MyAXURL/targets -Headers $MyRequestHeaders -Method Post -Body $MyRequestBody).target_id

  20. # Trigger a scan on the target - Scan ID is in the HTTP Response Headers

  21. $MyRequestBody='{"profile_id":"' + $FullScanProfileID + '","incremental":false,"schedule":{"disable":false,"start_date":null,"time_sensitive":false},"user_authorized_to_scan":"yes","target_id":"' + $MyTargetID + '"}'

  22. $TempResponse=Invoke-RestMethod -Uri $MyAXURL/scans -Headers $MyRequestHeaders -Method Post -ResponseHeadersVariable MyResponseHeaders -Body $MyRequestBody

  23. $MyScanID=$MyResponseHeaders.Location -replace "/api/v1/scans/", ""

  24. while ($true){

  25. $MyScanStatus=(Invoke-RestMethod -Uri "$MyAXURL/scans/$MyScanID" -Headers $MyRequestHeaders).current_session.status

  26. echo "ScanStatus: $MyScanStatus"

  27. switch ($MyScanStatus){

  28. "processing" {echo "Scan Status: Processing - waiting 30 seconds..."}

  29. "scheduled" {echo "Scan Status: Scheduled - waiting 30 seconds..."}

  30. "completed" {break}

  31. default {

  32. echo "Invalid Scan Status: Aborting"

  33. cleanup

  34. exit

  35. }

  36. }

  37. $MyScanStatus=""

  38. start-sleep -s 30

  39. }

  40. # Obtain the Scan Session ID

  41. $MyScanSessionID=(Invoke-RestMethod -Uri "$MyAXURL/scans/$MyScanID" -Headers $MyRequestHeaders).current_session.scan_session_id

  42. # Obtain the Scan Result ID

  43. $MyScanResultID=(Invoke-RestMethod -Uri "$MyAXURL/scans/$MyScanID/results" -Headers $MyRequestHeaders).results.result_id

  44. # Obtain Scan Vulnerabilities

  45. $MyScanVulnerabilities=Invoke-RestMethod -Uri "$MyAXURL/scans/$MyScanID/results/$MyScanResultID/vulnerabilities" -Headers $MyRequestHeaders

  46. echo ""

  47. echo "Target ID: $MyTargetID"

  48. echo "Scan ID: $MyScanID"

  49. echo "Scan Session ID: $MyScanSessionID"

  50. echo "Scan Result ID: $MyScanResultID"

  51. echo ""

  52. echo ""

  53. echo "Scan Vulnerabilities"

  54. echo "===================="

  55. echo ""

  56. echo $MyScanVulnerabilities | convertto-json

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.


[ad_2]

Source link