攻防世界-easyphp(前导数字字符串、数字字符串、数字弱类型比较)
一道php代码审计题,利用了字符与数字弱类型比较的漏洞。
一、基础知识
- 数字字符串
形如数字形式的字符串叫做数字字符串,例如:'123456','1e56112'(科学计数法),'123.4'(单纯的数字,没有其他字符,只是数据类型为字符串);数字字符串在与数字或者数字字符串进行比较时会转化为数字来进行比较。
- 前导数字字符串
前导数字字符串就是,前缀部分为数字字符,后接其他字符的字符串,例如:'123456abcde','1e456789abcde','123.4aaa'(注意必须是前缀部分为数字字符,例如:'aa123456bcd'就不是前导数字字符串)。前导数字字符串在进行弱类型比较时,只有在与数字进行比较时,才会转化为数字,即使是两个前导数字字符串进行弱类型比较也不会转化为数字。
- 其余字符串
对于既不是数字字符串也不是前导数字字符串的字符串,只会在与数字进行弱类型比较时转化为数字,且只能转化为0。
- is_numberic()函数
如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE,注意浮点型返回 1,即 TRUE。
- 字符串与数字弱类型比较测试结果
总结下来就是,数字与字符串进行弱类型比较时,会将字符串转化为数字。当字符串为数字字符串或者前导数字字符串时,会转化为相应数值的数字,当为普通字符串时会转化为0(数字0);字符串与字符串的比较规则为从左往右将字符进行比较,若要相等则所有字符得相等,若要比较大小,以第一个不相等的字符比较结果作为字符串大小结果。另外true和任何比较都能满足。
但特殊的是需要注意数字字符串与数字字符串之间的比较是转化为数字进行比较!
- 弱类型比较的函数与比较符
=,==,<,>,array_search,in_array, 后续遇到会添加上来,或是有知道的小伙伴,欢迎在评论区分享
二、分析代码
从下往上分析,易知当$key1和$key2的值都为真时会输出flag。
先看$key1,在第一个if里面,通过GET上传a和b的值来使$key1=1,要求的条件为:a是长度为3的整数,且a要大于6000000以及b的MD5加密值的后六位为8b184b。
对于a的构造,我们可以用科学计数表示法来令a=6e9使其满足条件
对于b的构造,我们可以使用脚本,爆破得出b的值b=53724
所以可以先构造payload为 ?a=1e9&b=53724
接着是$key2,$key2是通过上传json形式的c来实现控制。
c要满足的条件为:为json数据格式,是数组,至少含有键名为m,n的两个键值对
键m对应的值要满足:is_numeric()函数判定为假,且与2022进行>比较时要为真。
由于is_numberic会将数字和数字字符串判定为真,但前导数字字符串不会以及>是弱类型比较,且是将c['m']的值与数字进行比较,所以,我们可以直接用前导字符串来作为比较数字与2022进行比较。所以令c['m']='2023a'
键n对应的值要满足:有且仅有两个元素的数组,第一个值为数组,此处易于实现;第二个值要满足array_search("DGGJ", $c["n"])返回为真,同时c["n"]中又不能出现"DGGJ"。此处利用array_search函数在比较两者是否相等时是使用的弱类型比较。又由于"DGGJ"是既非数字字符串又非先导数字字符串的字符串,其在与数字进行比较时会转化为数字0。从而令c['n']的第二个值为0。(一点思考:此处若不是'DGGJ'而是其他字符串时,我们应该视情况而定,选择合适的数字)所以令c['n']=(array(1,2),0)
综上可以令c=array('m'=>'2023a','n'=>array(array(1,2),0)),然后再json_encode一下
构造payload为c={"m":"2023a","n":[[1,2],0]}
最后构造payload为?a=1e9&b=53724&c={"m":"2023a","n":[[1,2],0]}
返回结果为
flag为You're right cyberpeace{70fd15cef40f0516bc2fe7cef5484ff0}
趁热打铁,可以试试这道题
攻防世界-easyphp(前导数字字符串、数字字符串、数字弱类型比较)的更多相关文章
- 攻防世界(XCTF)WEB(进阶区)write up(一)
cat ics-05 ics-06 lottery Cat XCTF 4th-WHCTF-2017 输入域名 输入普通域名无果 输入127.0.0.1返回了ping码的结果 有可能是命令执行 ...
- js 字符串转换成数字的三种方法
在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形 ...
- js 字符串转换成数字(转)
转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才能正确运行:对其他类型返回的 ...
- js字符串转成数字的三种方法
js读取的html代码中获得的值 ,统统是以字符串的形式呈现的,为了方便我们后面对数据的操作,有时候我们有必要进行转换一下. 方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转 ...
- js 字符串转化成数字
方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有 ...
- js 字符串转化成数字:(实例:用正则检测大于0的正数,最多保留4位小数)
来源:http://www.cnblogs.com/hwx0807/archive/2011/06/28/2092021.html 实例: function BindSubmitEvent() { / ...
- JavaScript字符串转换成数字的三种方法
在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b.value,因为他们都是字符串形 ...
- JavaScript进阶(四)js字符串转换成数字的三种方法
js字符串转换成数字的三种方法 在js读取文本框或者其它表单数据的时候获得的值是字符串类型的,例如两个文本框a和b,如果获得a的value值为11,b的value值为9 ,那么a.value要小于b. ...
- js字符串转换成数字与数字转换成字符串的实现方法
转载:点击查看地址 js字符串转换成数字 将字符串转换成数字,得用到parseInt函数.parseInt(string) : 函数从string的开始解析,返回一个整数. 举例:parseInt(' ...
- js字符串转换成数字,数字转换成字符串
转自网络,忘记出处了. js字符串转换成数字 将字符串转换成数字,得用到parseInt函数. parseInt(string) : 函数从string的开始解析,返回一个整数. 举例:parseIn ...
随机推荐
- 与TNF拮抗剂治疗AS临床和MRI疗效相关的血清生物标记物
与TNF拮抗剂治疗AS临床和MRI疗效相关的血清生物标记物 PresentID: THU0223 SERUM BIOMARKERS ASSOCIATED WITH CHANGES IN ASDAS A ...
- vue浏览器全屏 非全屏切换 按esc退出全屏
methods: { // 全屏 点击按钮 allping(){ this.status = true; this.enterFullscreen(); ...
- unity resMgr
yooAsset GitHub - tuyoogame/YooAsset: unity3d resources management system xAsset GitHub - xasset/xas ...
- LVS的NAT,TUN,DR原理及区别
原理及其区别 Linux Virtual Server是通过ipvs内核模块和ipvsadm用户空间命令行工具来实现负载均衡的它支持三种工作模式: NAT模式:LVS调度器将请求转发给后端服务器,同时 ...
- CF1137F Matches Are Not a Child's Play 题解
以最后被删去的点为根,这样子不会存在从父亲然后删掉某个点,儿子的删除顺序一定比父亲前. 记每个点子树中的最大值为 \(f_x\),那么一个点的排名,首先就需要加上 \(<f_x\) 的所有值,记 ...
- 2023 年 CCF 春季测试赛模拟赛 - 1
T1 个人思路: 询问:求 \(1\) 到 \(t_i\) 路径上离 \(1\) 最远的 \(p\),使得 \(dis_{1,p} \times 2 \le d_i\).即 \(dis_{1,t} \ ...
- cannot import name 'detail_route' from 'rest_framework.decorators'的解决办法
原因 es7不能使用3.1.1版本的django-haystack 解决办法 如果你是在弄elasticsearch,那么这个适合你,否则应该用不了. 终端执行django-haystack的更新 p ...
- 1.1 创建一个WCF应用程序服务
第一步:引入System.ServiceModel.dll 第二步 定义一个WCF接口: //定义接口 [ServiceContract] interface IGetInfo { [Operatio ...
- linux修改ssh默认端口
1 . 登录服务器,打开sshd_config文件 vim /etc/ssh/sshd_config 2 . 找到#Port 22,默认是注释掉的,先把前面的#号去掉,再插入一行设置成你想要的端口号, ...
- 【SQL Server】中的日期函数和日期数据类型
SQL Server Date 函数 SQL Server的重要日期函数包括: 函数 描述 参数含义 GETDATE() 返回当前的日期和时间 DATEPART(datepart,date) 返 ...