General Writeups & Problem Solving

HackTheBox RoadMap — Phase 2: Service Enumeration

AUTHORCyberAlp0
READ TIME02 MIN
HackTheBox RoadMap — Phase 2: Service Enumeration

In Part 1 we scanned the target and noted every open port. Now comes the phase where you should spend the most time: service enumeration. Enumerate every open service — this is where footholds are found.

Firstly: HTTP/HTTPS (Port 80/443)

Add the host name to /etc/hosts:

echo "<target_ip> <hostname>.htb" | sudo tee -a /etc/hosts

Secondly: Manual checks

  • View the website in the browser.
  • Read the page source (Ctrl+U) for comments and hidden fields.
  • Check /robots.txt and /sitemap.xml.
  • Identify the tech stack from headers, extensions, and cookies.
  • Look for login forms, search bars, and file upload features.

Thirdly: Directory brute-forcing using gobuster

gobuster dir -u http://target -w /usr/share/wordlists/dirb/common.txt
gobuster dir -u http://target -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt

Fourthly: Directory brute-forcing using ffuf

ffuf -u http://target/FUZZ -w /usr/share/wordlists/dirb/common.txt

Fifthly: Subdomain enumeration

Method 1: Using Gobuster

gobuster vhost -u http://target.htb -w /usr/share/wordlists/subdomains-top1million-5000.txt

Method 2: Using ffuf

ffuf -u http://target.htb -H "Host: FUZZ.target.htb" -w /usr/share/wordlists/subdomains-top1million-5000.txt
ffuf -u http://TARGET.htb -H "Host: FUZZ.TARGET.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -fs SIZE_OF_DEFAULT_PAGE

To find the default page size first, execute the following command:

curl -s http://TARGET.htb | wc -c

Use that number with -fs to filter out false positives.

Method 3: Viewing the source code

On every page you access — especially admin panels — press Ctrl+U and search for: http, href, src, internal, admin, api, dev, staging.

Developers leave references to internal services in HTML, JavaScript files, and comments.

Method 4: DNS Zone Transfer

dig axfr TARGET.htb @TARGET_IP

If the DNS server is misconfigured, it dumps all subdomains at once.

Method 5: JavaScript File Analysis

# Find JS files
curl -s http://TARGET.htb | grep -oP 'src="[^"]*\.js"'
# Search for URLs inside them
curl -s http://TARGET.htb/static/js/main.js | grep -oP 'https?://[a-zA-Z0-9.-]+'

Method 6: Public OSINT (Real-World Only)

# Certificate transparency logs
curl -s "https://crt.sh/?q=%.TARGET.com&output=json" | jq '.[].name_value' | sort -u
# Sublist3r
python3 sublist3r.py -d TARGET.com
# Amass
amass enum -d TARGET.com

After Finding a Subdomain

Always add it to /etc/hosts:

echo "TARGET_IP subdomain.TARGET.htb" | sudo tee -a /etc/hosts

Then access it in the browser and continue enumeration.

Sixth: Vulnerability scanner

nikto -h http://target

Seventh: Enumerating Common Services

1 — FTP (Port 21)

ftp <target_ip>
# Try anonymous login: anonymous / anonymous
# If logged in:
ls -la
get <filename>

2 — SSH (Port 22)

  • Don't brute-force unless you have a username
  • Come back when you find credentials
  • Check for outdated versions with known CVEs

3 — SMB (Port 139/445)

smbclient -L //<target_ip> -N
smbmap -H <target_ip>
enum4linux -a <target_ip>
crackmapexec smb <target_ip> --shares

4 — DNS (Port 53)

dig axfr <hostname>.htb @<target_ip>
dig any <hostname>.htb @<target_ip>

5 — SNMP (UDP Port 161)

snmpwalk -v2c -c public <target_ip>

6 — MySQL (Port 3306)

mysql -h <target_ip> -u root -p

7 — Redis (Port 6379)

redis-cli -h <target_ip>
info
keys *

8 — WinRM (Port 5985)

evil-winrm -i <target_ip> -u <username> -p <password>

Real-world notes

  • On an AD box, SMB is where the foothold usually hides. The box allowed an anonymous / guest null session (nxc smb <IP> -u 'guest' -p) showed (Null Auth: True), which exposed a custom readable share — ignore the defaults (ADMIN$, C#, IPC#, SYSVOL, NETLOGON) and chase anything else. Lesson: always open readable shares and actually read the documents left in them — credentials love to hide in "harmless" files.
  • When you find a credential, validate it before trusting it, and check how far it goes. and note that: [+] without pwned! means valid password but no WinRM shell — normal for low-priv accounts. You'll need another way in (see Part 4).
nxc smb  <ip> -u 'user' -p 'pass'     # is the password valid?

nxc winrm <ip> -u 'user' -p 'pass'    # (Pwn3d!) = you also get a shell

Next up — Part 3: Vulnerability Identification, where we turn enumeration findings into concrete attack vectors.

[ #hackthebox ][ #enumeration ][ #gobuster ][ #ffuf ][ #subdomain-enumeration ][ #smb ][ #winrm ][ #penetration-testing ][ #oscp ][ #infosec ][ #CyberSkii ][ #cyberalp0 ]
Need help? Contact us