skip to Main Content

I am attempting to make a web application (LAMP stack – MySQL version: 8.0.36-0ubuntu0.22.04.1) that is vulnerable to a SQL UNION Injection attack (or some type of SQL injection attack). The code takes the user’s input via POST parameters to get the VIN & mileage.

The following PHP Code handles the backend to adding the parameters to the database:

// If SESSION variables are set then proceed to Mileage.php
    if (isset($_SESSION['username'])) {
        // PHP Code for Handling ADDING CAR
        // Declare Variables
        $username = $_SESSION['username'];
        $vin = $_POST['vehicle'];
        $mileage = $_POST['mileage'];

        // Implement Try-catch for Error Hanlding
        try {
            // Add Mileage
            if(isset($_POST['add_data'])) {
                $query = "INSERT INTO mileage_master.mileages (`username`, `VIN`, `mileage`) VALUES ('$username', '$vin', '$mileage')";
                $query_result = mysqli_query($db,$query);
    
            // Update Mileage
            } elseif(isset($_POST['update_data'])) {
                // Query to update associated VIN's Mileage
                $update = "UPDATE mileage_master.mileages SET mileage='$mileage' WHERE username='$username' AND VIN='$vin'";
                $update_result = mysqli_query($db,$update);
            // Remove Mileage
            } elseif(isset($_POST['remove_data'])) {
                // Query to Remove VIN & Mileage
                $remove = "DELETE FROM mileage_master.mileages WHERE username='$username' AND VIN='$vin'";
                $remove_result = mysqli_query($db,$remove);
            }
        }
        catch (mysqli_sql_exception $e) {
            $showAlert = true;
            // Display Syntax Error
            $errorMessage = "My SQL Error: " . $e->getMessage();
            // Display Query (Intentional Unsafe Coding Practices)
            $errorMessage .= "t||tQuery: " . $sql;
        }

        
    }    
    else {
        header("Location: /");
    }
?>

The following PHP code prints the VIN & mileage to user’s page:

<?php
    // Query to get all VINs associated with username
    $result = mysqli_query($db,"SELECT * FROM mileages WHERE username='$username'");

    echo "<table style='margin-top: 35px;'>";
    echo "<tr><th>VIN</th>";
    echo "<th>Mileage</th></tr>";

    // While Loop to iterate through all returned rows
    while($row = mysqli_fetch_assoc($result)) {
        echo "<tr style='text-align: center;'>";
        // VIN
        echo "<td>" . $row['VIN'] . "</td>";
        // Mileage
        echo "<td>" . $row['mileage'] . "</td>";
        echo "</tr>";
    }

    echo "</table>";
?>

My thought process was that because the application uses dynamic queries an attacker could include some type of UNION SELECT statement. The UNION select statement’s output would be stored within the VIN column for that query.

However, I am unable to create a successful SQL Injection payload that would accomplish this.

Question

Do I need to change the logic of my application to make the exploit possible or is my idea not exploitable in the first place?

2

Answers


  1. To simulate a UNION SQL injection vulnerability for educational purposes, you could modify the application to include a feature where a user can search for their vehicles by VIN or mileage, directly inserting user input into a SELECT query.

    // Example of a vulnerable SELECT query
    if(isset($_POST['search_vin'])) {
        $search_vin = $_POST['search_vin'];
        $query = "SELECT * FROM mileage_master.mileages WHERE VIN='$search_vin'";
        $result = mysqli_query($db, $query);
        // Code to display results
    }
    

    This example would be vulnerable to UNION SQL injection because an attacker could input a value like 0′ UNION SELECT username, password FROM users — as the search_vin, potentially allowing them to extract sensitive information from the database.

    Login or Signup to reply.
  2. You can’t get SQL injection in the SELECT query, since the user doesn’t have control over the $username variable, and that’s the only thing you substitute. But you can do it in the INSERT query, to insert extra rows in the table with arbitrary values.

    It needs to terminate the current value list, then it can use a subquery in another value list, and finally it has to provide the beginning to match the end of the original value list.

    $vin = "12345', '20'), ('baduser', (SELECT '67890'), (SELECT '30')), ('baduser2', '1111";
    

    This will put a bogus VIN and mileage into the row for $username, then insert additional rows for baduser and baduser2. baduser2 will get another bogus VIN and the mileage from the parameter.

    baduser can use subqueries to get its VIN and mileage values, as long as the subqueries each only return one row and column. I used literals in the above example, but you can make them arbitrarily complex.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search