Author: Aditya Bhatt Category: Web App Hacking | Recon | Info Disclosure | CVE Enumeration
π Preface
Welcome to the first installment of Exposure Protocol β a technical bug bounty series that digs deep into the art of extracting sensitive intel through seemingly harmless leaks. From verbose errors to hidden secrets in source files, this series explores how whispers in web traffic can scream out loud to the trained eye.
In this opener, we'll start with a classic yet powerful case: Error-Based Info Disclosure. You'll see how a mistyped input unravelled the backend, helped us fingerprint vulnerable software, and laid the groundwork for CVE enumeration β all wrapped in a clean automation script.
This article is the beginning of a five-part saga, each focusing on a distinct form of information disclosure you might encounter in the wild β and how to weaponize it ethically.
So buckle up β recon just got real.
π Series Index: Information Disclosure β A Bug Hunter's Treasure Map

π Prelude to a Leak
Some bugs scream. Others whisper.
This one? It accidentally drops its whole backend rΓ©sumΓ© just because I threw a string into a parameter that expected a good ol' integer. π₯
Today, I'll walk you through how I turned a bad typecast into a full-on reconnaissance goldmine, discovered Apache Struts 2.3.31, and solved the PortSwigger lab with the swagger of a bounty hunter in a trench coat.
But waitβ¦ we're not stopping at the PoC. You'll also get a Python script to automate the whole shebang. Let's twist it up, automate the intel grab, and make devs cry (ethically, of course π«‘).
πΉοΈ TL;DR of the Attack
We take a productId endpoint, feed it malformed input (a string instead of an int), and the app coughs up a verbose error message containing its internal framework version.
We collect that info and submit it to solve the lab. Simple, elegant, and deliciously leaky.
βοΈ Step-by-Step PoC
- Go to Lab: Burp Lab β Info Leak via Error Messages. Open any product and capture the request.
2. Send GET /product?productId=5 to Repeater.
3. Observe the normal response. Yawn. π΄
4. Now swap 5 with "example" β productId="example" and boom β π₯ full Java stack trace drops in your lap.
In the stack trace, we spot the vulnerable tech: Apache Struts 2 2.3.31
5. Submit this version in the lab.
6. You just solved it. Now imagine doing this across 200 subdomains. That's bug bounty artillery right there. π
π€ Automation Script: Lab Destroyer 9000
Here's your script to automate the whole lab. Just plug in the lab URL, and it'll throw a string payload, catch the error, extract the version, and print it like a true recon master.
You can simply git clone and use the script from My GitHubπ.
β οΈ NOTE: Make sure you're logged into your PortSwigger Academy session in the same browser session (or use the session cookie in this script).
import requests
import re
# π§ CONFIG
LAB_URL = "https://YOUR-LAB-ID.web-security-academy.net/product?productId="
PAYLOAD = '"injection"'
# π§ HEADERS (Optionally add your session cookie if needed)
headers = {
"User-Agent": "Mozilla/5.0",
# "Cookie": "session=YOUR_SESSION_HERE"
}
# π MAKE THE REQUEST
def extract_version():
try:
print(f"[+] Sending request to: {LAB_URL}{PAYLOAD}")
response = requests.get(LAB_URL + PAYLOAD, headers=headers, timeout=10)
if response.status_code == 200:
# π§ Regex magic to find Apache Struts version
match = re.search(r'Apache Struts 2(?:\.| )([0-9]+\.[0-9]+\.[0-9]+)', response.text)
if match:
version = "2." + match.group(1)
print(f"[π―] Apache Struts version disclosed: {version}")
return version
else:
print("[-] No version info found. Maybe lab is patched or wrong URL.")
else:
print(f"[-] Unexpected response code: {response.status_code}")
except Exception as e:
print(f"[!] Exception occurred: {e}")
# π Run the extractor
if __name__ == "__main__":
extract_version()π Real World Implications
- That one version string? It's a fingerprint.
- Apache Struts is notorious for RCEs like CVE-2017β5638 β the Equifax breach? Yeah, it started with something like this.
- Once you know the version, you can map it against CVEs and craft custom exploits or pivot further.
π Defensive Measures
- Never expose internal stack traces to the user.
- Catch your exceptions, log them server-side, and serve generic 500 pages to users.
- Use a WAF or RASP to detect parameter fuzzing.
π§ Final Thoughts
Information disclosure is a gateway bug. It rarely gives you root access upfront, but it opens the door to version detection, CVE chaining, and attack surface expansion. Every recon artist's dream.
When in doubt, just toss in the wrong input and let the server do the talking.