Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aws): add checks for Bedrock logging configuration and CloudTrail LLM Jacking detection #5314

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions docs/tutorials/aws/threat-detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ Prowler allows you to do threat detection in AWS based on the CloudTrail log rec
```
prowler aws --category threat-detection
```
This comand will run these checks:
This command will run these checks:

* `cloudtrail_threat_detection_privilege_escalation`
* `cloudtrail_threat_detection_enumeration`
* `cloudtrail_threat_detection_privilege_escalation` -> Detects privilege escalation attacks.
* `cloudtrail_threat_detection_enumeration` -> Detects enumeration attacks.
* `cloudtrail_threat_detection_llm_jacking` -> Detects LLM Jacking attacks.

???+ note
Threat Detection checks will be only executed using `--category threat-detection` flag due to preformance.
Threat Detection checks will be only executed using `--category threat-detection` flag due to performance.

## Config File

If you want to manage the behavior of the Threat Detection checks you can edit `config.yaml` file from `/prowler/config`. In this file you can edit the following attributes related with Threat Detection:

* `threat_detection_privilege_escalation_threshold`: determines the percentage of actions found to decide if it is an privilege_scalation attack event, by default is 0.1 (10%)
* `threat_detection_privilege_escalation_threshold`: determines the percentage of actions found to decide if it is an privilege_scalation attack event, by default is 0.2 (20%)
* `threat_detection_privilege_escalation_minutes`: it is the past minutes to search from now for privilege_escalation attacks, by default is 1440 minutes (24 hours)
* `threat_detection_privilege_escalation_actions`: these are the default actions related with priviledge scalation.
* `threat_detection_enumeration_threshold`: determines the percentage of actions found to decide if it is an enumeration attack event, by default is 0.1 (10%)
* `threat_detection_privilege_escalation_actions`: these are the default actions related with privilege escalation.
* `threat_detection_enumeration_threshold`: determines the percentage of actions found to decide if it is an enumeration attack event, by default is 0.3 (30%)
* `threat_detection_enumeration_minutes`: it is the past minutes to search from now for enumeration attacks, by default is 1440 minutes (24 hours)
* `threat_detection_enumeration_actions`: these are the default actions related with enumeration attacks.
* `threat_detection_llm_jacking_threshold`: determines the percentage of actions found to decide if it is an LLM Jacking attack event, by default is 0.4 (40%)
* `threat_detection_llm_jacking_minutes`: it is the past minutes to search from now for LLM Jacking attacks, by default is 1440 minutes (24 hours)
* `threat_detection_llm_jacking_actions`: these are the default actions related with LLM Jacking attacks.
22 changes: 20 additions & 2 deletions docs/tutorials/configuration_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ aws:

# AWS CloudTrail Configuration
# aws.cloudtrail_threat_detection_privilege_escalation
threat_detection_privilege_escalation_threshold: 0.1 # Percentage of actions found to decide if it is an privilege_escalation attack event, by default is 0.1 (10%)
threat_detection_privilege_escalation_threshold: 0.2 # Percentage of actions found to decide if it is an privilege_escalation attack event, by default is 0.2 (20%)
threat_detection_privilege_escalation_minutes: 1440 # Past minutes to search from now for privilege_escalation attacks, by default is 1440 minutes (24 hours)
threat_detection_privilege_escalation_actions:
[
Expand Down Expand Up @@ -283,7 +283,7 @@ aws:
"UpdateLoginProfile",
]
# aws.cloudtrail_threat_detection_enumeration
threat_detection_enumeration_threshold: 0.1 # Percentage of actions found to decide if it is an enumeration attack event, by default is 0.1 (10%)
threat_detection_enumeration_threshold: 0.3 # Percentage of actions found to decide if it is an enumeration attack event, by default is 0.3 (30%)
threat_detection_enumeration_minutes: 1440 # Past minutes to search from now for enumeration attacks, by default is 1440 minutes (24 hours)
threat_detection_enumeration_actions:
[
Expand Down Expand Up @@ -378,6 +378,24 @@ aws:
"LookupEvents",
"Search",
]
# aws.cloudtrail_threat_detection_llm_jacking
threat_detection_llm_jacking_threshold: 0.4 # Percentage of actions found to decide if it is an LLM Jacking attack event, by default is 0.4 (40%)
threat_detection_llm_jacking_minutes: 1440 # Past minutes to search from now for LLM Jacking attacks, by default is 1440 minutes (24 hours)
threat_detection_llm_jacking_actions:
[
"PutUseCaseForModelAccess", # Submits a use case for model access, providing justification (Write).
"PutFoundationModelEntitlement", # Grants entitlement for accessing a foundation model (Write).
"PutModelInvocationLoggingConfiguration", # Configures logging for model invocations (Write).
"CreateFoundationModelAgreement", # Creates a new agreement to use a foundation model (Write).
"InvokeModel", # Invokes a specified Bedrock model for inference using provided prompt and parameters (Read).
"InvokeModelWithResponseStream", # Invokes a Bedrock model for inference with real-time token streaming (Read).
"GetUseCaseForModelAccess", # Retrieves an existing use case for model access (Read).
"GetModelInvocationLoggingConfiguration", # Fetches the logging configuration for model invocations (Read).
"GetFoundationModelAvailability", # Checks the availability of a foundation model for use (Read).
"ListFoundationModelAgreementOffers", # Lists available agreement offers for accessing foundation models (List).
"ListFoundationModels", # Lists the available foundation models in Bedrock (List).
"ListProvisionedModelThroughputs", # Lists the provisioned throughput for previously created models (List).
]

# AWS RDS Configuration
# aws.rds_instance_backup_enabled
Expand Down
22 changes: 20 additions & 2 deletions prowler/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ aws:

# AWS CloudTrail Configuration
# aws.cloudtrail_threat_detection_privilege_escalation
threat_detection_privilege_escalation_threshold: 0.1 # Percentage of actions found to decide if it is an privilege_escalation attack event, by default is 0.1 (10%)
threat_detection_privilege_escalation_threshold: 0.2 # Percentage of actions found to decide if it is an privilege_escalation attack event, by default is 0.2 (20%)
threat_detection_privilege_escalation_minutes: 1440 # Past minutes to search from now for privilege_escalation attacks, by default is 1440 minutes (24 hours)
threat_detection_privilege_escalation_actions:
[
Expand Down Expand Up @@ -190,7 +190,7 @@ aws:
"UpdateLoginProfile",
]
# aws.cloudtrail_threat_detection_enumeration
threat_detection_enumeration_threshold: 0.1 # Percentage of actions found to decide if it is an enumeration attack event, by default is 0.1 (10%)
threat_detection_enumeration_threshold: 0.3 # Percentage of actions found to decide if it is an enumeration attack event, by default is 0.3 (30%)
threat_detection_enumeration_minutes: 1440 # Past minutes to search from now for enumeration attacks, by default is 1440 minutes (24 hours)
threat_detection_enumeration_actions:
[
Expand Down Expand Up @@ -285,6 +285,24 @@ aws:
"LookupEvents",
"Search",
]
# aws.cloudtrail_threat_detection_llm_jacking
threat_detection_llm_jacking_threshold: 0.4 # Percentage of actions found to decide if it is an LLM Jacking attack event, by default is 0.4 (40%)
threat_detection_llm_jacking_minutes: 1440 # Past minutes to search from now for LLM Jacking attacks, by default is 1440 minutes (24 hours)
threat_detection_llm_jacking_actions:
[
"PutUseCaseForModelAccess", # Submits a use case for model access, providing justification (Write).
"PutFoundationModelEntitlement", # Grants entitlement for accessing a foundation model (Write).
"PutModelInvocationLoggingConfiguration", # Configures logging for model invocations (Write).
"CreateFoundationModelAgreement", # Creates a new agreement to use a foundation model (Write).
"InvokeModel", # Invokes a specified Bedrock model for inference using provided prompt and parameters (Read).
"InvokeModelWithResponseStream", # Invokes a Bedrock model for inference with real-time token streaming (Read).
"GetUseCaseForModelAccess", # Retrieves an existing use case for model access (Read).
"GetModelInvocationLoggingConfiguration", # Fetches the logging configuration for model invocations (Read).
"GetFoundationModelAvailability", # Checks the availability of a foundation model for use (Read).
"ListFoundationModelAgreementOffers", # Lists available agreement offers for accessing foundation models (List).
"ListFoundationModels", # Lists the available foundation models in Bedrock (List).
"ListProvisionedModelThroughputs", # Lists the provisioned throughput for previously created models (List).
]

# AWS RDS Configuration
# aws.rds_instance_backup_enabled
Expand Down
Empty file.
4 changes: 4 additions & 0 deletions prowler/providers/aws/services/bedrock/bedrock_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from prowler.providers.aws.services.bedrock.bedrock_service import Bedrock
from prowler.providers.common.provider import Provider

bedrock_client = Bedrock(Provider.get_global_provider())
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"Provider": "aws",
"CheckID": "bedrock_model_invocation_logging_enabled",
"CheckTitle": "Ensure that model invocation logging is enabled for Amazon Bedrock.",
"CheckType": [],
"ServiceName": "bedrock",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:bedrock:region:account-id:model/resource-id",
"Severity": "medium",
"ResourceType": "Other",
"Description": "Ensure that model invocation logging is enabled for Amazon Bedrock service in order to collect metadata, requests, and responses for all model invocations in your AWS cloud account.",
"Risk": "In Amazon Bedrock, model invocation logging enables you to collect the invocation request and response data, along with metadata, for all 'Converse', 'ConverseStream', 'InvokeModel', and 'InvokeModelWithResponseStream' API calls in your AWS account. Each log entry includes important details such as the timestamp, request ID, model ID, and token usage. Invocation logs can be utilized for troubleshooting, performance enhancements, abuse detection, and security auditing. By default, model invocation logging is disabled.",
"RelatedUrl": "https://docs.aws.amazon.com/bedrock/latest/userguide/model-invocation-logging.html",
"Remediation": {
"Code": {
"CLI": "aws bedrock put-model-invocation-logging-configuration --logging-config 's3Config={bucketName='tm-bedrock-logging-data',keyPrefix='invocation-logs'},textDataDeliveryEnabled=true,imageDataDeliveryEnabled=true,embeddingDataDeliveryEnabled=true'",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Bedrock/enable-model-invocation-logging.html",
"Terraform": ""
},
"Recommendation": {
"Text": "Enable model invocation logging for Amazon Bedrock service in order to collect metadata, requests, and responses for all model invocations in your AWS cloud account.",
"Url": "https://docs.aws.amazon.com/bedrock/latest/userguide/model-invocation-logging.html#model-invocation-logging-console"
}
},
"Categories": [
"logging",
"forensics-ready"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.bedrock.bedrock_client import bedrock_client


class bedrock_model_invocation_logging_enabled(Check):
def execute(self):
findings = []
for region, logging in bedrock_client.logging_configurations.items():
report = Check_Report_AWS(self.metadata())
report.region = region
report.resource_id = bedrock_client.audited_account
report.resource_arn = bedrock_client.audited_account_arn
report.status = "FAIL"
report.status_extended = "Bedrock Model Invocation Logging is disabled."
if logging.enabled:
report.status = "PASS"
report.status_extended = "Bedrock Model Invocation Logging is enabled"
if logging.cloudwatch_log_group and logging.s3_bucket:
report.status_extended += f" in CloudWatch Log Group: {logging.cloudwatch_log_group} and S3 Bucket: {logging.s3_bucket}."
elif logging.cloudwatch_log_group:
report.status_extended += (
f" in CloudWatch Log Group: {logging.cloudwatch_log_group}."
)
elif logging.s3_bucket:
report.status_extended += f" in S3 Bucket: {logging.s3_bucket}."

findings.append(report)

return findings
47 changes: 47 additions & 0 deletions prowler/providers/aws/services/bedrock/bedrock_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from typing import Optional

from pydantic import BaseModel

from prowler.lib.logger import logger
from prowler.providers.aws.lib.service.service import AWSService


class Bedrock(AWSService):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, provider)
self.logging_configurations = {}
self.__threading_call__(self._get_model_invocation_logging_configuration)

def _get_model_invocation_logging_configuration(self, regional_client):
logger.info("Bedrock - Getting Model Invocation Logging Configuration...")
try:
logging_config = (
regional_client.get_model_invocation_logging_configuration().get(
"loggingConfig", {}
)
)
if logging_config:
self.logging_configurations[regional_client.region] = (
LoggingConfiguration(
cloudwatch_log_group=logging_config.get(
"cloudWatchConfig", {}
).get("logGroupName"),
s3_bucket=logging_config.get("s3Config", {}).get("bucketName"),
enabled=True,
)
)
else:
self.logging_configurations[regional_client.region] = (
LoggingConfiguration(enabled=False)
)
except Exception as error:
logger.error(

Check warning on line 39 in prowler/providers/aws/services/bedrock/bedrock_service.py

View check run for this annotation

Codecov / codecov/patch

prowler/providers/aws/services/bedrock/bedrock_service.py#L38-L39

Added lines #L38 - L39 were not covered by tests
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)


class LoggingConfiguration(BaseModel):
enabled: bool = False
cloudwatch_log_group: Optional[str] = None
s3_bucket: Optional[str] = None
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class cloudtrail_threat_detection_enumeration(Check):
def execute(self):
findings = []
threshold = cloudtrail_client.audit_config.get(
"threat_detection_enumeration_threshold", 0.1
"threat_detection_enumeration_threshold", 0.3
)
threat_detection_minutes = cloudtrail_client.audit_config.get(
"threat_detection_enumeration_minutes", 1440
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"Provider": "aws",
"CheckID": "cloudtrail_threat_detection_llm_jacking",
"CheckTitle": "Ensure there are no potential LLM Jacking threats in CloudTrail.",
"CheckType": [],
"ServiceName": "cloudtrail",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "critical",
"ResourceType": "AwsCloudTrailTrail",
"Description": "This check ensures that there are no potential LLM Jacking threats in CloudTrail. LLM Jacking attacks involve unauthorized access to cloud-hosted large language model (LLM) services, such as AWS Bedrock, by exploiting exposed credentials or vulnerabilities. These attacks can lead to resource hijacking, unauthorized model invocations, and high operational costs for the victim organization.",
"Risk": "Potential LLM Jacking threats in CloudTrail can lead to unauthorized access to sensitive AI models, stolen credentials, resource hijacking, or running costly workloads. Attackers may use reverse proxies or malicious credentials to sell access to models, exfiltrate sensitive data, or disrupt business operations.",
"RelatedUrl": "https://sysdig.com/blog/llmjacking-stolen-cloud-credentials-used-in-new-ai-attack/",
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "To remediate this issue, enable detailed CloudTrail logging for Bedrock API calls, monitor suspicious activities, and secure sensitive credentials. Enable logging of model invocation inputs and outputs, and restrict access using IAM policies. Review CloudTrail logs regularly for suspicious `InvokeModel` actions or unauthorized access to models.",
"Url": "https://permiso.io/blog/exploiting-hosted-models"
}
},
"Categories": [
"threat-detection"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
Loading