Magic Quotes, addslashes and mysql_real_escape_string defense and bypass

Source: Internet
Author: User
Tags chr prepare sql injection stmt


0x00:php built-in filter function

PHP has built-in functions to defend against attacks and simply introduces several functions.


Magic Quotes

When turned on, all ' (single quotes), "(double quotes), \ (backslash), and NULL characters are automatically added with a backslash to escape. This is exactly the same as the addslashes () function.


A total of three magic quote instructions:

MAGIC_QUOTES_GPC affects HTTP request data (Get,post and cookies). Cannot be changed at run time. The default value in PHP is on. See GET_MAGIC_QUOTES_GPC ().

Magic_quotes_runtime if open, most of the functions that get data from external sources and return the data, including from the database and text files, are escaped by backslashes. This option can be changed at run time, and the default value in PHP is off. See Set_magic_quotes_runtime () and Get_magic_quotes_runtime ().

Magic_quotes_sybase if turned on, single quotes are escaped using single quotes instead of backslashes. This option will completely overwrite the MAGIC_QUOTES_GPC. If you open two options at the same time, the single quotes will be escaped to '. Double quotes, backslashes, and NULL characters are not escaped. How to get its value see Ini_get ().


Mysql_real_escape_string

Escape special characters in strings used in SQL statements: \x00, \ n, \ r, \, ', ', \x1a

Addslashes ()

Returns a string that is preceded by a pre-defined character with a backslash, a predefined character: ', ', \, NULL


Read a lot of PHP Web site in the anti-SQL injection is still using ddslashes and Str_replace, Baidu "PHP anti-injection" also used them, the practice found even mysql_real_escape_string there is a way hackers can bypass, If your system is still using the three methods above, the recommendation is better.

Anti-injection with str_replace and a variety of PHP character substitution functions I don't have to say, this "blacklist" defense has proven to withstand the test of time.


Here's how to bypass Addslasher and Mysql_real_escape_string (Trick).

If you are not sure if your system has the risk of SQL injection, please deploy the following demo to your server, and if the results are the same, refer to the final perfect solution.


Mysql:

Mysql> select version (); +---------------------+| version ()             |+---------------------+| 5.0.45-community-ny |+---------------- -----+1 row in set  (0.00 SEC) mysql> create database test  default charset gbk; query ok, 1 row affected  (0.00 sec) mysql> use test;database  changedmysql> create table users  (    username varchar (32)  character set gbk,    password varchar (+)  CHARACTER SET  GBK,    PRIMARY KEY  (username)); query ok, 0 rows affected  (0.02 sec) mysql> insert into users  set username= ' EWRFG ',  password= ' wer44 '; query ok, 1 row affected  (0.01 sec) mysql> insert into&Nbsp;users set username= ' ewrfg2 ',  password= ' wer443 '; query ok, 1 row affected  (0.01 sec) mysql> insert into users  set username= ' Ewrfg4 ',  password= ' wer4434 '; query ok, 1 row affected  (0.01 SEC) =


Php:


<?phpecho  "php version: ". Php_version. " \ n "; mysql_connect (' servername ', ' username ', ' password '); mysql_select_db (" test "); mysql_query (" Set names &NBSP;GBK "); $_post[' username '] = chr (0XBF). chr (0x27). '  or username = username /* '; $_post[' password '] =  ' guess '; $username  =  addslashes ($_post[' username '); $password  = addslashes ($_post[' password '); $sql  =  " select * from  users where  username =  ' $username '  AND  password =  ' $password ' "; $result  = mysql_query ($sql)  or trigger_error (mysql_error (). $sql); Var_dump (Mysql_num_rows ($result)); Var_dump (mysql_client_encoding ()); $username  = mysql_real_ Escape_string ($_post[' username '); $password  = mysql_real_escape_string ($_post[' password '); $sql  =  "select * from  users where  username =  ' $username '  and p assword =  ' $password '; $result  = mysql_query ($sql)  or trigger_error (mysql_ Error (). $sql); Var_dump (Mysql_num_rows ($result)); Var_dump (mysql_client_encoding ()); Mysql_set_charset ("GBK"); $ Username = mysql_real_escape_string ($_post[' username '); $password  = mysql_real_escape_ String ($_post[' password '); $sql  =  "select * from  users where   username =  ' $username '  AND password =  ' $password '; $result  = mysql_ Query ($sql)  or trigger_error (Mysql_error (). $sql), Var_dump (Mysql_num_rows ($result)); Var_dump (Mysql_ Client_encoding ());


Results:

PHP Version:5.5.44int (3) string (6) "Latin1" int (3) string (6) "latin1" int (0) string (3) "GBK"

It can be seen whether using addslashes or mysql_real_escape_string, I can use a coded vulnerability to enter any password can be entered into the server injection attack!!!!



0x01: Wide byte injection

Although all programs are now calling for Unicode encoding, all websites use UTF-8 encoding for a unified international specification. However, there are still a lot of CMS, including domestic and foreign (especially non-English-speaking countries), still use a set of their own country code, such as GBK, as their default encoding type. There are also some CMS in order to consider the old users, so out of GBK and utf-8 two versions.


We will take the GBK character code as a demonstration, the curtain is opened. GBK is a multi-character encoding, and there is one place in particular to note:

Typically, a GBK encodes a Chinese character, taking up 2 bytes. A utf-8 encoded Chinese character that occupies 3 bytes. In PHP, we can use the output

Echo strlen ("and");

To test. Output 2,utf-8 When the page encoding is saved to GBK is 3.


All ANSI encodings are 2 bytes apart from GBK. ANSI is just a standard, on the unused computer It may represent a different encoding, such as the Simplified Chinese system ANSI is represented as GBK.


As above, there are two ways to bypass the limitations of magic quotes, such as:

1. Add a \ (or a single number) to \ \, so that \ is escaped, ' escaped the limit

2. Remove the \.


Our wide-byte injection here is a feature of MySQL, which, when used with GBK encoding, considers two characters to be a Chinese character (the previous ASCII code is greater than 128 before the range of Chinese characters).

This is the feature of MySQL, because GBK is multi-byte encoding, he thinks that two bytes represents a Chinese character, so%df and the back of the%5c become a Chinese character "", and ' escaped out. Try again "%df%df%27", will not error. Because%DF%DF is a Chinese character,%5c%27 is not a Chinese character, still is \ '.


So MySQL how to judge a character is not a kanji, according to GBK encoding, the first byte ASCII code is greater than 128, basically can be. For example, we do not need to%DF, with%A1 can also,%a1%5c he may not be Chinese characters, but will be considered by MySQL is a wide character, you can let the back of the%27 escape out.


But it's important to note that

GB2312 and GBK should all be part of a wide-byte family, but not injected, due to the range of gb2312 encoded values. Its high-level range is 0xa1~0xf7, the low range is 0xa1~0xfe, and \ is 0x5c, is not in the low range. So, 0x5c is not the code in the gb2312, so nature will not be eaten.


So, to extend this idea to all the multibyte encodings in the world, we can assume that wide-character injection can be done as long as the low range contains 0x5c encoding.



0x02: fix for wide character injection


Call the Mysql_set_charset function to set the connection using the character set GBK, and then call mysql_real_escape_string to filter the user input.


This way is feasible, but there are some old CMS, in many places using addslashes to filter strings, we can not go to a addslashes all modified to mysql_real_escape_string. Our second solution is to set the character_set_client to binary (binary).


Just specify before all SQL statements that the form of the connection is binary:


mysql_query ("SET character_set_connection=gbk, Character_set_results=gbk,character_set_client=binary", $conn);


What do these variables mean?


When our MySQL receives the data from the client, it will think that his code is character_set_client, then it will be replaced with character_set_connection code, then into the specific table and field, and then converted to the corresponding encoding of the field.


Then, when the result of the query is generated, it is converted from the table and field encoding to Character_set_results encoding, which is returned to the client.


Therefore, we set the character_set_client to binary, there is no wide-byte or multi-byte problem, all data in the form of binary transmission, can effectively avoid wide character injection.



0x03:pdo and Mysqli

The perfect solution is to use PDO and mysqli with the prepared statement mechanism instead of mysql_query (note: mysql_query since PHP 5.5.0 has been discarded and will be removed in the future):




Pdo:

$pdo = new PDO (' Mysql:dbname=dbtest;host=127.0.0.1;charset=utf8 ', ' user ', ' Pass '); $pdo->setattribute (pdo::attr_ Emulate_prepares, false); $pdo->setattribute (Pdo::attr_errmode, pdo::errmode_exception); $stmt = $pdo->prepare (' SELECT * FROM employees WHERE name =: Name '); $stmt->execute (Array (' name ' = $name)); foreach ($stmt as $row) {/ /do something with $row}


Mysqli:


$stmt = $dbConnection->prepare (' SELECT * FROM employees WHERE name =? '); $stmt->bind_param (' s ', $name); $stmt->execute (); $result = $stmt->get_result (); while ($row = $result FETCH_ASSOC ()) {//Do something with $row}


This article is from the "Smokers" blog, please be sure to keep this source http://wt7315.blog.51cto.com/10319657/1931667

Magic Quotes, addslashes and mysql_real_escape_string defense and bypass

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.