Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I am exploring a vulnerability in one PHP website that is basically riddled with SQL injections. With SQLMap, I managed to dump all the tables and get some basic information (username, DB name, hostname, though the it seems pretty useless because the DB server is not externally available). My goal is to modify data in a specific table, not mentioned in any injectable SQL queries. I tried SQLmap's --db-shell switch, but I found out I cannot do anything beyond SELECT because PHP+MySQL combination disallows stacked queries.

Thus my question. Given one of the following snippets:

mysql_query("SELECT * FROM sometable WHERE id=".$_GET['id']);
mysql_query("INSERT INTO sometable (id) VALUES (".$_GET['id'].")");
mysql_query("UPDATE sometable SET id= ".$_GET['id']);
mysql_query("DELETE FROM sometable WHERE id=".$_GET['id']);

Can I modify (delete, insert, update) data from outside of sometable, without LOADFILE/INTO OUTFILE (and similar) tricks? Would MySQL syntax let me do it in this case? If the answer is "depends", how would the query syntax look like to let me through? I am not a DBA on this host. There are also no stored procedures on the website, just some very basic, amateur stuff that you could learn from a single book that doesn't even mention security.

share|improve this question
add comment

3 Answers

First off: I'm not sure i understood your query, but I'm assuming you meant: How can I affect data outside (the table these queries are about) ?

The most obvious attack would've been inserting multiple queries i.e. ";delete from other_table" but in this case it looks like you can't do that. mysql_query() sends a unique query (multiple queries are not supported)

Which means you're stuck with side-effects - doing things within the original query. It looks like at the very least you can be disruptive with locks: http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html in particular, you should be able to make the select's a 'select ... for update';

I can't yet see another way to affect the specific queries you've got.

share|improve this answer
    
Thanks for the locking trick, that's interesting! Also, can I modify the queried table from withing a SELECT statement? –  d33tah Dec 13 '13 at 21:02
    
I can't see a way - doesn't mean it's impossible. (Although I do get the impression they've tried hard to design it that way). –  pacifist Dec 19 '13 at 1:23
add comment

I've been playing around with this for a bit and I haven't found any way to do what you are talking about. It's possible that someone who is smarter than me could figure out a way to do it, but as far as I can tell it cannot be done.

share|improve this answer
add comment

You are far better off using PHP Data Objects for your data access layer queries. This will eliminate SQL injection altogether; not to mention you may also want to get friendly with the website group known as OWASP.

Example:

// Declare & set variable

list ($db_dbdriver, $db_hostname, $db_database, $db_username, $db_password) = Connection::dbConnect();
// Set default timezone

date_default_timezone_set('America/Los_Angeles'); $my_success = false; $my_message = "";

try {

// Create & set connection

$db_options = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'");

$conn = new PDO($db_dbdriver . ":host=" . $db_hostname . ";dbname=" . $db_database, $db_username, $db_password, $db_options);

$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Prepare an SQL statement

$my_sql = 'INSERT INTO Message (Message_State, Message_Body, Message_CBy, Message_EBy) VALUES (:Message_State, :Message_Body, :Message_CBy, :Message_EBy)';

$stmt = $conn->prepare($my_sql); // Bind parameters to prevent SQL Injection.

$stmt->bindValue(':Message_State', $message_state);

$stmt->bindValue(':Message_Body', $message_body);

$stmt->bindValue(':Message_CBy', $message_cby);

$stmt->bindValue(':Message_EBy', $message_eby);

// Execute the SQL statement

$stmt->execute();

// Closes the cursor, enabling the statement to be executed again

$stmt->closeCursor();

// Close & unset the connection

$conn = null; unset($conn);

// Set success value to TRUE

$my_success = true; $my_message = "success";

} catch(PDOException $e) {

// Catch error message

$error_message = $e->getMessage();

// Append error message to error log

file_put_contents('../../log/error/php_errors.log', "\r\n" . date("Y-m-d h:i:s A") . ": data_access_layer -> my_class.php (class_name) -> Function_Name : " . $e->getMessage(), FILE_APPEND);

// Set success value to FALSE & return an error message

$my_success = false; $my_message = $error_message;

}

return array($my_success, $my_message);

share|improve this answer
    
Does he even have access to modify the source code? –  Abe Miessler Sep 17 '13 at 19:17
    
Nope, I don't. :/ –  d33tah Sep 17 '13 at 20:52
    
Sorry about that; I should have asked that first. –  Sean Dorman Sep 18 '13 at 0:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.