Ok, starting fresh >
For our first assignment in a System Security class, we have to hack into the professors "cheaply organized" sql database. I know the only user is "admin" and picking a random password, the select statement generated in the php is:
select user_id from user where user_username = 'admin' AND user_password = md5('noob')
Now, I go for the basic starting point of trying to hack the crappy login with "admin'--"
select user_id from user where user_username = 'admin'--' AND user_password = md5('noob')
but the actual value being pushed to the database is
select user_id from user where user_username = 'admin\'--' AND user_password = md5('noob')
which doesn't help. The server uses POST to get the values from the form. I've already bypassed any value processing on my side of the send by disabling javascript.
There does not appear to be anything in the php that modifies the input in any way.
Assuming the select statement is part of a login form, then most likely it's generated something like this:
$user = $_POST['username'];
$pwd = $_POST['password'];
$query = "SELECT .... WHERE user_username='$user' AND user_password=md5('$pwd')";
which means, you could hack in by entering:
noob') or ('a'='a
for the password, giving you
SELECT .... AND user_password=md5('noob') or ('a'='a')
^^^^^^^^^^^^^^^^^-- your contribution
The actual password might not match, but 'a' will always equal itself, so the where clause will succeed and match a record based purely on the username and return the admin user's user_id.
As others had mentioned the escaping that you see is not the OS, but some form of encoding done in PHP (likely magic quotes, but could be a straight call to addslashes()).
Basically what you need to do is send in a form of quote that will not be escaped. You should research why one would use mysql_escape_string() rather than addslashes() and/or check this out: http://forums.hackthissite.org/viewtopic.php?f=37&t=4295&p=30747
Try ' OR 1; -- as user name. Imagine what the SQL query from such a user name looks like.
This has nothing to do with the operating system. The operating system simply runs the PHP package. PHP is what does sanitization, etc.
Have you tried submitting the following string for user_username?:
admin' OR 1=1-- #assuming mysql
Would yield a query:
select user_id from user where user_username = 'admin' OR 1=1 --' AND user_password = md5('noob')
In mysql (assuming the database type), -- is a comment, so everything after 1=1 is ignored. As a result, you've successfully gained access.
If php magic quotes are on, however, this will be slightly more difficult. You will need to submit characters outside of utf-8 or attempt overflows or submitting null bytes.
You could also try a bit of googling after entering a string that will error out the admin and use part of message that comes back as the key words.
You could also use the http://gray.cs.uni.edu/moodle/mod/forum/discuss.php?d=106 fourm to ask questions so the whole class can benifit!
if you can figure out how to upload files that would be great! I want to get c99.php up to really do some damage!
you could also try some "hash" verse "dash dash"
Related
I have a php script which selects from a MySQL table. The Table Content is set to UTF8, so is the php script interfacing with it.
The input strings are real_escaped. I am facing the following issue:
Given the following data in the table:
ID Username
1 Test
2 Test1
3 Test-A
The following SQL returns the IDs for 1 and 2 successfully but when asked for the 3rd it returns nothing.
SELECT `ID` FROM `User` WHERE `Username` = '$User'
Why is it not returning when I ask for the ID where Username = Test-A?
Is it because the Username contains a minus?
It has to be a different string. Double check the dash/hyphen mark in both cases (may be different unicode characters like described here) - it happens frequently when copying and pasting data from "rich" text editors.
Also check for whitespaces.
Depending on what you mean by "real_escaped" it might be the case that your username is escaped turning into something similar to ('Test\-A') which essentially does not exist.
Print out the value of the $User to check what you're sending to MySQL.
On top of that, you are using old outdated practices, there are better ways of querying the database securely with PDO::prepare (http://us1.php.net/manual/en/pdo.prepare.php), use those examples there.
I have browser game. There is message send form.
I didn't make real escape string function to the "message_content" variable.
There is any option, that the user could make after the insert of the message, any update ?
I mean that the user could write a sql code in the message_content that can UPDATE values in the sql? Like update users set gold = '9999' where username = 'my_username'
THANKS ALOT....
And that it only a question. Don't worry i already made mysql_real_escape_string...
Please learn about using parametrized queries, preferably with the PDO module, to protect your web app. http://bobby-tables.com/php has examples to get you started.
The mysql_query function doesn't allow the execution of multiple statements at once. So the often mentioned example of Robert'; DROP TABLE Students; -- won’t work.
This also means that the exploitation is restricted to the statement type. So if the injection point is in an INSERT statement, the vulnerability can only be exploited to insert arbitrary values into that specific table.
However, one can still inject arbitrary data from the database into that table. And if the attacker addresses the message to himself, he will be able to read arbitrary data from the database and may also be able to read and write arbitrary files on the server.
If you don't escape the user input the following can happen:
Imagine this query:
SELECT * FROM user WHERE login='$login'
where $loginis the user's input.
Now the user insers the following content in the variable: '; DROP TABLE user; --
The following query will be executed:
SELECT * FROM user WHERE login=''; DROP TABLE user; --'
It's a very generic example, but I hope you get the idea
I'm writing a script in PHP to allow a user to change their password. I make them enter their old password (even if they are logged in already) and then the new password. I'm trying to compare the old password and then update the field to the new password without running two separate queries, but my code isn't working like I expected. Is there a bug here? Or is this not allowed for some reason? What do you suggest?
mysql_query("UPDATE users SET userpass = '$encryptedPW' WHERE userid = '$uid' AND userpass = '$currentPW'");
I could see if mySQL performed the tasks in the order they're written, but it has to find the line before it can update it, right?
Thank you very much!
Billy
ETA: Sorry! Typo!
What does the actual generated query look like? Did you check if the query query succeeded?
$result = mysql_query("UPDATE ....") or die(mysql_error());
if (mysql_affected_rows() != 1) {
die("Failed to change password");
}
The or die() portion will handle any sql syntax errors, while the affected_rows will check if something did get updated. If the affected row count isn't 1 (assuming you're not allowing duplicate username/password pairs), then something didn't work right. 0 = no affected rows, no changes made. >1 = you've got duplicate user/password pairs.
Also make sure that you're comparin apples to apples. If you're storing the passwords in encrypted/hashed form, then you'll have to compare hashed/encrypted passwords for the results to make sense.
... WHERE password='letmein'
would fail if the password is actually stored as encrypted binary garbage.
from your code, I see that you use encrypted passwords. Check that you encrypted both passwords.
Furthermore, you have userpass and user_pass in your query. These are two "different" columns.
You have the right idea here, but I would advise against (for security concerns) using mysql_query() with unfiltered input. I'd rather see you using a prepared statement.
From your above query, however, it seems as if you have two different columns, user_pass and userpass. That may be the source of your woes for now.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is SQL injection?
I see a lot of php code floating around on stackoverflow and (too) little escaping of strings.
Can anyone
Explain what SQL injection is;
Explain what it can do to your server, data and code;
Give an example how to perform an SQL-injection
Give php sample code how to protect against SQL-injection
An SQL injection is a maliciously formed SQL query used to "confuse" an SQL database into giving something it shouldn't. For instance, consider the following query
"SELECT * FROM `users` WHERE `username` = '$name'";
In a normal case, this will work. If we submit 'Jack' to this, it will return all users named Jack. However, if a user enters, say "' OR 1=1", the resulting query would be
"SELECT * FROM `users` WHERE `username` = '' OR 1=1";
Since 1 always equals 1, and the combinating clause is OR, this will return true on every row, which will in turn display EVERY row to the malicious user. Using this technique, someone can view your entire database. Also consider if someone submits something like "'; DROP TABLE users";--, which results in
"SELECT * FROM `users` WHERE `username` = ''; DROP TABLE `users`";--";
Which is two queries, one which will do nothing, the second which will delete the ENTIRE users database, resulting in the loss of your data.
The best method to prevent SQL injections is to use prepared statements. With these, you send a query to the SQL database that says something like
"SELECT * FROM `users` WHERE `username` = '?'";
This lets the database know the format of the query (WHERE username equals some value), so there is no confusion when given a plain text query. Then the database knows to expect one value, and where to put it. Then you pass that value to the database which it can use to search. This is also better as the database can optimize the query for faster searching.
Read up on prepared statements, which will explain this in more detail.
I cannot resist aswell.
SQL Injection is "a code injection technique that exploits a security vulnerability occurring in the database layer of an application". In other words it's SQL code injected in as user input inside a query.
SQL Injections can manipulate data (delete, update, add ecc...) and corrupt or delete tables of the database. I'm not aware of SQL Injections manipulating scripts though.
Let's say in your PHP script you are expecting (as user input) a username and a password from the login form that are later used inside a query such as:
SELECT Id FROM Users WHERE Name = $name AND Password = $password;
The user can insert inside $name and as $password whatever he likes (for example trough an <input>). Let's imagine he adds a name such as "1 OR 1 = 1; --", the query will now look like:
SELECT Id FROM Users WHERE Name = 1 OR 1 = 1; -- AND Password = $password;
and then, after the ; I could add another query or make the script think that the username and the password actually exists.
Notice that -- AND Password = $password; is a SQL comment and will therefore be ignored.
If you are using PHP < 5 then you should look for mysql_real_escape_string() and use it to escape user inputs before embedding it inside a query.
If you are using PHP5+ you should use PDO or the mysqli extension which can prevent this problem via prepared statements.
I cannot resist posting this.
1- Sql Injection is explained better in one cartoon, than most other documents.
2- Mostly it does not do much to the server, but only to the underlying data. Consequence include delete, insert , select records, drop, create tables. (based on permissions etc..)
3- Examples.
4- Sorry I do not know PHP. But as long as you can abstract your DB layer from your View, you should be fine.
There's a lot of information out there (and elsewhere in here) about this subject, so do not take this answer as a complete list by any means and continue to research on your own...
Explain what SQL injection is;
Explain what it can do to your server, data and code;
Give an example how to perform an SQL-injection
Give php sample code how to protect against SQL-injection
SQL injection is where an attacker discovers that an input value supplied to your application is being sent directly to a database and realizes that they can craft that input to be a custom SQL command. It could be something as simple as entering a special character (such as %) into a text field and receiving a strange response.
It can do anything your database allows that command to do. For example, if your web application has DB owner permissions for the application's database then an attack can potentially drop tables or even drop the whole database. Or, with even normal application permissions, the attack can over-write data or read sensitive data (such as plain text passwords if you have those).
For example, if an application has a text field where you enter a username. If that field is open to SQL injection, an attacker can enter something like: MyName';DROP TABLE Users;-- In this example, the attack manually finishes the query with the closing single quote and semi-colon, then adds another query, then comments out anything afterward. If not protected against this, the database may run both queries.
This one I don't know updated enough information, but there's lots out there :)
So i was wondering if i this is OK or if theres another better and secure solution to grab info from the database.
if (isset($_SESSION['user_id'])) {
$string = mysql_query("SELECT * FROM users WHERE id = '$_SESSION[user_id]'");
$v = mysql_fetch_array($string);
}
Because I was thinking maybe its possible to hack the "session" and change user_id to another and woops they get access to any user...
Thank you
This depends on how the user_id gets into the Session in the first place.
As a rule of thumb, you should never place any unsanitized values into a query.
You should at least use mysql_real_escape_string.
Even better would be not to use the old and outdated mysql extension but mysqli's prepared statements.
I suggest escaping the user_id, just to be sure. You should also test if any rows were found (optional, depends on usage).
Every data coming from the user should be filtered, and never used directly in a query; this would avoid SQL injection.
Suppose the content of $_SESSION['user_id'] is ' OR id = '12' //; the query would become SELECT * FROM users WHERE id = '' OR id = '12' //'. Supposing that the user account with ID 12 has particular permissions that allow the user to delete content from the site, you can imagine the consequences.