Nmap (network mapper) is an open source security scanner used for network exploration and security auditing. It identifies endpoints and services within a network and provides a comprehensive network map. The network mapper is commonly referred to as the Swiss army knife of networking due to its many interesting capabilities to gather information from endpoints on a network.
ChatGPT is an artificial intelligence (AI) powered language model based on the GPT-4 (generative pre-trained transformer) architecture. It is a chatbot designed to generate human-like text based on the input it receives. This AI engine has been trained on diverse data and can provide constructive responses to questions. ChatGPT is a useful tool in various disciplines, including cybersecurity. The tool provides an API to obtain suggestions for effectively managing security audits, conducting threat hunting, or summarizing security issues.
Nmap and ChatGPT are resourceful tools that can improve the security posture of organizations when used correctly. In this blog post, we show how Wazuh utilizes the resources provided by these tools to improve your organization’s security posture.
Infrastructure
To demonstrate integrating Nmap and ChatGPT with Wazuh, we use the following infrastructure.
- A ready-to-use Wazuh OVA 4.4.5. Follow this guide to download the virtual machine.
- An Ubuntu 22.04 LTS endpoint with Wazuh agent 4.4.5 installed. To install the Wazuh agent, refer to the following installation guide.
- A Windows 11 endpoint with Wazuh agent 4.4.5 installed. To install the Wazuh agent, refer to the following installation guide.
Configuration
We use the Wazuh command monitoring capability combined with Nmap to periodically query the endpoints’ open port services.
The Wazuh command monitoring module allows you to execute specified commands on monitored endpoints, providing a way to gather important information or perform scheduled tasks. The output generated by these commands is captured as log data. You can analyze this data to identify potential security threats or gain valuable insights into the behavior of your network.
Nmap integration
In this section, we run an Nmap scan using Python to provide information about open ports on a Windows and Ubuntu endpoint.
Nmap script
We created a Python script to perform network scans on an endpoint. The script extracts information such as hostnames, protocols, and open ports.
#!/var/ossec/framework/python/bin/python3 # Copyright (C) 2015-2023, Wazuh Inc. import nmap import time import json import platform # The function to perform network scan on a host endpoint def scan_subnet(subnet): nm = nmap.PortScanner() nm.scan(subnet) results = [] for host in nm.all_hosts(): for proto in nm[host].all_protocols(): if proto not in ["tcp", "udp"]: continue lport = list(nm[host][proto].keys()) lport.sort() # Iterate over each port for the current host and protocol for port in lport: hostname = "" json_output = { 'nmap_host': host, 'nmap_protocol': proto, 'nmap_port': port, 'nmap_hostname': "", 'nmap_hostname_type': "", 'nmap_port_name': "", 'nmap_port_state': "", 'nmap_port_service': "" } # Get the first hostname and it’s type if nm[host]["hostnames"]: hostname = nm[host]["hostnames"][0]["name"] hostname_type = nm[host]["hostnames"][0]["type"] json_output['nmap_hostname'] = hostname json_output['nmap_hostname_type'] = hostname_type # Get the port name if available if 'name' in nm[host][proto][port]: json_output['nmap_port_name'] = nm[host][proto][port]['name'] # Get the port state if available if 'state' in nm[host][proto][port]: json_output['nmap_port_state'] = nm[host][proto][port]['state'] # Get the port service version if available if 'product' in nm[host][proto][port] and 'version' in nm[host][proto][port]: service = nm[host][proto][port]['product'] + " " + nm[host][proto][port]['version'] json_output['nmap_port_service'] = service results.append(json_output) return results # The function to append the scan results to the active response log file def append_to_log(results, log_file): with open(log_file, "a") as active_response_log: for result in results: active_response_log.write(json.dumps(result)) active_response_log.write("\n") # Specify the address(es) to scan subnets = ['127.0.0.1'] # path of the log file if platform.system() == 'Windows': log_file = "C:\\Program Files (x86)\\ossec-agent\\active-response\\active-responses.log" elif platform.system() == 'Linux': log_file = "/var/ossec/logs/active-responses.log" else: log_file = "/Library/Ossec/logs/active-responses.log" for subnet in subnets: results = scan_subnet(subnet) append_to_log(results, log_file) time.sleep(2)
Note: You can use the centralized configuration to distribute this setting across multiple monitored endpoints. Please note that remote commands are disabled by default for security reasons and must be explicitly enabled on each agent.
Ubuntu endpoint
Install the following packages to run an Nmap scan using Python on Ubuntu.
1. Install python3
and python3-pip
from the APT repository by running the command below:
$ sudo apt-get update && sudo apt-get install python3 $ sudo apt-get install python3-pip
2. Install Nmap
and the python-nmap
library. The python-nmap
library provides many options for customizing Nmap scans:
$ sudo apt-get install nmap $ sudo pip3 install python-nmap
Take the following steps to configure the Wazuh command monitoring module.
1. Create a ~/Documents/nmapscan.py
file and copy the content of Nmap script to it.
2. Edit the Wazuh agent /var/ossec/etc/ossec.conf
file and add the following command monitoring configuration within the <ossec_config>
block:
<!-- Run nmap python script --> <localfile> <log_format>full_command</log_format> <command>python3 /home/<USERNAME>/Documents/nmapscan.py</command> <frequency>604800</frequency> </localfile>
Replace <USERNAME>
placeholder with the name of the user account on the endpoint.
3. Restart the Wazuh agent to apply this change:
$ sudo systemctl restart wazuh-agent
Windows endpoint
Install the following packages to run an Nmap scan using Python on Windows.
Note: Administrator privileges are required to perform the installation
1. Python v 3.8.7 or later (with pip
pre-installed). Check the following boxes when prompted:
- Install launcher for all users (recommended).
- Add
Python
to PATH.
2. Microsoft Visual C++ 2015 Redistributable.
3. Nmap v7.94 or later. Ensure to add Nmap to PATH.
4. Run the command below to install the python-nmap
library and all its dependencies using Powershell:
> pip3 install python-nmap
Follow the steps below to configure the Nmap port scanner using Python after installing the above packages:
1. Create a C:\Users\<USERNAME>\Documents\nmapscan.py
file and copy the content of Nmap script to it.
2. Convert the Nmap script to an executable application. Open an administrator PowerShell terminal and use pip
to install pyinstaller
:
> pip install pyinstaller > pyinstaller --version
3. Create the executable file using pyinstaller
:
> pyinstaller -F <PATH_TO_NMAPSCAN.PY>
You can find the created nmapscan.exe
executable in the C:\Users\<USERNAME>\dist\
directory.
4. Copy the nmapscan.exe
executable file to C:\Users\<USERNAME>\Documents\nmapscan.exe
directory.
5. Edit the Wazuh agent C:\Program Files (x86)\ossec-agent\ossec.conf
file and add the following command monitoring configuration within the <ossec_config>
block:
<!-- Run nmap python script --> <localfile> <log_format>full_command</log_format> <command>C:\Users\<USERNAME>\Documents\nmapscan.exe</command> <frequency>604800</frequency> </localfile>
Replace <USERNAME>
placeholder with the name of the user account on the endpoint.
6. Restart the Wazuh agent using PowerShell for the changes to take effect:
> Restart-Service -Name wazuh
Wazuh server
In this section, we create a rule to capture the result of the Nmap scan on the monitored endpoint.
1. Add the rule below to the /var/ossec/etc/rules/local_rules.xml
file:
<group name="linux,nmap,"> <rule id="100100" level="3"> <decoded_as>json</decoded_as> <field name="nmap_port">\.+</field> <field name="nmap_port_service">\.+</field> <description>NMAP: Host scan. Port $(nmap_port) is open and hosting the $(nmap_port_service) service.</description> <options>no_full_log</options> </rule> </group>
Where:
- Rule ID
100100
is triggered after a successful Nmap scan on the monitored endpoint.
2. Restart the Wazuh manager to apply the configuration changes:
$ sudo systemctl restart wazuh-manager
Scan results
The images below show the alerts generated on the Wazuh dashboard when we perform Nmap scans on the Ubuntu and Windows endpoint.
Navigate to the Security events tab to view the generated alerts.
Ubuntu results
Windows results
ChatGPT integration
The Wazuh ChatGPT integration is a configuration that allows Wazuh to communicate with the ChatGPT AI engine. Users can enhance security monitoring and incident response capabilities by using the power of natural language processing. By integrating Wazuh with ChatGPT, we can create a chatbot interface that interacts with the Wazuh platform to perform security-related tasks or provide more information.
In this section, we use ChatGPT to provide information about open ports scanned by Nmap.
Wazuh server
1. Add the below custom rule to the /var/ossec/etc/rules/local_rules.xml
file.
<group name="linux,chat_gpt"> <rule id="100101" level="5"> <if_sid>100100</if_sid> <field name="nmap_port">\d+</field> <description>NMAP: Host scan. Port $(nmap_port) is open.</description> </rule> <rule id="100103" level="5"> <if_sid>100100</if_sid> <field name="nmap_port_service">^\s$</field> <description>NMAP: Port $(nmap_port) is open but no service is found.</description> </rule> </group>
Where:
- Rule ID
100101
is triggered after a successful Nmap scan on the monitored endpoint with the condition that there are one or more open ports with a found service. - Rule ID
100103
is triggered after a successful Nmap scan on the monitored endpoint with the condition that there are one or more open ports without a found service.
2. Install the Python module requests
. This HTTP library is necessary for the ChatGPT integration script to work with HTTP requests.
# pip install requests
3. Create an integration script called /var/ossec/integrations/custom-chatgpt.py
and copy the Python script below to custom-chatgpt.py
. The Python script below takes note of open ports on an endpoint and sends it to ChatGPT to get information about the open services and past vulnerabilities:
#!/var/ossec/framework/python/bin/python3 # Copyright (C) 2015-2023, Wazuh Inc. # ChatGPT Integration template by @WhatDoesKmean import json import sys import time import os from socket import socket, AF_UNIX, SOCK_DGRAM try: import requests from requests.auth import HTTPBasicAuth except Exception as e: print("No module 'requests' found. Install: pip install requests") sys.exit(1) # Global vars debug_enabled = False pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) print(pwd) #exit() json_alert = {} now = time.strftime("%a %b %d %H:%M:%S %Z %Y") # Set paths log_file = '{0}/logs/integrations.log'.format(pwd) socket_addr = '{0}/queue/sockets/queue'.format(pwd) def main(args): debug("# Starting") # Read args alert_file_location = args[1] apikey = args[2] debug("# API Key") debug(apikey) debug("# File location") debug(alert_file_location) # Load alert. Parse JSON object. with open(alert_file_location) as alert_file: json_alert = json.load(alert_file) debug("# Processing alert") debug(json_alert) # Request chatgpt info msg = request_chatgpt_info(json_alert,apikey) # If positive match, send event to Wazuh Manager if msg: send_event(msg, json_alert["agent"]) def debug(msg): if debug_enabled: msg = "{0}: {1}\n".format(now, msg) print(msg) f = open(log_file,"a") f.write(str(msg)) f.close() def collect(data): nmap_port_service = data['nmap_port_service'] choices = data['content'] return nmap_port_service, choices def in_database(data, nmap_port_service): result = data['nmap_port_service'] if result == 0: return False return True def query_api(nmap_port_service, apikey): # Calling ChatGPT API Endpoint headers = { 'Authorization': 'Bearer ' + apikey, 'Content-Type': 'application/json', } json_data = { 'model': 'gpt-3.5-turbo', 'messages': [ { 'role': 'user', 'content': 'In 4 or 5 sentences, tell me about this service and if there are past vulnerabilities: ' + nmap_port_service, }, ], } response = requests.post('https://api.openai.com/v1/chat/completions', headers=headers, json=json_data) if response.status_code == 200: # Create new JSON to add the port service ip = {"nmap_port_service": nmap_port_service} new_json = {} new_json = response.json()["choices"][0]["message"] new_json.update(ip) json_response = new_json data = json_response return data else: alert_output = {} alert_output["chatgpt"] = {} alert_output["integration"] = "custom-chatgpt" json_response = response.json() debug("# Error: The chatgpt encountered an error") alert_output["chatgpt"]["error"] = response.status_code alert_output["chatgpt"]["description"] = json_response["errors"][0]["detail"] send_event(alert_output) exit(0) def request_chatgpt_info(alert, apikey): alert_output = {} # If there is no port service present in the alert. Exit. if not "nmap_port_service" in alert["data"]: return(0) # Request info using chatgpt API data = query_api(alert["data"]["nmap_port_service"], apikey) # Create alert alert_output["chatgpt"] = {} alert_output["integration"] = "custom-chatgpt" alert_output["chatgpt"]["found"] = 0 alert_output["chatgpt"]["source"] = {} alert_output["chatgpt"]["source"]["alert_id"] = alert["id"] alert_output["chatgpt"]["source"]["rule"] = alert["rule"]["id"] alert_output["chatgpt"]["source"]["description"] = alert["rule"]["description"] alert_output["chatgpt"]["source"]["full_log"] = alert["full_log"] alert_output["chatgpt"]["source"]["nmap_port_service"] = alert["data"]["nmap_port_service"] nmap_port_service = alert["data"]["nmap_port_service"] # Check if chatgpt has any info about the nmap_port_service if in_database(data, nmap_port_service): alert_output["chatgpt"]["found"] = 1 # Info about the port service found in chatgpt if alert_output["chatgpt"]["found"] == 1: nmap_port_service, choices = collect(data) # Populate JSON Output object with chatgpt request alert_output["chatgpt"]["nmap_port_service"] = nmap_port_service alert_output["chatgpt"]["choices"] = choices debug(alert_output) return(alert_output) def send_event(msg, agent = None): if not agent or agent["id"] == "000": string = '1:chatgpt:{0}'.format(json.dumps(msg)) else: string = '1:[{0}] ({1}) {2}->chatgpt:{3}'.format(agent["id"], agent["name"], agent["ip"] if "ip" in agent else "any", json.dumps(msg)) debug(string) sock = socket(AF_UNIX, SOCK_DGRAM) sock.connect(socket_addr) sock.send(string.encode()) sock.close() if __name__ == "__main__": try: # Read arguments bad_arguments = False if len(sys.argv) >= 4: msg = '{0} {1} {2} {3} {4}'.format(now, sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] if len(sys.argv) > 4 else '') debug_enabled = (len(sys.argv) > 4 and sys.argv[4] == 'debug') else: msg = '{0} Wrong arguments'.format(now) bad_arguments = True # Logging the call f = open(log_file, 'a') f.write(str(msg) + '\n') f.close() if bad_arguments: debug("# Exiting: Bad arguments.") sys.exit(1) # Main function main(sys.argv) except Exception as e: debug(str(e)) raise
4. Grant executable permissions and modify the owner and group of the newly created Python script to belong to Wazuh:
# chmod 750 /var/ossec/integrations/custom-chatgpt.py # chown root:wazuh /var/ossec/integrations/custom-chatgpt.py
5. Edit the /var/ossec/etc/ossec.conf
file and add the integration block with the content below within the <ossec_config>
block:
<!-- ChatGPT Integration --> <integration> <name>custom-chatgpt.py</name> <hook_url>https://api.openai.com/v1/chat/completions</hook_url> <api_key><YOUR_CHATGPT_API_KEY></api_key> <level>5</level> <rule_id>100101</rule_id> <alert_format>json</alert_format> </integration>
The parameters used in the integration block are as follows:
<name>
is the name of the custom script that performs the integration. All custom script names must start withcustom-
.<hook_url>
is the API URL provided by ChatGPT.<api_key>
is the API key. Replace<YOUR_CHATGPT_API_KEY>
with your API key.<level>
sets a level filter so that the script does not act upon alerts below a certain level.<rule_id>
sets the rules that will trigger this integration. In this article, we use the rule ID100101
to trigger the ChatGPT integration script when Nmap discovers a service with an open port.<alert_format>
indicates the format of the alerts. We recommend the JSON format. The script will receive the alerts in full_log format if you do not set it to JSON.
Note: The OpenAI API is not free. However, when creating a new account, OpenAI provides you with a free trial usage for the API. You can register for a free API key at https://platform.openai.com/signup. Once your account is created:
- Click on the upper-right upper user icon.
- Click on View API Keys.
- Click Create new secret key.
- Confirm that you have free trial usage for the API at https://platform.openai.com/account/usage.
- Copy the new key and save it someplace safe as you won’t be able to view the key again.
6. Add the custom rule below to the /var/ossec/etc/rules/local_rules.xml
file. This rule will trigger when the port service is known and will also capture the response collected by the ChatGPT integration:
<group name="local,linux,"> <rule id="100102" level="6"> <field name="chatgpt.nmap_port_service">\w+</field> <description>The service $(chatgpt.nmap_port_service) is on an open port.</description> </rule> </group>
7. Restart the Wazuh manager to apply the configuration changes:
# systemctl restart wazuh-manager
Scan results
Below is the image of the alerts generated on the Wazuh dashboard when Nmap scans an Ubuntu endpoint.
Navigate to the Security events tab to view the generated alerts.
Ubuntu results
Windows results
Conclusion
In this blog post, we have demonstrated how to integrate Nmap and ChatGPT with Wazuh to perform network endpoint scans and enhance security audits. The integration enables ChatGPT to interact with Nmap and Wazuh, leveraging natural language processing to provide intelligent assistance. This functionality will allow your organization to gain better security insights by leveraging the combined strength of Nmap, ChatGPT, and Wazuh.
References
If you have any questions about this, join our Slack community channel! Our team and other contributors will assist you.