Sample API client

A sample API client written in Python, which can be used as a starting point for using the API.

#!/usr/bin/python

#
# Sample API client for Pentest-Tools.com.
# This client starts a Web Server Scan, queries the output and writes the report in a HTML and a PDF file.
# A valid API key is necessary for this program to work.
#
# API Reference: https://pentest-tools.com/api_reference
#

import requests
import json
import time
import sys
import traceback
import base64

def start_scan(api_url, tool_id, tool_params):
    data = {
                "op":             "start_scan",
                "tool_id":         tool_id,
                "tool_params":     tool_params
            }
    res = requests.post(api_url, data=json.dumps(data))
    return res


def get_output(api_url, scan_id, output_format):
    data = {
                "op":              "get_output",
                "scan_id":          scan_id,
                "output_format":    output_format
            }
    res = requests.post(api_url, data=json.dumps(data))
    return res


def stop_scan(api_url, scan_id):
    data = {
                "op":       "stop_scan",
                "scan_id":  scan_id
            }
    res = requests.post(api_url, data=json.dumps(data))
    return res


def get_scan_status(api_url, scan_id):
    data = {
                "op":        "get_scan_status",
                "scan_id":   scan_id
            }
    res = requests.post(api_url, data=json.dumps(data))
    return res


def get_scans(api_url, limit):
    data = {
                "op":        "get_scans",
                "limit":     limit
            }
    res = requests.post(api_url, data=json.dumps(data))
    return res


def get_targets(api_url, limit=0):
    data = {
                "op":        "get_targets",
                "limit":     limit
            }
    res = requests.post(api_url, data=json.dumps(data))
    return res


if __name__ == '__main__':

    key     = "xxxxxxxxxxxxxx"                              # <-- Put your API key here
    api_url = "https://pentest-tools.com/api?key=" + key

    # These values are specific to each tool
    # In this case we want to use the Web Server Scanner
    # See the API Reference for more details
    tool_id     = 170
    tool_params = {
                    "target": "http://demo.pentest-tools.com/webapp/",
                    "scan_type": "quick"
                  }

    # Start the scan
    res = start_scan(api_url, tool_id, tool_params)
    try:
        res_json = json.loads(res.text)
    except:
        print traceback.format_exc()
        print res.text


    # Check the status of the operation
    if res_json["op_status"] == "success":

        # This is the id of the new scan
        scan_id = res_json["scan_id"]

        print "Started scan %i" % scan_id


        # Poll periodically to check if the scan is finished
        while True:
            time.sleep(2)

            # Get the status of our scan
            res = get_scan_status(api_url, scan_id)
            res_json = json.loads(res.text)

            if res_json["op_status"] == "success":

                print "Scan status: %s" % res_json["scan_status"]

                if res_json["scan_status"] != "waiting" and res_json["scan_status"] != "running":

                    # Get the HTML report and write it to a file
                    print "Getting HTML report"
                    res         = get_output(api_url, scan_id, "html")
                    res_json    = json.loads(res.text)
                    output_html = res_json["scan_output"]["output_html"]

                    with open("report.html", "w") as f:
                        f.write(output_html)
                    print "HTML report written to file"


                    # Get the PDF report and write it to a file
                    print "Getting PDF report"
                    res         = get_output(api_url, scan_id, "pdf")
                    res_json    = json.loads(res.text)
                    output_pdf  = res_json["scan_output"]["output_pdf"]

                    with open("report.pdf", "w") as f:
                        f.write(base64.b64decode(output_pdf))
                    print "PDF report written to file"

                    break

            else:
                print "Operation get_scan_status failed because: %s. %s" % (res_json["error"], res_json["details"])
                break

    else:
        print "Operation start_scan failed because: %s. %s" % (res_json["error"], res_json["details"])