Is SQL injection possible in this code?

Introduction

I took over the maintenance of a really dirty PHP page, which is a platform for booking holiday apartments, but it doesn’t matter. The code was originally executed by the designer (not the encoder), and this is very bad. Passing logical variables along the lines of true and false is one of the minor WTFs. I want to convince the owner of the page, give me time (and money, of course) to clear the code (or rewrite it).

Apparently, the original “developer” had never heard of SQL injection, because he used the POST and GET variables directly in his SQL statements. To convince the owner, I want to hit his character by logging in as an administrator without using my password.

tl; dr (or: actual question)

This statement (where $ p_username is the POST variable that contains the contents of the "Username" input field):

"SELECT password FROM user WHERE username = '$p_username'" 

The returned string (which is an unsaved MD5 hash of the password that was stored in the database) is then compared with the (also hashed) string that was entered in the Password field, and if both lines correspond to the user, it is registered as the entered user. Can I insert something into the username field to log in as a "fake" administrator?

Note. The database server is MySQL, PHP is in Version 5 and magic_quotes enabled.

+4
source share
6 answers

As Colonel Shrapnel noted, magic_quotes makes it impossible if you do not fulfill some special circumstances .

However, if you are telling the truth, it is likely that the original developer knew little about magic_quotes, so most likely he messed up if he ever saved the GET / POST / COOKIE values ​​somewhere else besides the SQL statements. In short, find places where ' and " will be legal, and check to see if they are confused.

Also, did he know about htmlspecialchars() , or is it possible to use HTML / Javascript? :)

+2
source

With the magic quotes enabled, this would not be possible.

0
source

If this is a complete request and password verification is done on the PHP side, you won’t be able to log in as an administrator (even if magic_quotes is turned off), because you still have to match the password hash.

0
source

EDIT

There are several attack vectors with addslashes() . The first, which I chose below, was based on an article previously associated with the answer, in which it is cited to support the opposite statement. At least one of them has overlapping strings using at least UTF-8 encodings.

http://www.erich-kachel.de/?tag=addslashes

You can build a similar technique, as shown below. Long and short, the MySQL team found it necessary to retire magic_quotes , and also strongly recommended against the pretending addlashes () - a real form of protection. Maybe, you know, the MySQL team will know better? For what it's worth, mysql_real_escape_string has some vulnerabilities in extreme cases, but since it is specific to MySQL, and not just to PHP-specificity, it is one step ahead. The best solution would be to use query parameters.

Original answer follows

Yes, you can log in as admin. Not at a time, but two passes will do it.

Ref - http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string (Yes, this is the same link from another answer, but instead, my interpretation is that it is usually possible for any multibyte character set except utf8)

You did not indicate whether the system is multibyte, but since the question is open, I assume that it is.

 $p_username = chr(0xbf) . chr(0x27) . ';' . "update user set password='password', '. "username='" . chr(0xbf) . "' where username='admin' /*'; "SELECT password FROM user WHERE username = '$p_username'" 

I changed the username and password of the user "admin"

This type of attack is possible with any character encoding where there is a valid multibyte character that ends with 0x5c

0
source

As others have noted, getting one quote from past magic quotes is difficult, but if you can do this, the request will be a toast. Consider whether we can introduce the following:

 SELECT password FROM user WHERE username = 'unlikely' UNION ALL SELECT CHAR(102,111,111); #' 

This will return the string “foo” to PHP as a password, so all we need to do is ensure that our form sends our injection for $ username and “foo” for password $.

0
source

I think it is important to check all input variables and avoid all special characters, even if magic_quotes is enabled.

Of course, you can test your code with sqlmap.

-2
source

Source: https://habr.com/ru/post/1339527/


All Articles