Using Faraday API for Vulnerability Management
As in any consulting process, we often find that performing repetitive tasks consumes time that we could invest in other activities. At Faraday, we like to tackle these challenges and use any available tool to automate these use cases with simple scripts.
Within our Red team, we prefer to focus on specific tasks depending on the type of host and the associated vulnerabilities. Exploiting a vulnerability on a third-party server with no connection to a client’s internal network is not the same as attacking a cloud-hosted server that could potentially lead to a more interesting compromise, right? Another common example is when performing an internal pentest; our client details the most critical ranges to observe and analyze.
Faraday helps us manage and analyze vulnerabilities and assets that we will be assessing, using multiple inputs from different tools:
As you can see, a simple scan returns a list of 240 assets and over 6000 vulnerabilities, so organizing and cataloging my scope might be somewhat complex and difficult. Using the Faraday UI, I can apply filters to, for example, tag a set of vulnerabilities to separate and analyze them collectively. However, this would require creating a large filter that might be cumbersome to keep updated, so we will use the Faraday API in conjunction with faraday-cli for automating these tasks.
In this first section, we will understand the key components to carry out this automation:
Components
Authentication Token
The first step is to obtain an authentication token by sending a POST request to the Faraday server with the username and password. The token we receive will then be used in subsequent API requests.
Vulnerability IDs
The get_vulns_id function will return a list of identifiers for the IPs that we want to modify/update.
Setting Tags
Finally, the set_tags function will apply a specific tag to the vulnerability identifiers we obtained earlier.
CLI interface
What we are referring to as the main function is a CLI interface (using faraday-cli) to interact with the Faraday API. To install it, you can follow the steps from the official repository: https://github.com/infobyte/faraday-cli, but we can simplify it to the following two methods:
Using pip:
pip install faraday-cli
From the source code:
git clone https://github.com/infobyte/faraday-cli.git cd faraday-cli pip install .
The script will take as arguments the workspace, the Faraday server, the tags, and a list of IPs as an input file. Internally, it will authenticate to our server (using the username and password as environment variables), retrieve the vulnerabilities of the IPs to query, and apply a specific tag to each one.
Example usage
To use this script, you need to set the `FARADAY_USER` and `FARADAY_PASSWORD` environment variables. Then, you can run the script from the command line, providing the required parameters:
"`bash python script.py --workspace <workspace> --server <server> --tag <tag> --input-file <input_file> "`
Replace `<workspace>`, `<server>`, `<tag>`, and `<input_file>` with your actual values.
Internal Functions
Internally, our script will include certain functions to carry out the process we want to automate. In this section, each function will be explained and how they are implemented.
get_token(server, user, password)
Purpose
To return the vulnerability IDs for a given IP.
Return Value
A complete list of vulnerability IDs if the query was successful.
def get_vuln_ids(workspace, server, token, ip): vulns_response = requests.get( f'https://{server}/_api/v3/ws/{workspace}/vulns/filter?q={{"filters":[{{"name":"target","op":"==","val":"{ip}"}}]}}', headers={'Authorization': f'Token {token}'}, verify=False ) if vulns_response.status_code == 200: vulns_data = vulns_response.json() return [vuln['id'] for vuln in vulns_data["vulnerabilities"]] else: print(f"Error: Could not retrieve vulnerabilities for IP {ip}. Status code: {vulns_response.status_code}") return []
set_tags(workspace, server, token, vuln_ids, tag)
Purpose
To apply tags to vulnerabilities using the identifiers obtained earlier.
Return Value
Should print a message if the request was successful.
def set_tags(workspace, server, token, vuln_ids, tag): payload = {"vulnerability_ids": vuln_ids, "tags_to_add": [tag], "tags_to_remove": []} set_tags_response = requests.post( f'https://{server}/_api/v3/ws/{workspace}/vulns/set_tags', json=payload, headers={'Authorization': f'Token {token}'}, verify=False ) if set_tags_response.status_code == 200: print("Tags successfully set.") else: print(f"Error: Could not set tags. Status code: {set_tags_response.status_code}")
To use this script, you need to set FARADAY_USER and FARADAY_PASSWORD as environment variables with the corresponding values for your instance. Then, to run the script, you should execute it as follows:
python script.py --workspace <workspace> --server <server> --tag <tag> --input-file <input_file>
Replace the values of workspace, server, tag, and input_file with the values for your instance.
Trainings, red teaming services, or continuous scanning? We’ve got you covered. Reach out for more information.
Related Posts
October 7, 2024
Maturity Models in Vulnerability Management: Where Are You At?
Since organizations differ in size, structure, and maturity, there are various vulnerability management models tailored to each. These…
July 29, 2024
Expanded Attack Surface: How to Optimize Time and Resources in Cybersecurity
Security teams of all sizes, from large Fortune 500 companies to small NGOs, face the same problem: a lack of time and an ever-expanding…
May 29, 2024
Good practices in Cybersecurity – Part 3
Good security practices go hand in hand with automation, integration, and collaboration. As dynamic as the threat landscape is, so must our…