2

I'm trying to learn SQL injections so I can protect myself in the future.

Here is the PHP code:

  $req = mysql_query("INSERT INTO ip_change VALUES('', '".$_SESSION['id']."', '".$_POST['raison']."')") or die(mysql_error());

And the user has full control over $_POST['raison'] content.

When i use 'hello as $_POST['raison'] value I get

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'hello')' at line 1

When i use '); DELETE * FROM tabledetest;") or die(mysql_error());-- as $_POST['raison'] value I get

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELETE * FROM tabledetest;") or die(mysql_error());--')' at line 1

So I don't understand why my request isn't injected and I can't delete my tabledetest table.

Any help would be appreciated.

shrimpdrake
  • 1,476
  • 2
  • 14
  • 25
  • You may want to look at what a [testing tool](http://sqlmap.org) does to verify your escaping. It's not always as simple as adding a quote. – tadman May 01 '16 at 16:53
  • 5
    You should probably stop using `mysql` and start using `mysqli` or PDO. – Amous May 01 '16 at 16:54
  • 2
    @Amous Ironically for the purposes of this exercise it's actually the best tool. It's notoriously flawed. – tadman May 01 '16 at 16:55
  • @tadman What's notoriously flawed? – Strawberry May 01 '16 at 16:56
  • 1
    The `mysql_query` interface is so bad that it was removed in PHP 7. If you're trying to write secure code you **must** use something like `mysqli` or PDO with prepared statements as an absolute minimum. It's generally better to use an ORM like [Doctrine](http://www.doctrine-project.org/) or [Propel](http://propelorm.org/) to wrap around your database, it makes developing a lot more pleasant, or better still, use a [development framework](http://codegeekz.com/best-php-frameworks-for-developers/) like [Laravel](http://laravel.com/) that gives you even more support. – tadman May 01 '16 at 16:58
  • 1
    From the doc for [`mysql_query()`](http://php.net/manual/en/function.mysql-query.php) - *mysql_query() sends a unique query (multiple queries are not supported)*. That is why the 2nd code failed, as `mysql_query()` only allows 1 query, so anything after a `;` will throw an error – Sean May 01 '16 at 17:01
  • Either you are really a newbie on this field or this is some subtile attempt to get instructed on how to attack other sites. :-) As I'm generally thinking positive about other people (at least at first), I assume the first. You are trying what is known as [bobby tables](https://xkcd.com/327/). Perhaps the syntax of your `delete` is wrong? Drop the star, i.e. `delete from tabledetest` (instead of `delete * …`). – PerlDuck May 01 '16 at 17:04
  • @PerlDog how would fixing the `DELETE` syntax fix the main issue of *mysql_query() sends a unique query (multiple queries are not supported)*? – Sean May 01 '16 at 17:07
  • Well, @Sean, it would not :-( I'm not familiar with the diff's between mysql, mysqli, and PDO as I'm more perlish and always use prepared statements there (with ?). Albeit it was a nice riddle :-) Sorry for the noise. – PerlDuck May 01 '16 at 17:08
  • 1
    While you can't run multiple commands by default, imagine this: `SELECT * FROM user WHERE username = '{$_POST['username']}' AND email = '{$_POST['email']}'`. Now, this should be safe in that the user needs to know the username AND the email, but a username of `admin' --` means we wouldn't have to know the admin email as `--` would make the rest of the query a comment. You could also start joining with other tables and fetch info that you're not allowed to see. – h2ooooooo May 01 '16 at 17:17
  • The question is why are you trying to learn how to create SQL injection, instead of learning how to prevent it, i.e. [`How can I prevent SQL-injection in PHP?`](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php). You don't need to try drugs to know they can be bad and cause harm. Sometimes it is easier to just trust those who have been through it, and share the knowledge of how to prevent it. – Sean May 01 '16 at 17:21
  • Just take a look at this: http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?lq=1 – Edward May 01 '16 at 17:47
  • 1
    @Sean: I agree partially: It's absolutely unnecessary to (re-)invent the wheel for the purpose of having a wheel. But it's an outstanding approach to _learn how wheels work_. – PerlDuck May 01 '16 at 18:12

2 Answers2

3

It is because you didn't do proper injection!

Here is the one you have done. The auto-format will hint you:

<?php
$_SESSION['id'] = "123"; //Just assume

$req = mysql_query("INSERT INTO ip_change VALUES('', '123', ''hello')") or die(mysql_error());

It didn't properly end the statement.

For the next one:

$req = mysql_query("INSERT INTO ip_change VALUES('', '123', ''); DELETE * FROM tabledetest;") or die(mysql_error());--')") or die(mysql_error());
  1. From the manual:

mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.

mysqli has support for multiple statements.

  1. -- can't comment PHP code! PHP comment is // or #

Some of the links that might help you: [Similar to your question]

  1. https://en.wikibooks.org/wiki/PHP_Programming/SQL_Injection_Attacks
  2. http://roshanbh.com.np/2007/12/sql-injection-attack-examples-and-preventions-in-php.html
  3. SQL injection test - mysql_query
Community
  • 1
  • 1
Thamilhan
  • 13,040
  • 5
  • 37
  • 59
  • The question is now to make that non-working injection do something bad. – tadman May 01 '16 at 17:13
  • I have explained for the OP's question: _I don't understand why my request isn't injected_ – Thamilhan May 01 '16 at 17:15
  • 2
    I get that much, but can you make it properly inject? – tadman May 01 '16 at 17:17
  • Thanks Thamizhan does that mean since multiple queries are not supported by mysql_query() that I'm safe from such attacks on this unsafe query ? Does it mean I can't delete my tabledetest with this flaw ? If so how would you advise me to change that php code to make it injectable ? – shrimpdrake May 01 '16 at 18:04
  • @shrimpdrake Absolutely, `mysql_*` eliminates one of the SQL injection. If you want to use multiple statements, you should opt for `mysqli_*`. I have already mentioned in the answer, towards the end – Thamilhan May 02 '16 at 00:49
  • @thamizhan so my request is secure against injections ? An attacker can't do something like : ending the MySQL_query();do smth bad ; ? – shrimpdrake May 02 '16 at 06:35
  • @shrimpdrake I have added few links to the question that might help you to know further on – Thamilhan May 02 '16 at 06:41
1

To protect from SQL injection you should not inject the variables directly to query use Prepared Statements instead.

Rohit
  • 1,794
  • 1
  • 8
  • 16
  • 5
    In this situation the OP is wanting to directly inject the variables, as the opening line said *I'm trying to learn SQL injections so I can protect myself in the future.* – Sean May 01 '16 at 17:05