Objective
Learn how to exploit Improper Error Handling to gain sensitive information about the underlying application or server, which can aid in launching further attacks. Understand how to mitigate these vulnerabilities by implementing proper error handling practices.
Scenario
You are assessing a web application that exposes detailed error messages, such as stack traces and database errors, to end users. An attacker can leverage these error messages to identify vulnerabilities like SQL injection points or server misconfigurations.
Lab Setup
Prerequisites:
- Basic knowledge of PHP and SQL.
- XAMPP/LAMP/WAMP stack installed (or any web server with PHP and MySQL support).
Step 1: Create the Vulnerable Web Application
- PHP Script with Improper Error Handling
- Create a file
login.php
:<?php $conn = mysqli_connect("localhost", "root", "", "test_db"); if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } if (isset($_POST['username']) && isset($_POST['password'])) { $username = $_POST['username']; $password = $_POST['password']; $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $result = mysqli_query($conn, $sql); if (mysqli_num_rows($result) > 0) { echo "<h2>Login Successful</h2>"; } else { echo "<h2>Invalid Credentials</h2>"; } } ?> <h2>Login</h2> <form method="POST" action=""> Username: <input type="text" name="username" required><br> Password: <input type="password" name="password" required><br> <button type="submit">Login</button> </form>
- Create a file
- Running the Application
- Start the Apache and MySQL servers.
- Place
login.php
in the web server’s root directory (htdocs
for XAMPP). - Open
http://localhost/login.php
in your browser.
- Database Setup
- Run the following SQL commands:
CREATE DATABASE test_db; USE test_db; CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50), password VARCHAR(50) ); INSERT INTO users (username, password) VALUES ('admin', 'password123');
- Run the following SQL commands:
Exploitation Steps
Step 1: Triggering SQL Errors
- Input the following into the Username field:
' OR '1'='1
- Expected Result:
- The application displays a SQL syntax error like:
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given...
- The application displays a SQL syntax error like:
Step 2: Information Disclosure
- Input the following:
admin'--
- Expected Result:
- The error message might reveal table or column names, aiding SQL injection.
Step 3: Revealing Server Configuration
- Modify the connection line to a wrong password to cause an error:
$conn = mysqli_connect("localhost", "root", "wrong_password", "test_db");
- Expected Result:
- Detailed connection error reveals database information:
Warning: mysqli_connect(): (HY000/1045): Access denied for user 'root'@'localhost'
- Detailed connection error reveals database information:
Solution and Prevention
Problem Analysis
- The application exposes internal error details directly to users, leaking sensitive information.
Fixing the Vulnerability
- Display Generic Error Messages
- Show users a generic message without revealing system details:
if (!$conn) { error_log("Database connection failed: " . mysqli_connect_error()); die("An error occurred. Please try again later."); }
- Show users a generic message without revealing system details:
- Disable Error Display in Production
- Configure PHP to hide errors in production (
php.ini
):display_errors = Off log_errors = On error_log = /var/log/php_errors.log
- Configure PHP to hide errors in production (
- Use Error Logging
- Log errors securely instead of displaying them:
error_log("Failed login attempt for username: $username");
- Log errors securely instead of displaying them:
- Implement Custom Error Pages
- Redirect users to custom error pages:
header("Location: /error.html"); exit;
- Redirect users to custom error pages:
- Validate and Sanitize Input
- Use prepared statements to prevent SQL errors:
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->bind_param("ss", $username, $password); $stmt->execute();
- Use prepared statements to prevent SQL errors:
Testing After Fix
- Input
' OR '1'='1
into the Username field. - Expected Result:
- The application displays a generic error message without leaking SQL details.
- Cause a database connection failure.
- Expected Result:
- Errors are logged securely, and users see a generic error page.
Conclusion
In this lab, you exploited Improper Error Handling to reveal sensitive application and database information. You also learned how to prevent this vulnerability by showing generic error messages, securely logging errors, and using input validation techniques.
0 Comments