Michelangelo Car Dealership – Web Application Penetration Test

This write-up documents the penetration testing engagement I performed against the Michelangelo Car Dealership web application as part of the B032431 β€” Penetration Testing 2025/2026 course at my university. The assessment was a black-box web application pentest carried out against an isolated Docker container (gabrielec/ptexam1), targeting 172.17.0.2. Three real vulnerabilities were identified, ranging from Critical SQL Injection allowing full database exfiltration, to a Reflected XSS enabling phishing, and a Low-severity Information Disclosure through a forgotten debug endpoint and unscrubbed image metadata.

⚠️ Disclaimer: This engagement was performed in a controlled academic lab environment. All techniques shown here are for educational purposes only.

🎯 Scope & Engagement Overview

FieldValue
TargetMichelangelo Car Dealership Web App (gabrielec/ptexam1)
Target IP172.17.0.2 / 172.17.0.3
Assessment TypeBlack-box Web Application Penetration Testing
Rules of EngagementTesting limited to the designated local container

🧭 Methodology

The engagement followed a structured methodology aligned with industry standards:

  1. Information Gathering β€” Passive and active reconnaissance
  2. Network Scanning β€” Port scanning and service enumeration
  3. Banner Grabbing & Enumeration β€” Service versioning and resource discovery
  4. Vulnerability Assessment β€” Manual and automated identification
  5. Exploitation β€” Controlled exploitation to confirm impact
  6. Reporting β€” Documentation of findings and remediation

The OWASP Web Application Testing Guide was used as a reference framework throughout.

πŸ“Š Key Findings Summary

#VulnerabilityRiskCVSSAffected
1SQL Injection β€” Auth Bypass & Data ExfiltrationπŸ”΄ Critical9.1/login.php
2Reflected Cross-Site Scripting (XSS)🟑 Medium6.1/recovery.php
3Information Disclosure🟒 Low5.3/debug.php

πŸ”΄ Finding 1 β€” SQL Injection (Critical, CVSS 9.1)

Affected endpoint: http://172.17.0.2/login.php Impact: Full database exfiltration, administrative credentials retrieved, authentication bypass achieved.

Description

A critical SQL Injection vulnerability exists in the username parameter of the login.php authentication form. The application uses a weak blacklist filter instead of parameterized queries. As a result, an unauthenticated attacker can inject SQL commands to bypass authentication and exfiltrate the entire backend database β€” including administrator credentials.

1️⃣ Initial Detection β€” The Telltale Quote

The login form at /login.php was tested by submitting a single quote ' in the username field. The application returned a verbose SQL error, confirming that user input was being passed directly into the SQL query without sanitization. The error also leaked the backend DBMS: MariaDB.

SQL error message leaking MariaDB backend

2️⃣ Bypassing the Blacklist Filter

Standard payloads like ' OR 1=1# failed immediately. A behavioral difference quickly became apparent:

  • Submitting invalid-but-normal credentials (admin:admin) returned "Wrong"
  • Submitting SQL payloads triggered "Illegal format" β€” meaning a blacklist filter was rejecting the request before the DB even saw it

To map the filter, each suspicious character was tested individually:

Injected CharacterResponseStatus
(blank space)Illegal format🚫 Blocked
= (equals)Illegal format🚫 Blocked
/**/ (multi-line comment)Illegal format🚫 Blocked
%27 (URL-encoded quote)Wrongβœ… Passed
# (hash comment)Wrongβœ… Passed
() (parentheses)Wrongβœ… Passed

This map made it clear the filter blocked spaces, equals signs, and inline comments β€” exactly the characters classic payloads depend on.

Manual filter mapping in the browser

3️⃣ Weaponizing SQLMap with Tamper Scripts

A vanilla SQLMap run would have crashed against the input filter. Instead, the manual findings were turned into a precision-tuned command using tamper scripts:

sqlmap -u "http://172.17.0.2/login.php" \
  --data="username=test&password=test" \
  --dbms=mysql \
  --tamper=space2comment,equaltolike \
  --dbs \
  --batch
  • space2comment β†’ replaces spaces with /**/ … but since /**/ is also filtered, this is paired with equaltolike (replaces = with LIKE) to bypass the equals-sign block. The combination produces payloads that look nothing like the blacklist expects.
  • --dbms=mysql β†’ skips fingerprinting, saves time
  • --batch β†’ auto-accepts SQLMap prompts

SQLMap successfully enumerating databases

4️⃣ Pwned! πŸ’₯ β€” Dumping the Database

SQLMap broke through. The micdb database was enumerated, and dumping the customers table returned the administrator credentials in cleartext:

admin:adminpwd

Administrator credentials extracted from the customers table

Full authentication bypass and complete database compromise β€” achieved by understanding the filter rather than fighting it.

Remediation

  • Implement parameterized queries. This is the only robust defense β€” fully separate SQL logic from user data. Blacklists will always lose this game.
  • Strict whitelisting. Validate the username parameter against an allowlist of expected characters (e.g. [a-zA-Z0-9_]).

🟑 Finding 2 β€” Reflected XSS / HTML Injection (Medium, CVSS 6.1)

Affected endpoint: http://172.17.0.2/recovery.php Impact: Highly convincing phishing attacks against authenticated users.

Description

The email parameter of recovery.php reflects user input directly into the DOM with no sanitization or encoding. This allows an attacker to inject arbitrary HTML β€” including full fake login forms β€” that render as part of the trusted page.

Proof of Concept

To demonstrate the real-world impact, a credential-harvesting form was injected into the vulnerable email field:

<h1>Sistem BakΔ±mda</h1>
<p>Lütfen tekrar giriş yapın:</p>
<form action="http://172.17.0.2/login.php" method="POST">
  KullanΔ±cΔ±:<input type="text" name="username">
  Şifre:<input type="password" name="password">
  <input type="submit" value="Giriş">
</form>

The browser rendered this as a fully functional fake login form, indistinguishable from a legitimate maintenance page β€” only this one ships credentials wherever the attacker wants.

Injected phishing form rendered on recovery.php

Remediation

  • Output encoding. Always HTML-encode user input before reflecting it in the browser (e.g. htmlspecialchars() in PHP).
  • Input validation. Validate email format server-side before processing.

🟒 Finding 3 β€” Information Disclosure (Low, CVSS 5.3)

Affected endpoints: http://172.17.0.2/debug.php and image files under /pic/ Impact: Valuable reconnaissance data exposed to anonymous attackers.

Description

The application leaks sensitive internal data through two distinct channels:

  1. A leftover debug.php file directly invokes phpinfo(), leaking the full server configuration.
  2. Image files served from /pic/ retain their original Exif metadata, including internal author names.

Proof of Concept

Vector 1 β€” debug.php: Accessing http://172.17.0.3/debug.php returns a full phpinfo() dump, leaking PHP 7.2.34, document root, database status, environment variables, and loaded modules.

phpinfo() output exposed via debug.php

Vector 2 β€” Exif metadata: Running ExifTool against the served images reveals internal authorship data:

exiftool 2.jpg
Author : Jim Geuther

A name leak like this is gold for a social-engineering follow-up: target identified, no authentication required.

ExifTool output revealing internal author name

Remediation

  • Server cleanup. Permanently remove debug.php from production. Debug endpoints should never ship.
  • Metadata sanitization. Strip Exif data from all uploaded/served images (e.g. via an automated pipeline at upload time).

🧰 Tools Used

  • Nmap 7.94 β€” Network scanning & service detection
  • Gobuster 3.6 β€” Directory and file enumeration
  • Nikto 2.5 β€” Web server vulnerability scanning
  • SQLMap 1.8 β€” Automated SQL injection (with tamper scripts)
  • ExifTool 12.57 β€” Metadata extraction
  • OWASP ZAP 2.15 β€” Web application proxy & scanner
  • Hydra 9.5 β€” Credential brute forcing

πŸ“š References


πŸŽ“ Reflections

This engagement was a great reminder that blacklists are not security β€” every blacklist is a puzzle waiting to be solved, and tamper scripts are how you solve them. The most rewarding moment wasn't the SQLMap dump, it was the manual character-by-character filter mapping that made the SQLMap dump possible. Recon and observation always win.