I am trying to simulate an SQL injection attack on my own database by inserting SQL code into the input spaces.
My SQL code is:
SELECT * FROM Users
WHERE username = '...'
AND password = '...';
where ... is the input.
I am trying to use the following input to select every user and LIMIT that output to 1.
Here is the username input:
' OR ''='
This should get all the usernames.
And here is the password input:
' OR ''='' LIMIT 1; --
This should first get all the passwords, then limit the output to just 1 row, and then comment the final ';
So the code executed should look like:
SELECT * FROM Users
WHERE username = '' OR ''=''
AND password = '' OR ''='' LIMIT 1; -- ';
This does not work for some reason. I am using SequelPro and it tells me it's running 2 queries and not outputting anything. The second query being -- ';
However, if I remove that last part and just run up until the first semicolon, it works and retrieves a single user from the database.
What is going on?
Your query is all right, and the problem you have is from SequelPro which parser appears to be a blunt one, taking a comment for another query.
To avoid this confusion better take out the trailing semicolon from the forged input
Related
When I search for results from my table with the use of WHERE equals Clause I've got results that I would prefer to be different. For instance, when I look for result and my query is
SELECT * FROM users WHERE login="lapis" result is the same as it would be in
SELECT * FROM users WHERE login="lapis ". The whitespace at the end is ignored which is problem in my code as I use this query for my php login script and anyone can log into account with proper password but technically without proper login (it should be "lapis", not "lapis "). Is there anything I can do with it?
Your question isn't very detailed, but from what I can gather a simple preg_replace() will do what you want.
For example,
$login = preg_replace('/\s+/', '', 'lapis '); // This will output: lapis
$conn->query("SELECT * FROM users WHERE login='".$login."'")
preg_replace with the characters I included will remove ALL whitespace, including tabs and other forms.
You can do your query like the following.
SELECT * FROM users WHERE login LIKE "your_input_here"
Using LIKE solves the problem.
For example:
SELECT * FROM users WHERE login LIKE "lapis"
Only will get values that 'lapis' as login. And
SELECT * FROM users WHERE login LIKE "lapis "
Only will get values that 'lapis ' as login.
This removes whitespace from the end in your result.
SELECT RTRIM(username) FROM users WHERE login="lapis"
I've been working on a legacy website. Recently a user has informed us about a potential security breach.
Long story short, when trying to login and using '=' 'or' as password or a username the following query will get executed.
SELECT * FROM `table-goes-here` WHERE `username` = ''=' 'or'' AND `password` = 'some-hash-goes-here'
This query will select everything in that table and will allow login without any actual valid credentials.
I just maintain the site and I have talked to the owner before about such security leaks, he won't listen.
What I want to know is how exactly is this a valid query and what exactly does it do(preferably step by step, explain it to me like I'm 5 version). My MySQL knowledge isn't the best there could be.
I'm very aware that this is an SQL injection. I know how to prepare statements, but they're not in the budget apparently. I just want to know what it does exactly. Namely this part. I have never seen this syntax before and googling doesn't really help as I don't know what I'm looking for exactly.
`username` = ''=' 'or''
Thing is you are actually running
SELECT * FROM table WHERE (username= '' = '') or ('' AND password="");
and (user_username = '' = '') evaluates to true... try
SELECT (username= '' = '') FROM table;
and ('' AND password="") also evaluates to true... try
Select ('' AND password="") FROM table;
also evaluates to true so... everything is shown
I think it's working like this, first of all evals the
username = '' this returns false or 0 then the other parts come
0 = ' '
as you can see from mysql : https://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_equal
if you compare string with 0 (zero), it returns 1 (true)
AS a result:
SELECT 'blabla' = ''; // returns 0
SELECT 0 = ' '; // returns 1
The query would basically evaluate to true and would return all records.
So, the thing which would happen is that the hacker would be logged in as the user whose ID is stored first in your database.
Of course, it wouldn't show the database to the hacker, because you aren't echoing any of the database content anywhere, but with a little modification the hacker can manage to login as any user, not just the first one.
Read following to prevent such attacks How can I prevent SQL injection in PHP?
More info- http://www.w3schools.com/sql/sql_injection.asp
EDIT- The hacker would also have to use a similar trick in password field because else it would become false.
I am sending a Query string like:-
String query = "select * from table where id = 12345 or id like '___1435'";
in php code:-
$phone = $_REQUEST['data1'];
$result = mysql_query($phone);
return $result;
through android but it is not working.
But a query like:-
String query = "select * from table where id = 12345 or id = 21435";
is working.
I also tried:-
$phone = mysql_real_escape_string($_REQUEST['data1']);
$result = mysql_query($phone);
return $result;
What could be the problem.
Most probably it is related to the quotes I am using in String.
How can I overcome this ?
Thank You!
A LIKE query needs percentage signs to signify a wild card, which I assume you are trying:
id like '%___1435%'
If you don't want this wildcard behaviour then you could just remove the like
id = '___1435'
I think the problem is that you're attempting to perform a string comparison on an integer field. Try casting your ID field as a CHAR first, like this:
select * from table where id = 12345 or CAST(id as CHAR) like '___1435'
Edit: It's going to be a guessing game unless you can a) post some error logs or b) post your MySQL query log (to see the actual query executing), which you can enable by turning on the General Query Log for your installation. Since it looks like you're accepting your query string via POST, if the string has been encoded in any way (ie url encoding), it'll affect your query if not properly decoded first.
A better and more secure approach would be to create a specific web service that accepts the ID to query, which you can pass into a prepared statement server side. It's better practice anyway so your system isn't vulnerable to wide open queries from a client.
I can not get an SQL update statement to subtract a variable from a table value. Here is my code:
$_SESSION_Job101=mysql_fetch_array(mysql_query("SELECT * FROM job_101 WHERE job_101.username='$_SESSION_User'"));
mysql_query("UPDATE characters SET currenergy=currenergy-$_SESSION_Job101['ecost'] WHERE username='$_SESSION_User'");
$_SESSION_Job101 is a perfectly valid result, as I pull from it on another page; I even pull the 'ecost' on said page. I also update currenergy this way in another script, except I use the number 1 instead of the variable. So I've narrowed it down to that variable.
It wouldn't matter that $_SESSION_Job101 is the result from a second table (job_101), and that query is updating to the table characters, would it?
We don't have enough information, but since you don't perform ANY error handling or validation that SQL resultset is returned, it could be an error caused by issues such as:
no rows returned in first query
some other parsing issue not directly evident
I would propose that you use temporary strings and echo the actual SQL queries.
Continue by actually testing them with MYSQL (through workbench, queryviewer, or console) in order to see where and what the error is.
Also, it's not recommended to skip error checking and try to combine so many lines/steps into 2 lines.
Imagine the first query does not return any results for example...
Debugging:
$query1 = "SELECT * FROM job_101 WHERE job_101.username='$_SESSION_User'";
echo $query1."<br/>";
$_SESSION_Job101=mysql_fetch_array(mysql_query($query1 ));
$query2 = "UPDATE characters SET currenergy=currenergy-$_SESSION_Job101['ecost'] WHERE username='$_SESSION_User'";
echo $query2."<br/>";
mysql_query($query2);
Update
Based on your comment I suggest you try the following two options:
1) Add a space between the - and $_SESSION_Job101['ecost'].
2) If that doesn't work, change your string to:
mysql_query("UPDATE characters SET currenergy=currenergy-".$_SESSION_Job101['ecost']." WHERE username='".$_SESSION_User."'";`
I have a PHP script that is generating a MySQL select statement:
select * from words where word = 'Classic'
There is exactly one word in the words table with the variable word equal to Classic.
When my PHP page executes, I get no results from the query. If I echo the string that is being used to execute the query, cut and paste that into the SQL window in PHPMyAdmin in the database, I also get no results. However, if I re-type that EXACT string into the SQL window in PHPMyAdmin (with the same quote characters), I get the proper result of one row.
The word Classic from the select statement is gotten from a PHP GET (see code below). I can echo the $word variable, and get the correct result of 'Classic'. What am I doing wrong?
Here is my code:
<?php
require ('dbconnect.php');
$word = $_GET["word"];
$selectStr = "SELECT * FROM words WHERE word = '" . $word . "'";
if ($results = MySQL($dbName, $selectStr))
{
$rowCount = MySQL_NUMROWS($results);
}
$resultRow = MYSQL_FETCH_ROW($results);
$wordID = $resultRow[0];
?>
Please, please, please sanitize that word. mysql_real_escape_string() should do the trick.
$selectStr = "SELECT * FROM words WHERE word LIKE '" . $sanitized_word_i_promise . "'"; should work :)
Just to explain: "=" should work for exact matches. This includes uppercase / lowercase, spaces etc. You should probably trim that result first too, before using it in the query.
If you have foo stored in the database (note the space at the end) - it won't match foo, without a space. You'll want to use LIKE 'foo%' - probably.
Either way, Sourabh is right, although performance wise, this isn't a big hit when trying to match exact strings, you should look for the problem in other places first (such as, is the item in the database an exact match?).
First off you should not take any user input and directly input it into a query without sanitizing it, or using a prepared statement.
Now that we've gotten that out of the way: have you tried doing a strcmp() with the variable and your string written in? Such as
echo strcmp($_GET['word'], "Classic")
If you get a result other than 0 it means they are not the same, most likely there will be a whitespace of some sort in the $_GET variable. use trim() on it to take out whitespace. Also could be a case sensitivity issue as well.