Reputation: 81
Good morning,
I had some problems yesterday and got help, unfortunately, my app still not does 100% does what I want it to do, although only a small detail is missing.
Given a scenario where I want to do an SQL injection to drop a database, and when it happens, render a PHP page. Everything works fine until I want the render to happen - even though the injection executes and the DB is dropped when I check it MySQL, still no rendering. The problem is probably due to the incorrect usage of multi_query. More details in comments in the code.
<?php
include("/../../connection.php");
if(isset($_POST["button_one"])){
$username = $_POST['username'];
$password = $_POST['password'];
if($conn->multi_query("SELECT id FROM users WHERE username = '$username' OR password = '$password'")) // IF THE USER HAS A VALID USERNAME OR PASSWORD,
{
do {
if ($result = $conn->store_result()) {
while ($row = $result->fetch_row()) { // THEN ENABLE BUTTON TWO, WHICH HAS TO BE CLICKED TO DROP THE DATABASE
echo "
<script type=\"text/javascript\">
document.getElementById('button_two').disabled=false;
</script>
";
}
$result->free();
}
} while ($conn->next_result());
}
}
if(isset($_POST["button_two"])){
$username = $_POST['username']; // SQL INJECTION TO DROP THE DB HAPPENS HERE
$password = $_POST['password'];
if($conn->multi_query("SELECT id FROM users WHERE username = '$username' OR password = '$password'")) // SQL INJECTION SUCCEEDED
{
do {
if ($result = $conn->store_result()) {
while ($row = $result->fetch_row()) {
if ($result = $conn->query("SHOW DATABASES LIKE 'mydatabase'")) { // NO MORE DATABASE LIKE THAT, IT HAS BEEN DROPPED DUE TO THE INJECTION
if($result->num_rows == 0) {
include("another.php"); // THE PROBLEM IS HERE. EVEN THOUGH THE DB IS DROPPED, THIS PAGE IS NOT RENDERING
}
}
}
$result->free();
}
} while ($conn->next_result());
}
}
?>
Any helpful idea would be appreciated!
Upvotes: 2
Views: 103
Reputation: 562250
another.php
never runs, because the SHOW DATABASES query fails.I tested your code and added some error reporting:
if ($result = $conn->query("SHOW DATABASES LIKE 'mydatabase'")) {
if($result->num_rows == 0) {
include("another.php");
}
} else {
echo "Error: {$conn->error}\n";
}
I got this:
Error: Commands out of sync; you can't run this command now
You can't run another SQL query while the one you already have executed still has results to fetch. Even though you have used store_result()
to fetch the result set, that only fetches the current result set. You used mulit_query()
which produces multiple result sets. You have to process all result sets until the end of the next_result()
loop before you can start a new query.
Another lesson here is that you should always check for and report errors after you try to query()
or multi_query()
or prepare()
or execute()
.
Here's an example: You have to wait until after the last result has been processed before you can run another query. This means after the loop on $conn->next_result()
is done.
if(isset($_POST["button_two"])){
$username = $_POST['username'];
$password = $_POST['password'];
if($conn->multi_query("SELECT id FROM users WHERE username = '$username' OR password = '$password'"))
{
do {
if ($result = $conn->store_result()) {
while ($row = $result->fetch_row()) {
// DISPLAY RESULTS FROM QUERY
}
}
$result->free();
} while ($conn->next_result());
// CAN'T START ANOTHER QUERY UNTIL AFTER THE NEXT_RESULT LOOP IS DONE
if ($result = $conn->query("SHOW DATABASES LIKE 'mydatabase'")) {
if($result->num_rows == 0) {
include("another.php");
}
}
}
Upvotes: 1