刷刷刷刷刷
ctfshow
web4
查看源代码,似乎是SQL注入,连注释也给了
注意到传参id的值,同样是preg_match函数对变量$id进行正则表达式匹配
如果变量$id中包含后面那一串字符就终止程序,并输出id error
这里简要的写一下这几种过滤吧
or:应是用于防止sql注入中的逻辑操作 or 语句,例如万能密码 ' or 1=1 #' 还有 1 OR 1=1这种注入攻击
-(减号):同样是防止sql注入,sql注入中 -- 表示注释
\(反斜杠):防止路径遍历或转义字符注入。路径遍历攻击:..\ 或转义字符,攻击者可利用其进行绕过过滤
/(正斜杠):防止路径遍历或URL注入(../可用于路径遍历,/可构造恶意URL)
*:防止sql注入或通配符滥用(* 在SQL中攻击者可利用通配符(如*FROM)获取更多数据))
< >:防止xss跨站脚本攻击。尖括号< >可用于HTML标签,攻击者可通过注入<script>标签执行恶意Javascript代码
!:防止逻辑非操作或命令注入。(!可用于逻辑非操作(!=)或命令注入)
x:防止十六进制编码绕过。可使用x表示十六进制编码绕过(如0x41表示字符A)
hex:防止十六进制编码绕过。hex是sql注入中的函数,攻击时可以使用他进行编码。
( ):括号可用于sql函数调用(如SELECT version())或构造恶意逻辑
+(加号):防止SQl注入或字符串拼接或数学运算(如'a' + 'b')
select:同样是防止SQL注入中的SELECT语句获取敏感数据
\s:匹配所有空白字符,包括空格、Tab、换行符
注意末尾的 /i 代表不区分大小写
总之这些字符和字符串主要防止了
SQL注入、:or、- 、*、select、hex、
XSS攻击、:< >
路径遍历、:/ \
命令注入:! ( )
空白字符:\s
下面继续
get传参获取id的值
先测试一下,发现id=1 有回显
而id=2时查询结果为空
也就是说id=2时没有对应信息
再看intval()函数,这里需要了解intval函数转换字符串的用法
intval()函数在转换时,如果被转换的是字符串,则会从最左边第一个字符开始转换,直到遇到非整数的字符才会停止转换,这么说不太标准,还是这个清楚一些
输出的结果:
关于intval函数的其他作用这篇博客也有记录:PHP intval()函数详解,intval()函数漏洞原理及绕过思路_intval函数-CSDN博客
注意到上面例子的第4条,数字开头的字符串,仅转换数字,这么一来或许可以利用特殊字符(逻辑或||)来绕过intval函数的转换
此时注意到对id值大小的判断
id不能大于999,否则就会返回 id error,如当id=1000时
但又注意到代码结尾提示id=1000时可以得到flag
那么构造payload的整体思路就知道了
用 逻辑或 || 连接两个id的值,前一个用于绕过id大于999,(即构造id小于999)
后一个用于get flag(id=1000),然后||连接的整体用于绕过intval函数 (如 id=1 || id=1000)
但都不能触碰黑名单,所以空格要用%20绕过过滤,payload构造完成
诶,别忘了id=1时有正常查询结果,会将id=1000进行覆盖,而id=2时查询结果才为空,所以需要将1改为2。
这里解释一下payload
id=2 || id=1000
首先,刚刚的第4条,intval函数在遇到 id=2 后面的 || 字符时,停止转换,取id的值为2
id=2时,2<999,if语句判断($id>999)后返回false,随即执行else中的SQL语句
select * from article where id=2 || id=1000
结尾id=1000时可get 到flag
由于使用的 || 前部分id=2查询结果为空,没有返回信息,所以只会返回id=1000时的信息,即flag
注意绕过空格过滤的%20在URL地址栏里是不会显示的,但不代表可以不替换空格