SQL的union注入

目标:

  1. 了解union注入过程运用到的关键数据库,数据表,数据列
  2. SQL查询中group_concat的作用
  3. 最终使用union注入拿到靶机中数据库里面的所有用户名和密码

1.1拿到表名和列名

步骤:

  1. 查找注入点

    这里默认注入点为id参数,在地址后面加?id=1

注入点演示
2. 查找是数字型还是字符型注入

这里可以在id后面用减法运算来判断,若是id=2-1和id=1输出的结果相同,则为数字型注入,若结果不同,则为字符型注入

  • 字符型源码
1
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"
  • 提交1 and 1=1
1
$sql="SELECT * FROM users WHERE id='1 and 1=1' LIMIT 0,1"
  • 数字型源码
1
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"
  • 提交and 1=2
1
$sql="SELECT * FROM users WHERE id=$id and 1=2 LIMIT 0,1"

判断注入演示

可以看到,这里的结果和上面那一张图片的输出的结果不一样,则可以判断应该为字符型注入

  1. 若是为字符型注入,则应当判断闭合方式(数字型可以跳过)

    我们可以通过加上一个单引号或者双引号然后观察报错来判断闭合类型

判断闭合演示

  • 我们可以看到报错为

    ‘ ‘2’ ‘ LIMIT 0,1 ‘ at line 1

  • 其中第一个单引号和最后一个单引号是对应关系,因此可以发现我们的’2’’多了一个单引号,由此判断为单引号闭合
  1. 寻找回显位
  • 上一步我们知道了闭合关系,接下来我们要寻找回显位,我们在上一步的地址之后加上–+

    这里–+是为了注释掉后面的语句,防止干扰我们,这样子我们就可以把我们要执行的命令插入到这里面

我们先要判断原表的列数,因为union要求前后的列数要一致

  • 可以使用order by或者group by来判断有多少列
    order by报错

    可以看到这里找不到第五列,通过二分法继续降

order by成功

最终找到有三列

接下来就可以查找回显位(注意这里用id=-2是因为回显只有第一行数据才会回显,因此我们直接用一个在原表里不存在的数据从而显示出我们想要的数据)

在hackerbar里输入:?id=-2’ union select 1,2,3–+

回显位

  • 可以发现回显位是2,3
  1. 获取当前数据库名
    获取数据库名

    可以直接在回显位输入database()获取数据库名

  2. 获取该数据库下的所有表名和列名
  • 首先需要知道在information_schema数据库中,存着所有数据库的简要信息。
  • information_schema.tables:记录了所有的表信息。
  • information_schema.columns:记录了所有的列的信息

由此我们就可以构造出注入语句

id=0’union select 1,table_name,3 from information_schema.tables–+

(由于我们是在别的库里,所以如果要查别的库别的表必须要带上(库的名字.表的名字))
图片

发现只能回显出一个

information_schema.tables
由于数据库有很多表名,我们应当加一点限制条件,TABLE_SCHEMA存储的是数据库的名字

id=0’union select 1,table_name,3 from information_schema.tables where table_schema=database()–+

(这里也可以用’security’不过database()一般更好绕过)

这里又出现新问题了,我们有很多表名,但是回显只能显示一个,这时候就要用group_concat()了

id=0’union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()–+

图片
这时候就全部回显出来了
同样的思路:

  • 我们可以用相同的方法找到列名
    information_schema.columns
    可以观察一下information_schema.columns中的列名,其中COLUMNS_NAME放的是我们所有列的名字,由此我们可以编写出注入命令

    id=0’union select 1,group_concat(column_name),3 from nformation_schema.columns where table_schema=database() and table_name=’users’–+

输出结果

这个table_name=’users’可以从上上张图片的回显得到,我们判断users这张表有我们所需的数据

1.2获取数据

知道数据库名、表名、列名后,就可以直接查询目标数据了。为了防止用户名和密码连在一起看不清,可以在中间加一个分隔符(~)

1
id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

成功图
可以看到最终成功获取敏感数据


本站为rabow的个人博客