So, I'm using Sqlmap for a while now to test the security for my company (we're too small to have IT guy and I'm the closest they got for now), I already managed to access the database remotely and dump the database using this

Parameter: id (GET) Type: boolean-based blind Title: OR boolean-based blind - WHERE or HAVING clause (Generic comment) Payload: id=-XXXX' OR YYYY=YYYY-- -&gid=XXXXX

Now I want to inject some information to the users table, I know table name, columns, etc. I also know which information I want to enter but I need to translate it to "geek" language which I don't really know yet. I also tried --os-shell on the server but it failed (we're not using any of the listed names it checks)

Of course, After I do that we're going to upgrade the software and I'll have to test it all again.

Thanks for anyone who can help me.

  • Why would you (still) need to inject code? You now your vulnerabilities and can fix them. Asking here for instructions on how to do SQL injection is not going to get many answers, I'm afraid.
    – user13695
    Mar 13 '16 at 19:52
  • well, injecting data can also be harmful for us, I want to know how harmful can it be, plus I really like reading new stuff.
    – Lumi Kor
    Mar 13 '16 at 20:13

First things first

Are you even allowed and authorized to test and mess around with this? You might need a written proof for your own sake in case it turns bad. Make sure you're not doing this live on some production server, use a test server instead.

Back to the basics

A classic way to demonstrate SQL injections:

$id = isset($_GET['id']) ? $id : -1; // Set default value if id isn't set
$stmt = $db->query('SELECT * FROM articles WHERE id=' . $id);
$results = $stmt->fetchAll();

To get all the rows, we might use 0 OR 1=1. The final query will look like this SELECT * FROM articles WHERE id=0 OR 1=1. Since 1=1 is always true it will return all rows from articles.

This is usually not what we want unless we want to stress the server in some way. So we tend to use UNION to reach other tables: 1 UNION SELECT ALL 1, 2, username, hash from users.

What about injecting an INSERT after SELECT?

SQL injection is really about modifying the original SQL query in unintended ways. The query needs to be valid to be successful. Following our previous example, you can't just mix an INSERT with a SELECT in one query:

SELECT * FROM articles WHERE id=1 ALSO INSERT INTO articles (title, content) VALUES ("foo", "bar")

Note that ALSO is just an imaginary keyword, well since it's not supported. Another attempt would be to use to separate queries by separating them with ;:

SELECT * FROM articles WHERE id=1; INSERT INTO articles (title, content) VALUES ("foo", "bar")

Most of the times this won't work. The second query gets ignored, because the underlying code needs to specify it's using "multiple queries" also known as "stacked queries". In PHP for example, one needs to use mysqli::multi_query instead of mysqli::query. Most applications use the later equivalant. You might want to read a previous answer of mine.

Injecting an INSERT statement

So the other legit way is to try and find a vulnerable code that uses INSERT:

// Registration page
// Got credentials via $_POST
$username = 'foo';
$password = 'bar'; // not hashed, so bad

$db->query('INSERT INTO users (username, password, admin) VALUES ("' . $username . '", "' . $password . '", 0)');

The final query will look like:

INSERT INTO users (username, password, admin) VALUES ("foo", "bar", 0)

We change the flow by using a different password: bar", 0), ("haxors_admin", "easy", 1)--. The final query will look like this:

INSERT INTO users (username, password, admin) VALUES ("foo", "bar", 0), ("haxors_admin", "easy", 1)--", 0)

Everything after -- gets commented and thus effectively ignored. We just added an admin user. Note that this scenario is very simple to demonstrate the attack.

sqlmap joins the fun

sqlmap is an automation tool to find SQL vulnerabilities and exploit them. Apart from data exfiltration, it also has options for OS takeover like --os-shell or --os-cmd.

Under the hood, it will check if stacked queries are supported. If it is, it will either use sys_exec or sys_eval to execute those commands. If it isn't, it will try to use a web backdoor (for example a php backdoor) to execute those commands. The backdoor is created by injecting INTO OUTFILE: trick the query to write to a writable folder. Now if MySQL doesn't have the rights to write to that folder, it won't be created. Thus the attack fails. This attack vector is better explained in the sqlmap usage wiki. More on this in Advanced SQL injection to operating system full control (whitepaper).


In your case, stacked queries aren't supported and MySQL doesn't have enough rights. Which explains why the attack failed. Aside from learning purposes, I would advise to not bother further and start fixing vulnerabilities.

  • 1
    that what I wanted to know (and now I can read more about it) as for the legal issues, I have the written consent, so I'm all covered. Already upgraded the system and that exploit is fixed.
    – Lumi Kor
    Mar 15 '16 at 17:51

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