Pentest Notes / Enumeration / Web Enumeration
Active
• ping
• traceroute or tracert
• telnet (not imp)
• nc (to grab banners during initial connection)
• Add domain to /etc/hosts: echo "[IP] [domain]" | sudo tee -a /etc/hosts
Directories and file enumeration
gobuster dir -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -x html,txt,php, js -u http://[MACHINE_IP]
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php, txt, html, js -u http://[MACHINE_IP]
ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -u http://[MACHINE_IP] -e .html,.txt.,php,.js
Subdomain Enumeration
DNS bruteforce:
gobuster:
gobuster dns --domain [example.thm] -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
ffuf:
ffuf -w /usr/share/wordlists/SecLists/Discovery/DNS/namelist.txt -H "Host: FUZZ.acmeitsupport.thm" -u http://[MACHINE_IP]
use ip address, sometimes the name wont work even after adding it to /etc/hosts
Filter by size of response:
ffuf -w /usr/share/wordlists/SecLists/Discovery/DNS/namelist.txt -fs {size} -H "Host: FUZZ.[MACHINE_IP]" -u http://[MACHINE_IP]
Virtual Host Enumeration
gobuster vhost -u http://[MACHINE_IP] --domain example.thm -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain
FeroxBuster
Discovers unlinked content in web applications
Install: curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/main/install-nix.sh | sudo bash -s $HOME/.local/bin
API Fuzzing
git clone https://github.com/PandaSt0rm/webfuzz_api.git
cd webfuzz_api
pip3 install -r requirements.txt
python3 api_fuzzer.py http://IP:PORT
https://tryhackme.com/room/modernwebstacks
Fingerprinting MERN
Header check:
| Signal | Value | Confidence | Comment |
|---|---|---|---|
| X-Powered-By header | Express | High | Express sends by default, absent only if app.disable('x-powered-by') is called |
| Set-Cookie header | connect.sid=s%3A... | High | Absence of this doesn't mean absense of express |
| Unhandled route response | Cannot GET /nonexistent (plain text) | High | curl -I MACHINE_IP:3000/nonexistent : Returns plaintext rather than error |
Fingerprinting Next.js
Possible CVE: CVE-2025-29927 and CVE-2025-55182
| Signal | Value | Confidence |
|---|---|---|
| X-Powered-By header | Next.js | High |
| HTML source | window.__next_f in script tag | High (confirms App Router) |
| Static asset paths | /_next/static/chunks/ | High |
| Middleware headers | x-middleware-next or x-middleware-rewrite | Medium |
| Redirect to protected route | HTTP 307 to /login | Medium |
Add the header "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" to bypass middleware check
Fingerprinting Django
Possible CVE: CVE-2021-35042
| Signal | Value | Confidence |
|---|---|---|
| Server header | WSGIServer/0.2 CPython/X.X.X | High |
| Cookie name | csrftoken | High |
| X-Frame-Options header | DENY | High |
| X-Content-Type-Options header | nosniff | High |
| Referrer-Policy header | same-origin | Medium |
| HTML source (any POST form) | csrfmiddlewaretoken hidden field | High |
The combination of X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and Referrer-Policy: same-origin appearing together signals Django's SecurityMiddleware.
Fingerprinting LAMP
| Signal | Value | Confidence |
|---|---|---|
| Server header | Apache/2.4.49 (Unix) | High - exact CVE match |
| 404 error page footer | Apache/2.4.49 version string | High |
| /cgi-bin/ response | 403 Forbidden (not 404) | High - mod_cgi enabled |