agentic-threat-hunting-framework 0.2.2__py3-none-any.whl → 0.2.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {agentic_threat_hunting_framework-0.2.2.dist-info → agentic_threat_hunting_framework-0.2.4.dist-info}/METADATA +1 -1
- agentic_threat_hunting_framework-0.2.4.dist-info/RECORD +47 -0
- athf/__version__.py +1 -1
- athf/cli.py +1 -1
- athf/commands/context.py +29 -15
- athf/commands/hunt.py +1 -3
- athf/commands/init.py +45 -0
- athf/commands/similar.py +2 -2
- athf/core/hunt_manager.py +7 -0
- athf/data/__init__.py +14 -0
- athf/data/docs/CHANGELOG.md +147 -0
- athf/data/docs/CLI_REFERENCE.md +1797 -0
- athf/data/docs/INSTALL.md +594 -0
- athf/data/docs/README.md +31 -0
- athf/data/docs/environment.md +256 -0
- athf/data/docs/getting-started.md +419 -0
- athf/data/docs/level4-agentic-workflows.md +480 -0
- athf/data/docs/lock-pattern.md +149 -0
- athf/data/docs/maturity-model.md +400 -0
- athf/data/docs/why-athf.md +44 -0
- athf/data/hunts/FORMAT_GUIDELINES.md +507 -0
- athf/data/hunts/H-0001.md +453 -0
- athf/data/hunts/H-0002.md +436 -0
- athf/data/hunts/H-0003.md +546 -0
- athf/data/hunts/README.md +231 -0
- athf/data/integrations/MCP_CATALOG.md +45 -0
- athf/data/integrations/README.md +129 -0
- athf/data/integrations/quickstart/splunk.md +162 -0
- athf/data/knowledge/hunting-knowledge.md +2375 -0
- athf/data/prompts/README.md +172 -0
- athf/data/prompts/ai-workflow.md +581 -0
- athf/data/prompts/basic-prompts.md +316 -0
- athf/data/templates/HUNT_LOCK.md +228 -0
- agentic_threat_hunting_framework-0.2.2.dist-info/RECORD +0 -23
- {agentic_threat_hunting_framework-0.2.2.dist-info → agentic_threat_hunting_framework-0.2.4.dist-info}/WHEEL +0 -0
- {agentic_threat_hunting_framework-0.2.2.dist-info → agentic_threat_hunting_framework-0.2.4.dist-info}/entry_points.txt +0 -0
- {agentic_threat_hunting_framework-0.2.2.dist-info → agentic_threat_hunting_framework-0.2.4.dist-info}/licenses/LICENSE +0 -0
- {agentic_threat_hunting_framework-0.2.2.dist-info → agentic_threat_hunting_framework-0.2.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
---
|
|
2
|
+
hunt_id: H-0003
|
|
3
|
+
title: AWS Lambda Persistence Detection
|
|
4
|
+
status: completed
|
|
5
|
+
date: 2025-11-28
|
|
6
|
+
hunter: Sydney Marrone
|
|
7
|
+
platform: [AWS Cloud]
|
|
8
|
+
tactics: [persistence, privilege-escalation]
|
|
9
|
+
techniques: [T1546.004, T1098, T1078.004]
|
|
10
|
+
data_sources: [AWS CloudTrail, AWS Lambda Logs, IAM Access Analyzer]
|
|
11
|
+
related_hunts: []
|
|
12
|
+
findings_count: 2
|
|
13
|
+
true_positives: 2
|
|
14
|
+
false_positives: 0
|
|
15
|
+
customer_deliverables: []
|
|
16
|
+
tags: [aws, lambda, serverless, iam, persistence, api-gateway, eventbridge, cloud]
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# H-0003: AWS Lambda Persistence Detection
|
|
20
|
+
|
|
21
|
+
**Hunt Metadata**
|
|
22
|
+
|
|
23
|
+
- **Date:** 2025-11-28
|
|
24
|
+
- **Hunter:** [Your Name]
|
|
25
|
+
- **Status:** Completed
|
|
26
|
+
- **MITRE ATT&CK:** T1546.004 - Event Triggered Execution, T1098 - Account Manipulation
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## LEARN: Prepare the Hunt
|
|
31
|
+
|
|
32
|
+
### Hypothesis Statement
|
|
33
|
+
|
|
34
|
+
Adversaries with initial access to AWS environments will establish persistence by creating Lambda functions with overly permissive IAM roles, scheduled triggers (EventBridge), or public-facing API Gateway endpoints to maintain backdoor access. These functions can execute on-demand or automatically, enabling long-term control even after initial credentials are revoked.
|
|
35
|
+
|
|
36
|
+
### Threat Context
|
|
37
|
+
|
|
38
|
+
AWS Lambda provides serverless compute that executes code in response to events. Adversaries abuse this by:
|
|
39
|
+
- Creating Lambda functions with administrative IAM roles for privilege escalation
|
|
40
|
+
- Configuring API Gateway to expose functions as public HTTP endpoints
|
|
41
|
+
- Using EventBridge (CloudWatch Events) for scheduled execution
|
|
42
|
+
- Deploying backdoor code for command execution, data exfiltration, or reconnaissance
|
|
43
|
+
|
|
44
|
+
**Key attack patterns:**
|
|
45
|
+
- **Function naming:** Masquerade as legitimate services (`sys-health-check`, `cloudwatch-logs-processor`, `backup-automation`)
|
|
46
|
+
- **IAM roles:** Attach `AdministratorAccess`, `PowerUserAccess`, or overly permissive custom policies
|
|
47
|
+
- **Triggers:** API Gateway (public), EventBridge schedules (periodic), or event source mappings
|
|
48
|
+
- **Code characteristics:** Base64-encoded payloads, reverse shells, environment variable exfiltration, AWS API enumeration
|
|
49
|
+
|
|
50
|
+
This technique maps to:
|
|
51
|
+
- **T1546.004 - Event Triggered Execution:** Lambda functions triggered by events
|
|
52
|
+
- **T1098 - Account Manipulation:** IAM role manipulation for persistence
|
|
53
|
+
- **T1078.004 - Cloud Accounts:** Compromised cloud credentials enable initial Lambda creation
|
|
54
|
+
|
|
55
|
+
Recent threat intel indicates APT groups and initial access brokers increasingly target cloud environments for persistence mechanisms that survive credential rotation.
|
|
56
|
+
|
|
57
|
+
### ABLE Scoping
|
|
58
|
+
|
|
59
|
+
Define your hunt scope using the ABLE framework:
|
|
60
|
+
|
|
61
|
+
| **Field** | **Your Input** |
|
|
62
|
+
|-------------|----------------|
|
|
63
|
+
| **Actor** *(Optional)* | N/A - Focus on behavioral patterns consistent with persistence establishment |
|
|
64
|
+
| **Behavior** | Malicious Lambda function creation with overly permissive IAM roles and public/scheduled triggers (T1546.004, T1098) |
|
|
65
|
+
| **Location** | AWS production accounts (all regions where Lambda is enabled) |
|
|
66
|
+
| **Evidence** | **Source:** AWS CloudTrail<br>**Key Fields:** eventName (CreateFunction, UpdateFunctionConfiguration, AttachRolePolicy, CreateApi, CreateEventSourceMapping), userIdentity, requestParameters, sourceIPAddress, userAgent<br>**Example:** CreateFunction event with requestParameters.role containing AdministratorAccess, followed by CreateApi for API Gateway endpoint |
|
|
67
|
+
|
|
68
|
+
### Threat Intel & Research
|
|
69
|
+
|
|
70
|
+
- **MITRE ATT&CK Techniques:**
|
|
71
|
+
- `T1546.004 - Event Triggered Execution` (Lambda functions respond to events)
|
|
72
|
+
- `T1098 - Account Manipulation` (IAM role escalation)
|
|
73
|
+
- `T1078.004 - Cloud Accounts` (compromised credentials for initial access)
|
|
74
|
+
- `T1098.001 - Additional Cloud Credentials` (IAM role creation)
|
|
75
|
+
- **CTI Sources & References:**
|
|
76
|
+
- [MITRE ATT&CK - T1546.004](https://attack.mitre.org/techniques/T1546/004/)
|
|
77
|
+
- AWS Lambda persistence documented in MITRE Cloud Matrix
|
|
78
|
+
- Multiple APT groups observed using serverless for persistence (public reporting from threat intel vendors)
|
|
79
|
+
- Service account compromise remains primary initial access vector for cloud environments
|
|
80
|
+
- **Historical Context:**
|
|
81
|
+
- Recent trend: Attackers prefer Lambda over EC2 for persistence (harder to detect, lower cost, scales automatically)
|
|
82
|
+
- Known false positives: DevOps automation, CI/CD pipelines, infrastructure-as-code deployments
|
|
83
|
+
- Legitimate use cases: Scheduled Lambda for log processing, API Gateway for microservices, EventBridge for automation
|
|
84
|
+
|
|
85
|
+
### Related Tickets
|
|
86
|
+
|
|
87
|
+
| **Team** | **Ticket/Details** |
|
|
88
|
+
|----------|-------------------|
|
|
89
|
+
| **SOC/IR** | INC-2341 - Compromised IAM service account `developer-jenkins` |
|
|
90
|
+
| **Threat Intel** | TI-0092 - Increased cloud persistence TTPs in recent campaigns |
|
|
91
|
+
| **Detection Engineering** | DET-0058 - Implement Lambda function code analysis for IOCs |
|
|
92
|
+
| **Cloud Security** | CLOUD-0789 - Review and restrict IAM permissions for Lambda roles |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## OBSERVE: Expected Behaviors
|
|
97
|
+
|
|
98
|
+
### What Normal Looks Like
|
|
99
|
+
|
|
100
|
+
Legitimate Lambda activity that should not trigger alerts:
|
|
101
|
+
|
|
102
|
+
- **DevOps automation:** Infrastructure-as-code (Terraform, CloudFormation) creating Lambda functions with documented IAM roles
|
|
103
|
+
- **CI/CD pipelines:** Automated deployments from known service accounts (e.g., `jenkins-prod`, `github-actions`)
|
|
104
|
+
- **Monitoring/logging:** Lambda functions processing CloudWatch Logs, S3 bucket events, or DynamoDB streams
|
|
105
|
+
- **API backends:** Lambda functions behind API Gateway for microservices with appropriate IAM roles (not admin)
|
|
106
|
+
- **Scheduled maintenance:** EventBridge rules triggering Lambda for backups, cleanups, or data processing
|
|
107
|
+
- **Known automation accounts:** Service accounts in whitelist performing legitimate infrastructure operations
|
|
108
|
+
|
|
109
|
+
### What Suspicious Looks Like
|
|
110
|
+
|
|
111
|
+
Adversaries will create Lambda functions to establish persistence. We expect to see:
|
|
112
|
+
|
|
113
|
+
1. **Suspicious IAM policies:**
|
|
114
|
+
- `AdministratorAccess` or `PowerUserAccess` attached to Lambda execution roles
|
|
115
|
+
- Wildcard permissions (e.g., `iam:*`, `s3:*`, `lambda:*`)
|
|
116
|
+
- Privilege escalation paths (e.g., `iam:PassRole`, `iam:AttachRolePolicy`)
|
|
117
|
+
|
|
118
|
+
2. **Unusual triggers:**
|
|
119
|
+
- API Gateway endpoints created for newly deployed functions (public-facing backdoor)
|
|
120
|
+
- EventBridge scheduled rules with unusual frequencies (every minute, odd times)
|
|
121
|
+
- Event source mappings to unexpected services
|
|
122
|
+
|
|
123
|
+
3. **Suspicious timing:**
|
|
124
|
+
- Lambda function created, IAM role attached, and API Gateway configured within minutes
|
|
125
|
+
- Activity outside business hours (e.g., 02:00-05:00 UTC)
|
|
126
|
+
- Rapid succession of Lambda-related API calls
|
|
127
|
+
|
|
128
|
+
4. **Suspicious source:**
|
|
129
|
+
- Residential IPs or VPN exit nodes (not corporate network)
|
|
130
|
+
- User agents from AWS CLI in unexpected locations
|
|
131
|
+
- Service accounts operating from anomalous geolocations
|
|
132
|
+
|
|
133
|
+
5. **Suspicious function characteristics:**
|
|
134
|
+
- Function names masquerading as legitimate services (`sys-health-check`, `cloudwatch-processor`)
|
|
135
|
+
- Runtime mismatches (e.g., Python 3.11 when org standard is Python 3.9)
|
|
136
|
+
- Execution from non-standard regions
|
|
137
|
+
|
|
138
|
+
### Expected Observables
|
|
139
|
+
|
|
140
|
+
- **Processes:** N/A (Lambda is serverless)
|
|
141
|
+
- **Network:** API Gateway endpoints created, HTTP requests to newly created endpoints
|
|
142
|
+
- **Files:** Lambda function code packages (ZIP files), deployment packages in S3
|
|
143
|
+
- **Registry:** N/A (cloud-based hunt)
|
|
144
|
+
- **Authentication:** IAM API calls (CreateFunction, AttachRolePolicy, CreateApi), CloudTrail logs
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## CHECK: Execute & Analyze
|
|
149
|
+
|
|
150
|
+
### Data Source Information
|
|
151
|
+
|
|
152
|
+
- **Index/Data Source:** AWS CloudTrail (all regions)
|
|
153
|
+
- **Time Range:** Last 7 days (2025-11-21 00:00:00 to 2025-11-28 23:59:59)
|
|
154
|
+
- **Events Analyzed:** ~450,000 CloudTrail events (Lambda, IAM, API Gateway, EventBridge)
|
|
155
|
+
- **Data Quality:** Excellent - CloudTrail enabled in all regions, logging to centralized S3 bucket with Splunk ingestion
|
|
156
|
+
|
|
157
|
+
### Hunting Queries
|
|
158
|
+
|
|
159
|
+
#### Initial Query: Monitor All Lambda Function Creations
|
|
160
|
+
|
|
161
|
+
```spl
|
|
162
|
+
index=aws_cloudtrail eventName="CreateFunction"
|
|
163
|
+
| stats count by userIdentity.principalId, requestParameters.functionName, userIdentity.arn, sourceIPAddress
|
|
164
|
+
| sort -count
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Query Notes:**
|
|
168
|
+
|
|
169
|
+
- Returned 89 CreateFunction events over 7-day period
|
|
170
|
+
- 70% from known CI/CD automation accounts (jenkins-prod, github-actions)
|
|
171
|
+
- 20% from developer accounts during business hours (expected)
|
|
172
|
+
- 10% from unexpected sources requiring investigation
|
|
173
|
+
- Most activity during business hours (09:00-17:00 UTC)
|
|
174
|
+
|
|
175
|
+
**Initial Findings:**
|
|
176
|
+
- Overwhelming legitimate activity from DevOps automation
|
|
177
|
+
- Need to filter known automation accounts and focus on IAM policy analysis
|
|
178
|
+
|
|
179
|
+
#### Refined Query: Focus on Suspicious IAM Policies
|
|
180
|
+
|
|
181
|
+
```spl
|
|
182
|
+
index=aws_cloudtrail (eventName="CreateFunction" OR eventName="UpdateFunctionConfiguration")
|
|
183
|
+
| spath input=requestParameters.role output=lambda_role
|
|
184
|
+
| join type=left lambda_role [
|
|
185
|
+
search index=aws_cloudtrail (eventName="PutRolePolicy" OR eventName="AttachRolePolicy")
|
|
186
|
+
| spath input=requestParameters.policyArn output=policy_arn
|
|
187
|
+
| spath input=requestParameters.policyDocument output=policy_doc
|
|
188
|
+
| eval policy=coalesce(policy_arn, policy_doc)
|
|
189
|
+
]
|
|
190
|
+
| where policy="*" OR policy LIKE "%AdministratorAccess%" OR policy LIKE "%PowerUserAccess%" OR policy LIKE "%iam:*%"
|
|
191
|
+
| stats values(eventName) as events,
|
|
192
|
+
values(requestParameters.functionName) as functions,
|
|
193
|
+
values(sourceIPAddress) as source_ips,
|
|
194
|
+
values(policy) as policies
|
|
195
|
+
by userIdentity.principalId, userIdentity.arn, lambda_role
|
|
196
|
+
| sort -count
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Refinement Rationale:**
|
|
200
|
+
|
|
201
|
+
- Shifted focus from all Lambda creations to those with overly permissive IAM roles
|
|
202
|
+
- Joined CreateFunction events with IAM policy attachment events
|
|
203
|
+
- Filtered for administrative policies (AdministratorAccess, PowerUserAccess, wildcard permissions)
|
|
204
|
+
- This identifies potential privilege escalation via Lambda execution roles
|
|
205
|
+
|
|
206
|
+
**Query Results:**
|
|
207
|
+
|
|
208
|
+
- 8 Lambda functions with suspicious IAM policies
|
|
209
|
+
- 5 legitimate admin functions for automation (documented in runbooks)
|
|
210
|
+
- 3 require investigation (unknown accounts, unexpected timing)
|
|
211
|
+
|
|
212
|
+
**Problem:** Still includes legitimate admin Lambda functions for infrastructure automation
|
|
213
|
+
|
|
214
|
+
#### Final Query: Anomaly + Permissions + Trigger Analysis
|
|
215
|
+
|
|
216
|
+
```spl
|
|
217
|
+
index=aws_cloudtrail (eventName="CreateFunction" OR eventName="UpdateFunctionConfiguration" OR eventName="CreateEventSourceMapping")
|
|
218
|
+
| spath input=requestParameters.role output=lambda_role
|
|
219
|
+
| eval function_name=coalesce('requestParameters.functionName', 'requestParameters.FunctionName')
|
|
220
|
+
| join type=left lambda_role [
|
|
221
|
+
search index=aws_cloudtrail eventName="AttachRolePolicy"
|
|
222
|
+
| spath input=requestParameters.policyArn output=policy_arn
|
|
223
|
+
| where policy_arn LIKE "%AdministratorAccess%" OR policy_arn LIKE "%PowerUserAccess%"
|
|
224
|
+
| stats values(policy_arn) as attached_policies by requestParameters.roleName
|
|
225
|
+
| rename requestParameters.roleName as lambda_role
|
|
226
|
+
]
|
|
227
|
+
| join type=left function_name [
|
|
228
|
+
search index=aws_cloudtrail (eventName="CreateEventSourceMapping" OR eventName="CreateApi" OR eventName="CreateRestApi")
|
|
229
|
+
| stats values(eventName) as trigger_events by requestParameters.functionName
|
|
230
|
+
| rename requestParameters.functionName as function_name
|
|
231
|
+
]
|
|
232
|
+
| where NOT [| inputlookup known_automation_accounts.csv | fields userIdentity.principalId]
|
|
233
|
+
| eval time_since_creation=now()-_time
|
|
234
|
+
| where time_since_creation < 3600
|
|
235
|
+
| stats earliest(_time) as first_event,
|
|
236
|
+
latest(_time) as last_event,
|
|
237
|
+
values(eventName) as events,
|
|
238
|
+
values(function_name) as functions,
|
|
239
|
+
values(lambda_role) as roles,
|
|
240
|
+
values(attached_policies) as policies,
|
|
241
|
+
values(trigger_events) as triggers,
|
|
242
|
+
values(sourceIPAddress) as source_ips,
|
|
243
|
+
values(userAgent) as user_agents
|
|
244
|
+
by userIdentity.principalId, userIdentity.arn
|
|
245
|
+
| eval duration_minutes=round((last_event-first_event)/60, 2)
|
|
246
|
+
| where isnotnull(attached_policies) AND isnotnull(triggers)
|
|
247
|
+
| sort -duration_minutes
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Refinement Rationale:**
|
|
251
|
+
|
|
252
|
+
- Multi-dimensional analysis: Lambda creation + IAM policy + trigger mechanism
|
|
253
|
+
- Temporal analysis: Events occurring within 1 hour (indicates rapid setup)
|
|
254
|
+
- Whitelist known automation accounts to reduce false positives
|
|
255
|
+
- Focus on functions with both administrative IAM roles AND public/scheduled triggers
|
|
256
|
+
- This identifies complete persistence setup (function + permissions + accessibility)
|
|
257
|
+
|
|
258
|
+
**Final Results:**
|
|
259
|
+
|
|
260
|
+
- **2 true positives:** Malicious Lambda functions with admin roles and public API Gateway endpoints
|
|
261
|
+
- **0 false positives:** Legitimate automation filtered out via whitelist
|
|
262
|
+
- **Success!** Query identified full attack chain from creation to weaponization
|
|
263
|
+
|
|
264
|
+
### Visualization & Analytics
|
|
265
|
+
|
|
266
|
+
- **Timeline:** Lambda creation events show clustering during maintenance windows (expected) and isolated events during off-hours (suspicious)
|
|
267
|
+
- **Heatmap:** User vs. IAM role shows `developer-jenkins` creating Lambda with `AdministratorAccess` (anomalous)
|
|
268
|
+
- **Network diagram:** API Gateway endpoints linked to suspicious Lambda functions
|
|
269
|
+
- **Geolocation:** Source IPs for suspicious Lambda creations map to residential ISP (103.253.145.22)
|
|
270
|
+
|
|
271
|
+
### Query Performance
|
|
272
|
+
|
|
273
|
+
**What Worked Well:**
|
|
274
|
+
|
|
275
|
+
- CloudTrail comprehensive logging captured full attack lifecycle
|
|
276
|
+
- Join operations between Lambda, IAM, and API Gateway events revealed complete picture
|
|
277
|
+
- Temporal analysis (< 1 hour window) identified rapid setup indicative of attacker behavior
|
|
278
|
+
- Known automation whitelist reduced noise by 87%
|
|
279
|
+
- Multi-event correlation (CreateFunction + AttachRolePolicy + CreateApi) high signal
|
|
280
|
+
|
|
281
|
+
**What Didn't Work:**
|
|
282
|
+
|
|
283
|
+
- Initial query too broad - captured all Lambda activity including legitimate DevOps
|
|
284
|
+
- IAM policy analysis challenging due to varied policy document formats (inline vs. managed)
|
|
285
|
+
- Query performance slow on 7-day window (450k events) - consider reducing to 24-48h for real-time detection
|
|
286
|
+
- No baseline of "normal" Lambda function names to compare against
|
|
287
|
+
- User agent strings inconsistently formatted across AWS CLI versions
|
|
288
|
+
|
|
289
|
+
**Iterations Made:**
|
|
290
|
+
|
|
291
|
+
- Iteration 1: Added IAM policy join to focus on overly permissive roles (reduced results by 70%)
|
|
292
|
+
- Iteration 2: Added trigger analysis (API Gateway, EventBridge) to identify accessibility
|
|
293
|
+
- Iteration 3: Implemented whitelist for known automation accounts
|
|
294
|
+
- Iteration 4: Added temporal analysis (< 1 hour window) to identify rapid setup
|
|
295
|
+
|
|
296
|
+
### Manual Validation Steps
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Retrieve Lambda function configuration
|
|
300
|
+
aws lambda get-function --function-name sys-health-check-v2
|
|
301
|
+
|
|
302
|
+
# Review Lambda function code (download and inspect)
|
|
303
|
+
aws lambda get-function --function-name sys-health-check-v2 --query 'Code.Location'
|
|
304
|
+
|
|
305
|
+
# Check IAM role permissions
|
|
306
|
+
aws iam get-role --role-name lambda-admin-role-temp
|
|
307
|
+
aws iam list-attached-role-policies --role-name lambda-admin-role-temp
|
|
308
|
+
|
|
309
|
+
# List API Gateway endpoints
|
|
310
|
+
aws apigateway get-rest-apis
|
|
311
|
+
|
|
312
|
+
# Check EventBridge rules
|
|
313
|
+
aws events list-rules | grep cloudwatch-logs-processor
|
|
314
|
+
|
|
315
|
+
# Review CloudTrail for additional context
|
|
316
|
+
aws cloudtrail lookup-events --lookup-attributes AttributeKey=Username,AttributeValue=developer-jenkins
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Validation Results:**
|
|
320
|
+
|
|
321
|
+
- Confirmed `sys-health-check-v2` Lambda function contains base64-encoded reverse shell
|
|
322
|
+
- IAM role `lambda-admin-role-temp` has `AdministratorAccess` (full account control)
|
|
323
|
+
- API Gateway endpoint publicly accessible without authentication
|
|
324
|
+
- Source IP 103.253.145.22 maps to residential ISP (suspicious for service account)
|
|
325
|
+
- `developer-jenkins` service account compromised (credentials leaked or stolen)
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## KEEP: Findings & Response
|
|
330
|
+
|
|
331
|
+
### Executive Summary
|
|
332
|
+
|
|
333
|
+
This hunt investigated Lambda-based persistence mechanisms (T1546.004, T1098) in AWS production accounts over a 7-day period. Analysis of 450,000 CloudTrail events identified 89 Lambda function creations, with 2 confirmed malicious functions used for persistence. The hypothesis was fully confirmed: an adversary with compromised service account credentials (`developer-jenkins`) established persistence via Lambda functions with administrative IAM roles and public API Gateway triggers. Both functions were detected within 3 minutes of creation, contained within 20 minutes, and fully remediated within 2 hours. No data exfiltration occurred. Overall, 95% of Lambda activity was legitimate DevOps automation, with 5% requiring investigation.
|
|
334
|
+
|
|
335
|
+
### Findings
|
|
336
|
+
|
|
337
|
+
| **Finding** | **Ticket** | **Description** |
|
|
338
|
+
|-------------|-----------|-----------------|
|
|
339
|
+
| **True Positive** | INC-2341 | Lambda function `sys-health-check-v2` with `AdministratorAccess` and public API Gateway - confirmed malicious backdoor |
|
|
340
|
+
| **True Positive** | INC-2341 | Lambda function `cloudwatch-logs-processor` with recon capabilities on EventBridge schedule - confirmed malicious |
|
|
341
|
+
| **Suspicious** | CLOUD-0789 | 3 additional Lambda functions with overly permissive IAM roles - legitimate but violate least privilege principle |
|
|
342
|
+
| **False Positive** | N/A | 0 false positives after whitelisting known automation accounts |
|
|
343
|
+
|
|
344
|
+
**True Positives:** 2 confirmed malicious Lambda persistence mechanisms
|
|
345
|
+
**False Positives:** 0
|
|
346
|
+
**Suspicious Events:** 3 legitimate functions with excessive IAM permissions (policy violations)
|
|
347
|
+
|
|
348
|
+
### Detection Results
|
|
349
|
+
|
|
350
|
+
**Finding #1: Persistence Lambda (`sys-health-check-v2`)**
|
|
351
|
+
|
|
352
|
+
- **Function Name:** `sys-health-check-v2` (masquerading as legitimate health check)
|
|
353
|
+
- **Runtime:** Python 3.11
|
|
354
|
+
- **IAM Role:** `lambda-admin-role-temp` with `AdministratorAccess` policy
|
|
355
|
+
- **Trigger:** API Gateway endpoint `https://abc123.execute-api.us-east-1.amazonaws.com/prod/health`
|
|
356
|
+
- **Creator:** `arn:aws:iam::123456789012:user/developer-jenkins` (compromised service account)
|
|
357
|
+
- **Source IP:** `103.253.145.22` (residential ISP - suspicious)
|
|
358
|
+
- **User Agent:** `aws-cli/2.13.5 Python/3.11.4`
|
|
359
|
+
- **Created:** 2025-11-28 03:15:42 UTC
|
|
360
|
+
- **Code Analysis:** Base64-encoded reverse shell, environment variable exfiltration, AWS API enumeration
|
|
361
|
+
- **Intent:** On-demand command execution via HTTP requests to API Gateway endpoint
|
|
362
|
+
- **Action Taken:** Lambda function deleted, IAM role removed, API Gateway endpoint deleted
|
|
363
|
+
|
|
364
|
+
**Finding #2: Scheduled Recon Lambda (`cloudwatch-logs-processor`)**
|
|
365
|
+
|
|
366
|
+
- **Function Name:** `cloudwatch-logs-processor` (masquerading as log processing)
|
|
367
|
+
- **Runtime:** Python 3.9
|
|
368
|
+
- **IAM Role:** `lambda-recon-role` with `ReadOnlyAccess` + `iam:ListUsers`, `iam:ListRoles`
|
|
369
|
+
- **Trigger:** EventBridge scheduled rule (every 6 hours)
|
|
370
|
+
- **Creator:** Same compromised `developer-jenkins` account
|
|
371
|
+
- **Source IP:** `103.253.145.22` (same attacker)
|
|
372
|
+
- **Created:** 2025-11-28 03:16:55 UTC
|
|
373
|
+
- **Code Analysis:** AWS API calls to enumerate IAM principals, S3 buckets, EC2 instances
|
|
374
|
+
- **Intent:** Automated reconnaissance for privilege escalation opportunities
|
|
375
|
+
- **Action Taken:** Lambda function deleted, IAM role removed, EventBridge rule deleted
|
|
376
|
+
|
|
377
|
+
### Timeline
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
2025-11-28 03:15:42 - CreateFunction event for sys-health-check-v2 detected
|
|
381
|
+
2025-11-28 03:16:18 - AttachRolePolicy event: AdministratorAccess attached to lambda-admin-role-temp
|
|
382
|
+
2025-11-28 03:16:55 - CreateFunction event for cloudwatch-logs-processor detected
|
|
383
|
+
2025-11-28 03:17:05 - CreateApi event: API Gateway endpoint created for sys-health-check-v2
|
|
384
|
+
2025-11-28 03:17:42 - CreateRule event: EventBridge rule created for cloudwatch-logs-processor
|
|
385
|
+
2025-11-28 03:18:33 - DETECTION ALERT TRIGGERED (automated CloudWatch Logs Insights query)
|
|
386
|
+
2025-11-28 03:22:15 - Incident response analyst begins investigation (INC-2341 created)
|
|
387
|
+
2025-11-28 03:28:45 - Lambda function code retrieved and analyzed (confirmed malicious)
|
|
388
|
+
2025-11-28 03:35:47 - Containment: Lambda functions deleted, IAM roles removed, API Gateway deleted
|
|
389
|
+
2025-11-28 03:45:12 - EventBridge rule deleted
|
|
390
|
+
2025-11-28 04:12:22 - Compromised service account credentials rotated
|
|
391
|
+
2025-11-28 05:30:00 - SCPs implemented to restrict Lambda IAM role permissions
|
|
392
|
+
2025-11-28 08:00:00 - Incident response complete, forensics finalized
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Impact Metrics
|
|
396
|
+
|
|
397
|
+
| Metric | Value |
|
|
398
|
+
|--------|-------|
|
|
399
|
+
| **Time to Detection** | 3 minutes from Lambda creation |
|
|
400
|
+
| **Time to Investigation Start** | 6 minutes from detection |
|
|
401
|
+
| **Time to Containment** | 20 minutes from detection |
|
|
402
|
+
| **Total Incident Duration** | ~5 hours (creation to full remediation) |
|
|
403
|
+
| **Lambda Functions Created** | 2 malicious functions |
|
|
404
|
+
| **IAM Roles Created** | 2 roles with excessive permissions |
|
|
405
|
+
| **API Gateway Endpoints** | 1 publicly accessible backdoor |
|
|
406
|
+
| **EventBridge Rules** | 1 scheduled recon task |
|
|
407
|
+
| **Compromised Accounts** | 1 service account (`developer-jenkins`) |
|
|
408
|
+
| **Data Exfiltration** | 0 (contained before attacker executed functions) |
|
|
409
|
+
| **Lambda Execution Cost** | $0.47 (attacker testing, minimal invocations) |
|
|
410
|
+
| **Blast Radius Prevented** | Full AWS account compromise (AdministratorAccess available) |
|
|
411
|
+
| **False Positives** | 0 (after automation whitelist) |
|
|
412
|
+
|
|
413
|
+
### Detection Logic
|
|
414
|
+
|
|
415
|
+
**Automation Opportunity:**
|
|
416
|
+
|
|
417
|
+
This hunt can be fully automated with the following approach:
|
|
418
|
+
|
|
419
|
+
- Real-time CloudWatch Logs Insights queries on CloudTrail logs
|
|
420
|
+
- Alert on Lambda creation with administrative IAM policies AND public/scheduled triggers
|
|
421
|
+
- Baseline known automation accounts and IAM role naming conventions
|
|
422
|
+
- Correlate Lambda activity with IAM policy attachment and API Gateway creation
|
|
423
|
+
- Lambda trigger for automated initial containment (disable function, notify SOC)
|
|
424
|
+
|
|
425
|
+
**Proposed Detection:**
|
|
426
|
+
|
|
427
|
+
```spl
|
|
428
|
+
# Automated Lambda Persistence Detection Rule
|
|
429
|
+
# Run every 5 minutes, alert on suspicious Lambda + IAM + Trigger combinations
|
|
430
|
+
index=aws_cloudtrail earliest=-5m
|
|
431
|
+
(eventName="CreateFunction" OR eventName="UpdateFunctionConfiguration" OR eventName="AttachRolePolicy" OR eventName="CreateApi" OR eventName="CreateRule")
|
|
432
|
+
| spath input=requestParameters.role output=lambda_role
|
|
433
|
+
| spath input=requestParameters.policyArn output=policy_arn
|
|
434
|
+
| eval function_name=coalesce('requestParameters.functionName', 'requestParameters.FunctionName')
|
|
435
|
+
| eval is_admin_policy=if(match(policy_arn, "AdministratorAccess|PowerUserAccess"), "true", "false")
|
|
436
|
+
| stats earliest(_time) as first_event,
|
|
437
|
+
latest(_time) as last_event,
|
|
438
|
+
values(eventName) as events,
|
|
439
|
+
dc(eventName) as unique_events,
|
|
440
|
+
values(function_name) as functions,
|
|
441
|
+
values(lambda_role) as roles,
|
|
442
|
+
values(policy_arn) as policies,
|
|
443
|
+
values(sourceIPAddress) as source_ips,
|
|
444
|
+
max(is_admin_policy) as has_admin_policy
|
|
445
|
+
by userIdentity.principalId, userIdentity.arn
|
|
446
|
+
| where unique_events >= 2 AND has_admin_policy="true"
|
|
447
|
+
| lookup known_automation_accounts.csv userIdentity.principalId OUTPUT is_known
|
|
448
|
+
| where isnull(is_known) OR is_known="false"
|
|
449
|
+
| eval duration_seconds=last_event-first_event
|
|
450
|
+
| where duration_seconds < 1800
|
|
451
|
+
| eval severity=case(
|
|
452
|
+
has_admin_policy="true" AND match(events, "CreateApi|CreateRule"), "critical",
|
|
453
|
+
has_admin_policy="true", "high",
|
|
454
|
+
1==1, "medium"
|
|
455
|
+
)
|
|
456
|
+
| eval description="Suspicious Lambda persistence detected: ".userIdentity.arn." created function(s) ".functions." with admin IAM role and trigger"
|
|
457
|
+
| table first_event, severity, userIdentity.arn, functions, roles, policies, events, source_ips, description
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
**Detection Deployment:**
|
|
461
|
+
|
|
462
|
+
- Scheduled as CloudWatch Logs Insights query with SNS notification
|
|
463
|
+
- Integrated with Lambda function for automated initial containment:
|
|
464
|
+
- Disable suspicious Lambda function
|
|
465
|
+
- Remove IAM role policies
|
|
466
|
+
- Create incident ticket in JIRA
|
|
467
|
+
- Notify SOC via Slack
|
|
468
|
+
- Snapshot function code for forensics
|
|
469
|
+
|
|
470
|
+
### Lessons Learned
|
|
471
|
+
|
|
472
|
+
**What Worked Well:**
|
|
473
|
+
|
|
474
|
+
- CloudTrail comprehensive logging provided full attack visibility
|
|
475
|
+
- Multi-event correlation (Lambda + IAM + triggers) identified complete attack chain
|
|
476
|
+
- Temporal analysis (rapid succession within 1 hour) strong indicator of malicious activity
|
|
477
|
+
- Known automation whitelist eliminated 87% of false positives
|
|
478
|
+
- Real-time alerting enabled detection within 3 minutes of Lambda creation
|
|
479
|
+
- Automated incident response reduced containment time from hours to minutes
|
|
480
|
+
|
|
481
|
+
**What Could Be Improved:**
|
|
482
|
+
|
|
483
|
+
- Baseline of "normal" Lambda function naming conventions needed
|
|
484
|
+
- Lambda function code analysis not automated (requires manual download and inspection)
|
|
485
|
+
- Service account credential security needs strengthening (MFA, short-lived credentials)
|
|
486
|
+
- IAM policy least privilege principle not enforced (too many admin roles for Lambda)
|
|
487
|
+
- Threat intel integration for malicious IPs/user agents would improve context
|
|
488
|
+
|
|
489
|
+
**Telemetry Gaps Identified:**
|
|
490
|
+
|
|
491
|
+
- No automated Lambda function code scanning for IOCs (base64, reverse shells, exfiltration)
|
|
492
|
+
- Lambda execution logs not centralized (only creation events monitored)
|
|
493
|
+
- API Gateway access logs not enabled (no visibility into function invocations)
|
|
494
|
+
- EventBridge rule invocations not logged (can't confirm if recon Lambda executed)
|
|
495
|
+
- IAM Access Analyzer alerts not integrated with SIEM (delayed visibility)
|
|
496
|
+
|
|
497
|
+
### Remediation Actions
|
|
498
|
+
|
|
499
|
+
1. **Immediate Containment (Completed):**
|
|
500
|
+
- [x] Deleted malicious Lambda functions (`sys-health-check-v2`, `cloudwatch-logs-processor`)
|
|
501
|
+
- [x] Removed IAM roles (`lambda-admin-role-temp`, `lambda-recon-role`)
|
|
502
|
+
- [x] Deleted API Gateway endpoint (public backdoor)
|
|
503
|
+
- [x] Removed EventBridge scheduled rule
|
|
504
|
+
- [x] Rotated compromised service account credentials (`developer-jenkins`)
|
|
505
|
+
- [x] Reviewed all Lambda functions created by compromised account (no additional malicious functions)
|
|
506
|
+
|
|
507
|
+
2. **Preventive Controls (In Progress):**
|
|
508
|
+
- [x] Implemented Service Control Policies (SCPs) to restrict Lambda IAM role permissions (max `PowerUserAccess`)
|
|
509
|
+
- [x] Enabled IAM Access Analyzer for continuous policy analysis
|
|
510
|
+
- [ ] Enforce MFA for all service accounts (target: 2025-12-05) - CLOUD-0790
|
|
511
|
+
- [ ] Implement short-lived credentials for CI/CD pipelines (target: 2025-12-15) - CLOUD-0791
|
|
512
|
+
- [ ] Deploy Lambda function code scanning for IOCs (target: 2026-01-10) - DET-0058
|
|
513
|
+
|
|
514
|
+
3. **Detective Controls (In Progress):**
|
|
515
|
+
- [x] Deployed automated Lambda persistence detection rule (5-minute frequency)
|
|
516
|
+
- [x] Enabled API Gateway access logging for all endpoints
|
|
517
|
+
- [ ] Centralize Lambda execution logs in SIEM (target: 2025-12-10) - CLOUD-0792
|
|
518
|
+
- [ ] Integrate IAM Access Analyzer findings with SOAR (target: 2025-12-20) - DET-0059
|
|
519
|
+
- [ ] Create dashboard for Lambda creation activity and IAM role analysis
|
|
520
|
+
|
|
521
|
+
4. **Playbook Development:**
|
|
522
|
+
- [x] Documented Lambda persistence detection and response playbook for SOC
|
|
523
|
+
- [x] Created runbook for Lambda function code analysis
|
|
524
|
+
- [x] Updated incident response procedures for cloud persistence
|
|
525
|
+
|
|
526
|
+
### Follow-up Actions
|
|
527
|
+
|
|
528
|
+
- [x] Escalate INC-2341 to incident response (completed, forensics finalized)
|
|
529
|
+
- [x] Create baseline inventory of legitimate Lambda functions and automation accounts (target: 2025-12-01)
|
|
530
|
+
- [ ] Conduct security review of all existing Lambda functions for excessive IAM permissions (target: 2025-12-15) - CLOUD-0793
|
|
531
|
+
- [ ] Implement Lambda function code signing to prevent unauthorized modifications (target: 2026-01-30) - CLOUD-0794
|
|
532
|
+
- [ ] Deploy AWS GuardDuty for additional serverless threat detection (target: 2026-02-15) - CLOUD-0795
|
|
533
|
+
- [ ] Schedule recurring hunt execution (monthly) for Lambda persistence patterns
|
|
534
|
+
- [ ] Threat intel sharing: Submit IOCs to MISP (IP, function names, code hashes)
|
|
535
|
+
|
|
536
|
+
### Follow-up Hunts
|
|
537
|
+
|
|
538
|
+
- H-0012: AWS Step Functions Persistence Detection (T1546.004)
|
|
539
|
+
- H-0013: EventBridge Rule Abuse for Persistence
|
|
540
|
+
- H-0014: IAM Role Privilege Escalation Patterns
|
|
541
|
+
- H-0015: S3 Bucket Event-Driven Lambda Backdoors
|
|
542
|
+
- H-0016: Cross-Account Lambda Invocation Analysis
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
**Hunt Completed:** 2025-11-28
|