sql注入之union联合注入

发布时间 2023-07-17 00:33:20作者: gsjisgsj

注入原理

利用union select对两个表进行联合查询

注意:union前后两个select查询的字段数要一样,否则会报错

为什么可以呢?

以上是测试靶场的源代码,因为测试的靶场是通过$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";语句来进行查询,而id则是我们在前端传入的参数,显然,有' ',是一个字符型注入,因此我们可以自己加一个‘,利用union来对靶机网站进行渗透

注入流程

  1. 首先通过sqlmap或者其他扫描软件判断到有字符型注入点;或者手动判断,输入1' and '1'='1输出的页面结果和输入1' and '1'='2的页面结果不相同,因此可以确定存在注入

以下为我试验的图:

输入1‘ and '1'='1的结果!


输入1‘ and '1'='2的结果

显然这里存在注入且由’的位置可以知道是字符型注入(教程里面都说了,显然的哈哈哈)

  1. 由于union前后两个select需要select相同的字段数,因此这一步是要判断这个表的字段数。输入1' order by N (注意,N一般大于1,从尽量大一点的数开始试。) 知道试出正确结果为止,N则为前面查询字段数

输入1' order by 3-- 的结果!

显然不是3个字段,再往下尝试,知道2发现有结果,因此前面的select显然字段数为2

  1. 此时就可以尝试使用union来获取相关数据。学过mysql的很容易就可以知道information_schema这个表里记录了整个数据表的信息,因此此时我们可以这样输入:-1' union select 1,(select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1)--+

原理:information_schema的TABLE表,记录着某个库的表名TABLE_NAME,TABLE_SCHEMA代表着某个库,database()可以获取当前使用数据库的名字;--+是为了注释掉原有sql语句后面的'(在后台的);limit 0,1中0代表第几个表,1代表只输出几行(前面-1’加-是因为不想输出前面的,复数默认前面不输出),只需要修改前面的0所对应的数字,就看可以得出全部表的名字,如下图所示:



surname为空代表没咯,就是只有两个表,分表为guestbook和users

  1. 接下来获取其他敏感信息,获取每个表的字段名,尝试输入:

-1' union select 1,(select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='users' and TABLE_SCHEMA=database() limit 0,1)--+

如下图所示

获取到的字段名分别为user_id、user、password等,一般来说根据英文就这里就login和password有用,后面的正常来说也不会有用

  1. 接下来可以获取到相关用户的账号密码信息了,输入:

    -1' union select 1,(select group_concat(user,0x3a,password) from users)--+