How to automate your cybersecurity defenses with generative AI
A practical guide on how to use GenAI to assist with anomaly detection and incident response, with step-by-step instructions and sample code to follow.
May 3, 2024 • 12 Minute Read
The emergence of generative AI (GenAI) could become a turning point in today's society. Its transformative capabilities are evident in fields like healthcare, creative content generation, and scientific research. Large language and stable diffusion models pave the way for increased productivity and accelerated innovation.
Like any new technology, there are legitimate use cases where people transform their ideas into products that provide increased value for society. However, bad actors are also leveraging GenAI to craft more sophisticated and impactful attacks.
Script kiddies now have the ability to use petabytes of scrapped data used to train these models for developing real threats to information systems. Even though the companies behind these models are setting protection measures to prevent using them with malicious intent, there are still plenty of ways to drive the prompt of large language models to output dangerous information.
Now let’s not be too pessimistic about it. GenAI has a lot of potential in cybersecurity too. It can provide meaningful code snippets, which could be used to enhance already-built solutions, or build new ones from scratch.Let’s explore some of the ways in which you can use GenAI for increasing the security stance of your organization. I will share some insights from my own experience using the OpenAI API in cyber defense, a project that I call Dr. CyberGPT.
Table of contents
The problem with cybersecurity: We're drowning in data
Let’s face it, humans are limited in processing vast amounts of data. We have bottlenecks in attention and working memory, which hinder our ability to hold and manipulate multiple pieces of information simultaneously. The more data we deal with, the more likely we are to make mistakes, miss subtle patterns, or become biased in our interpretations. Our main assets are our intuition, creativity and social skills.
In cybersecurity we are swimming in an ocean of data. From log files to network traffic, the amount of information to sift through is staggering. This is often referred to as the "security data deluge." According to a report by Splunk, the average organization generates over 17,000 security events per week! This can lead to:
Alert fatigue: Security teams become desensitized to alerts, leading to missed threats.
Information overload: Analysts struggle to prioritize and analyze the sheer volume of data.
Inefficient resource allocation: Teams waste time and resources on false positives or low-priority threats.
As a cybersecurity professional, managing this information overload is challenging. Let’s see how to tackle it.
How to use GenAI for anomaly detection
The setup
We’re going to see Dr. 's CyberGPT small detection Python script that is capable of finding threats in the logs generated by email servers. The logs are being injected in an ElasticSearch instance.
What do we need?
As a prerequisite, we need to register to OpenAI and generate an API key. This is needed in order to get the authorization for using their API. The process is straightforward and can be done in a few minutes through their official website.
Next, we need a few libraries to install before we proceed writing any code. Let’s install the openai library, by running the following command:
pip install openai
We also need a way to interact with ElasticSearch, so let’s install the right dependency for it:
pip install elasticsearch
That’s it! Now let’s start coding our detection script.
The code
First, let’s connect to ElasticSearch using the dedicated Python library. Here’s how to do it:
es = Elasticsearch(
['http://elasticSearchInstanceUrl:9200'],
http_auth=('user', 'password')
)
We provide the url to the elastic search instance, as well as an http_auth object that contains the credentials.
Next, we need to define the API key for the OpenAI API. We will do it in the script itself this time, however it is recommended to do it via an environment variable in order not to expose this information publicly. For keeping this example simple, we can have it hard coded in the script, like this:
openai.api_key = 'your-api-key'
Now, the meaty parts! We need to create a way to query for the logs sent to ElasticSearch by our email server. We can do it as follows:
def query_email_logs(hours_ago=24):
query = {
"query": {
"bool": {
"must": [
{"match": {"log_type": "email"}},
{"range": {"@timestamp": {"gte": f"now-{hours_ago}h/h", "lt": "now/h"}}}
]
}
}
}
return es.search(index="your-log-index", body=query)
Here we use a query which matches any logs that are of type email. Obviously this needs to be fine tuned to match the way you identify these logs. We capture everything that was generated in the last 24 hours by default. This also could be adjusted if the script will be run more often.
Now that we have the logs, we need to send them to GPT-4 to analyze them for threats and anomalies. Let’s see how to do that:
Def analyze_logs_with_gpt4(logs):
for log in logs['hits']['hits']:
email_content = log['_source']['email_content']
prompt = f"Analyze this email for potential threats or anomalies:\n\n{email_content}"
response = openai.Completion.create(
model="gpt-4-0125-preview",
prompt=prompt,
max_tokens=150
)
print(f"Email: {email_content}\nAnalysis: {response.choices[0].text}\n")
This function takes the log object as an argument, and sends each hit to the gpt-4-0125-preview model, which is one of the most advanced offered by OpenAI to date.
The prompt we use is this: Analyze this email for potential threats or anomalies:\n\n{email_content}. We set the max_tokens parameter to 150 in order to decrease the costs for using this model. This limits the response of the model to roughly 150 words, which can lead to more optimal costs, as the pricing depends on the number of tokens used for each interaction with the model.
Impressive, nice, now let’s see the main method:
def main():
try:
print("Querying Elasticsearch for recent email logs...")
logs = query_email_logs(24) # Query last 24 hours logs
if logs['hits']['total']['value'] > 0:
print("Analyzing logs with GPT-4...")
analyze_logs_with_gpt4(logs)
else:
print("No recent email logs found.")
except Exception as e:
print(f"An error occurred: {e}")
Here we get the logs from the last 24 hours, and if there are more than 0 results, we send the logs to GPT-4 for analysis. Here’s what it detects for the following logs:
-------------------------------
[2023-04-01 12:34:56] [INFO] 250-AUTH-LOGIN: User 'johndoe@globomantics.com' authenticated
[2023-04-01 12:35:01] [INFO] 250-STARTTLS: Connection encrypted
[2023-04-01 12:35:05] [INFO] 250-MAIL-FROM: Sender address 'sender@example.com'
[2023-04-01 12:35:10] [INFO] 250-RCPT-TO: Recipient address 'johndoe@globomantics.com'
[2023-04-01 12:35:15] [INFO] 354-DATA: Message accepted for delivery
[2023-04-01 12:35:20] [INFO] 250-QUIT: Connection closed
[2023-04-01 12:36:10] [ERROR] 250-AUTH-LOGIN: Failed authentication attempt for user 'nonexistentuser@globomantics.com' (This line shows an unsuccessful login attempt, which could indicate a brute-force attack)
[2023-04-01 12:36:15] [WARNING] 250-SMTP-INJECTION: Potential malware attachment detected (This line suggests that the message contains a malicious attachment)
[2023-04-01 12:37:01] [INFO] 250-AUTH-LOGIN: User 'janesmith@globomantics.com' authenticated (This line shows a successful login attempt by a legitimate user)
[2023-04-01 12:37:05] [INFO] 250-STARTTLS: Connection encrypted (This line indicates that the connection is now encrypted)
[2023-04-01 12:37:10] [INFO] 250-MAIL-FROM: Sender address 'support@globomantics.com' (This line shows a legitimate sender address)
[2023-04-01 12:37:15] [INFO] 250-RCPT-TO: Recipient address 'janesmith@globomantics.com' (This line shows a legitimate recipient address)
[2023-04-01 12:37:20] [INFO] 354-DATA: Message accepted for delivery (This line indicates that the message has been accepted for delivery)
[2023-04-01 12:37:25] [INFO] 250-QUIT: Connection closed (This line shows that the connection has been closed)
[2023-04-01 12:38:01] [INFO] 250-AUTH-LOGIN: User 'bobjones@globomantics.com' authenticated (This line shows another successful login attempt by a legitimate user)
[2023-04-01 12:38:05] [INFO] 250-STARTTLS: Connection encrypted (This line indicates that the connection is now encrypted)
[2023-04-01 12:38:10] [INFO] 250-MAIL-FROM: Sender address 'sales@globomantics.com' (This line shows a legitimate sender address)
[2023-04-01 12:38:15] [INFO] 250-RCPT-TO: Recipient address 'bobjones@globomantics.com' (This line shows a legitimate recipient address)
[2023-04-01 12:38:20] [INFO] 354-DATA: Message accepted for delivery (This line indicates that the message has been accepted for delivery)
[2023-04-01 12:38:25] [INFO] 250-QUIT: Connection closed (This line shows that the connection has been closed)
-------------------------------
At a glance, we don’t see anything suspicious, just a normal day in the office for our email server. However, GPT-4 managed to find the following:
Failed Authentication Attempt:
[2023-04-01 12:36:10] [ERROR] 250-AUTH-LOGIN: Failed authentication attempt for user 'nonexistentuser@globomantics.com'
This log entry indicates a failed login attempt for a user that appears to be nonexistent. This could be a sign of a brute-force attack where an attacker is trying different usernames to gain unauthorized access. It's important to monitor for repeated failed login attempts, as this could indicate a more concerted attack effort.
SMTP Injection Warning:
[2023-04-01 12:36:15] [WARNING] 250-SMTP-INJECTION: Potential malware attachment detected
This entry suggests that a message contains a potential malware attachment. This is a significant security concern as it could indicate an attempt to distribute malware within your network. It's crucial to investigate the nature of this attachment, determine its origin, and check if similar messages have been received. Ensure your malware detection systems are up-to-date and consider implementing stricter filtering for email attachments.
This is how you can use OpenAI API, more specifically the GPT-4 model, to perform threat hunting on email servers. If you want to learn more about threat hunting, you can check out my dedicated course on Pluralsight.
How to use GenAI for cybersecurity incident response
Large language models are not only useful in the context of threat hunters. These models can be used in anything that requires language comprehension. In this section, we will see how we can drive automatic incident response with GPT-4.
The setup
Our dear colleagues from the security engineering team use a ticketing system to log any security incident that happened on our platform. They added processes and checklists based on a broad spectrum of incidents, with actions for handling the aftermath of the majority of the incidents. The process is entirely manual, as they log the details of the incident and manually go through these checklists and follow up with the relevant actions. This can be automated to some extent by Dr. CyberGPT!
The code
Let’s say we want to handle any incident that involves our email server. The initial part for logging the incidents in a ticketing system depends entirely on the system itself. If it exposes an API, we can use that API to create a ticket based on the analysis of the logs we’ve seen in the previous section.
Next, we need to instruct GPT-4 to give us a checklist of actions we need to run based on the incident. We can reuse the API call we defined in the previous section but with a different prompt:
Def analyze_logs_with_gpt4(incident):
prompt = f"Provide a list of actions for performing incident response for the following incident:\n\n{incident}"
response = openai.Completion.create(
model="gpt-4-0125-preview",
prompt=prompt,
max_tokens=150
)
print(f"Analysis: {response.choices[0].text}\n")
Now, for the following incident:
Incident Type: Suspicious Email
Details: Received an email with a suspicious link claiming to be from a trusted sender. The email asks for sensitive information.
We get the following response from GPT-4:
- Quarantine the email to prevent further distribution.
- Notify the security team to investigate the source and content of the email.
- Remind employees about cybersecurity best practices, such as avoiding clicking on suspicious links and verifying the authenticity of emails from unknown senders.
- Conduct a security awareness training session focusing on phishing prevention.
- Monitor network traffic for any unusual activity or attempted breaches.
- Update email filtering rules to better detect and block similar phishing attempts in the future.
Pretty good, but this is not automating the full process. What else could we do to decrease the manual effort even further?
OpenAI added the ability to respond with a JSON instead of text for its models. What we need to do to enable this is to added the following parameter to the openai.Completion.create method: response_format: { "type":"json_object" }
Next step is to play with the prompt and instruct the model to output http calls that are meant to execute the steps provided previously as text. The assumption is that all the services used to quarantine emails, notify the security team or monitor network traffic, expose APIs that can be called. This JSON is then parsed by an HTTP client and each request is executed, automating the incident response checklist fully. Here’s how such a JSON response from GPT-4 would look like for a subset of the actions we’ve seen before:
{
"actions": [
{
"action": "quarantine_email",
"description": "Quarantine the email to prevent further distribution",
"http_call": {
"method": "POST",
"url": "https://example.com/quarantine",
"headers": {
"Content-Type": "application/json"
},
"body": {
"email_id": "[email protected]"
}
}
},
{
"action": "notify_security_team",
"description": "Notify the security team to investigate the source and content of the email",
"http_call": {
"method": "POST",
"url": "https://example.com/notify",
"headers": {
"Content-Type": "application/json"
},
"body": {
"message": "Suspicious email detected, please investigate."
}
}
},
{
"action": "monitor_network_traffic",
"description": "Monitor network traffic for any unusual activity or attempted breaches",
"http_call": {
"method": "POST",
"url": "https://example.com/monitor",
"headers": {
"Content-Type": "application/json"
},
"body": {
"target": "all"
}
}
},
]
}
While this seems complex to implement in real life, it is definitely doable. It only needs exposed HTTP services and a client that can interpret and execute the requests. All the adjustments that need to guarantee the compatibility between the model’s response and the downstream services can be achieved through prompt engineering, such as instructing the model to create a request in a way that is supported by your services. If you wish to learn more about prompt engineering, you can check out the related learning path.
Conclusion and further resources
That’s it! We’ve seen two important use cases where we can use GenAI to automate tasks related to cybersecurity. We’ve seen a simplified version of my automated security partner, Dr. CyberGPT, and how I use it to augment how I do threat hunting and incident response.
If you liked this article, make sure to check out my Pluralsight courses, which deal with other cybersecurity-related topics and techniques worth learning about.