antoninolorenzo/ai-ops/web-reconnaissance

Claude Code and agent skill by antoninolorenzo/ai-ops

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Perform initial HTTP/HTTPS reconnaissance on a target to identify the web stack, exposed endpoints, security headers, and surface-level misconfigurations. Load at the start of any web-facing task before running exploitation tools.

Install

npx vskill@latest install antoninolorenzo/ai-ops/web-reconnaissance

SKILL.md

Start with a baseline request against the root path. This confirms the host is responding and gives you the raw material for fingerprinting.

bash
curl -sk -D /tmp/headers.txt -o /tmp/body.html --max-time 10 "$TARGET_URL/"

If headers.txt is empty, the host is not responding. Verify with nmap -sV -p <port> <host> before continuing.

Fingerprinting

Read headers.txt for technology signals: Server and X-Powered-By give the web server and language directly. Cookie names are reliable framework indicators — PHPSESSID = PHP, JSESSIONID = Java, csrftoken/sessionid = Django, laravel_session = Laravel, rack.session = Ruby. Note any missing security headers (Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, X-Content-Type-Options) and any Location redirect that leaks internal path structure.

Then read the body:

bash
# CMS, generator tags, framework comments
grep -iE '(generator|wp-content|drupal|joomla|powered by|framework)' /tmp/body.html | head -20
# JS/CSS asset paths — version strings often appear in filenames
grep -oE 'src="[^"]*\.js[^"]*"' /tmp/body.html | head -20
# Request a non-existent path and read the error page — server and framework often self-identify
curl -sk -o /tmp/error.html "$TARGET_URL/doesnotexist_$(date +%s)" && grep -iE '(apache|nginx|iis|php|python|java|ruby|exception|stack trace)' /tmp/error.html | head -10

The identified technology determines which file extensions are worth fuzzing later:

StackExtensions to target
PHP.php, .php5, .phtml, .bak, .php.bak
Java / JSP.jsp, .jspx, .do, .action
ASP.NET.asp, .aspx, .ashx, .asmx, .config
Python.py, .cfg, .env
Any.bak, .old, .orig, .txt, .zip, ~, .swp

Known Paths

Fetch paths the application may expose intentionally or accidentally. These often reveal structure before any fuzzing is needed.

bash
for path in robots.txt sitemap.xml sitemap_index.xml .well-known/security.txt crossdomain.xml; do
status=$(curl -sk -o /tmp/$(basename $path) -w "%{http_code}" "$TARGET_URL/$path")
[ "$status" = "200" ] && echo "[+] $path" && cat /tmp/$(basename $path)
done

Extract any paths from robots.txt and sitemap — use them as a supplementary wordlist:

bash
grep -oE '(/[^ \n]*)' /tmp/robots.txt /tmp/sitemap.xml 2>/dev/null | sort -u > /tmp/known_paths.txt

Wildcard Calibration

This step is mandatory before running ffuf. Many servers return a 200 or redirect for every path — running ffuf without calibration produces hundreds of false positives.

Request two random paths and compare the responses:

bash
R1=$(curl -sk -o /tmp/wc1.html -w "%{http_code} %{size_download}" "$TARGET_URL/$(head -c8 /dev/urandom | md5sum | head -c8)"); R2=$(curl -sk -o /tmp/wc2.html -w "%{http_code} %{size_download}" "$TARGET_URL/$(head -c8 /dev/urandom | md5sum | head -c8)"); echo "Sample 1: $R1"; echo "Sample 2: $R2"

Choose the ffuf filter based on what you see:

Both responsesFilter to use
404, any sizeNo filter needed — use -mc 200,201,301,302,307,401,403
200, same size-fs <that_size>
200, similar but not identical size-fw $(wc -w < /tmp/wc1.html)
302 to the same destination-fc 302 and inspect the redirect target separately

Directory Fuzzing

Run a fast first pass with common.txt. This calibrates signal density before committing to a larger list.

bash
ffuf -u "$TARGET_URL/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/common.txt \
-mc 200,201,204,301,302,307,401,403 \
-t 40 -o /tmp/ffuf_pass1.json -of json -s

Parse the results:

bash
python3 -c "import json; [print(f\"{r['status']} {r['length']:>8} {r['url']}\") for r in json.load(open('/tmp/ffuf_pass1.json')).get('results',[])]" | sort

If the app shows signs of depth (login panels, API routes, admin paths in Pass 1), follow up with a broader list. Add the calibrated filter from above.

bash
ffuf -u "$TARGET_URL/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
-mc 200,201,204,301,302,307,401,403 \
-t 40 -o /tmp/ffuf_pass2.json -of json -s

For recursion into discovered directories (doubles request count — use with intent):

bash
ffuf -u "$TARGET_URL/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/common.txt \
-mc 200,301,302,401,403 \
-recursion -recursion-depth 2 -t 20 -o /tmp/ffuf_recursive.json -of json -s

Extension Fuzzing

Run this only after fingerprinting identifies the stack. Backup and swap files are consistently high-value — they can expose source code of files that are otherwise served compiled or behind access controls.

bash
ffuf -u "$TARGET_URL/FUZZ" \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt \
-e .php,.bak,.old,.txt,.zip,.config,.env,.swp \
-mc 200,201,301,302,401,403 \
-t 40 -o /tmp/ffuf_ext.json -of json -s

Virtual Host Enumeration

Only relevant when the target has a known hostname rather than a bare IP. First measure the baseline response size for an unknown Host header, then fuzz:

bash
baseline=$(curl -sk -o /dev/null -w "%{size_download}" -H "Host: nonexistent-$(date +%s).<DOMAIN>" "$TARGET_URL/")
ffuf -u "$TARGET_URL/" \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-H "Host: FUZZ.<DOMAIN>" \
-mc 200,201,301,302,401,403 -fs $baseline \
-t 40 -o /tmp/ffuf_vhost.json -of json -s

TLS Certificate Check

HTTPS targets only. SAN entries frequently reveal internal hostnames and additional vhosts not visible from the main application.

bash
_h=$(echo $TARGET_URL | sed 's|https\?://||' | cut -d: -f1 | cut -d/ -f1); _p=$(echo $TARGET_URL | grep -oP ':\K[0-9]+' || echo 443); echo | openssl s_client -connect $_h:$_p -servername $_h 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

A subject matching the issuer means self-signed. SAN DNS entries are candidate vhosts — add them to Virtual Host Enumeration. An expired notAfter signals a neglected or abandoned service.

What to Carry Forward

At this point you should know the technology stack, which paths exist and their status codes, whether backup or config files are exposed, and any additional hostnames from TLS SANs. Record all of this — the stack determines which exploitation techniques apply, the path list feeds directly into parameter and vulnerability probing, and any 401/403 paths are candidates for authentication bypass.

Common Failure Modes

SymptomLikely causeAction
headers.txt emptyHost down or port filterednmap -sV -p <port> <host>
ffuf wordlist not foundWrong pathls /usr/share/seclists/Discovery/Web-Content/; fallback: /usr/share/wordlists/dirb/common.txt
ffuf returns hundreds of same-size hitsWildcard catch-allRe-run calibration; add -fs <size>
Hits vary by a few bytesDynamic wildcardSwitch to -fw or -fr "<stable_phrase_from_error_page>"
openssl s_client hangsPort is plain HTTPSkip TLS step entirely
SAN entries show unknown hostnamesAdditional vhostsFeed into Virtual Host Enumeration

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
168
Repository forks
26
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/antoninolorenzo/ai-ops/web-reconnaissance/badge)](https://verified-skill.com/skills/antoninolorenzo/ai-ops/web-reconnaissance)

Something wrong with this skill or its page? Tell us.