文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

[WUSTCTF 2020]朴实无华:PHP 下的 intval 绕过技巧

2023-10-22 09:53

关注

文章目录

参考

项目描述
搜索引擎BingGoogle
AI 大模型文心一言通义千问讯飞星火认知大模型ChatGPT
PHP 手册PHP Manual
WriteUpNSSCTF

环境

项目描述
PHP5.5.05.6.87.0.07.2.57.4.98.0.08.2.9

intval()

主角登场

在 PHP 中,intval() 函数用于将其他类型的数据转化为整型数据。

intval(mixed $value, int $base = 10): int

其中:

项目描述
$value需要使用 intval() 进行转化的数据,该参数的值可以是一个整型数值,但转化结果与原数据不会存在任何区别(由该函数的功能决定)。
$base指定被转化数据 $value 采用的进制(默认为十进制),intval() 将据此解析 $value 并将其转化为 十进制整型数值

截断而非四舍五入

intval() 函数将 浮点数(含有小数点的数值) 转化为 整数数值 的方式是以小数点为基准将浮点数分为两部分,原浮点数的整数部分即为转化结果。对此,请参考如下示例:

var_dump(intval('948.53975'));var_dump(intval(0.454397));

执行效果

int(948)int(0)

进制转化

intval() 函数的 $base 参数仅在 $value 参数的数据类型为 字符串 时生效。因此,当你需要将一个 采用 $base 进制的数值 转化为 十进制数值 时,需要 先将该数值转化为字符串 再交由 intval() 函数进行处理。

# 尝试将八进制数值 36363.33, 8 转化为十进制整数值var_dump(intval(36363.33, 8));# 尝试将字符串(包含八进制数值) 36363.33 转化为十进制整数值var_dump(intval('36363.33', 8));

执行效果

int(36363)int(15603)

字符串解析规则

十进制字符串

$base 参数的值为默认值 10 时且 $value 参数的值为字符串类型的数据时,intval() 函数的解析规则如下:

  1. 若字符串的 首个字符不为数字且不为空格等空白字符,则将该字符串转化为零。
  2. 若字符串的 首个字符不为数字但为空格等空白字符,则尝试读取其余字符,忽略遇到到数字字符前的所有空白字符,在遇到非数字字符时停止对字符串的读取并将已读取字符转化为数值
  3. 若字符串的 首个字符为数字,则尝试读取其余字符,在遇到非数字字符(除符合科学计数法格式的字符 e 或 E外)时停止对字符串的读取并将已读取字符转化为数值

举个栗子

var_dump(intval(' 457.935HELLO'));var_dump(intval('Hello45995'));var_dump(intval('  0000053.0494   '));var_dump(intval('0x2f'));var_dump(intval('0b10101'));

执行效果

int(457)int(0)int(53)int(0)int(0)
其他进制

intval() 函数的 $base 参数的值不为默认值且 $value 的数据类型为字符串时,intval() 的解析规则以十进制字符串的解析规则为基础,正常解析其他进制下的特有数字字符(十六进制数包含 abc 等特有数字字符)及前缀(如以 0x0X 为前缀的数值常用于表示十六进制数)。 对此,请参考如下示例:

# 十六进制字符串var_dump(intval('   0X2FHELLO', 16));var_dump(intval('00000x2FHELLO', 16));var_dump(intval('2FHELLO', 16));var_dump(intval('0x18', 16));# 十进制字符串var_dump(intval('0x18'));# 二进制字符串var_dump(intval('0b03940', 2));var_dump(intval(' 0B1010101', 2));var_dump(intval('H010101', 2));var_dump(intval('1010101', 2));

执行效果

int(47)int(0)int(47)int(24)int(0)int(0)int(85)int(0)int(85)

注:

在使用 intval() 处理其他进制的字符串时,需要注意到字符串中的 数值部分 是否以相对应的前缀开头。十六进制数值以 0x0X 为前缀,而不是 0000X70x 等。

var_dump(intval('0x2b', 16));var_dump(intval('0000x2b', 16));var_dump(intval('    0X2B', 16));var_dump(intval('0b10011', 2));var_dump(intval('0000B10011', 2));var_dump(intval('    0B10011', 2));

执行效果

int(43)int(0)int(43)int(19)int(0)int(19)

科学计数法

e/E 表示法

在 PHP 中,eE 均表示 科学计数法(Scientific Notation)。科学计数法由 基数指数 两部分组成,常用于 表示非常大或非常小的数值。

在科学计数法中,基数 通常 是一个浮点数,介于 110 之间,而指数是一个整数,表示要将基数乘以 10 的多少次方。基数与指数之间以字符 eE 进行分隔。

举个栗子

# 1 * 10 ^ 2var_dump(intval('1E2'));# 3.688 * 10 ^ 2var_dump(intval('3.688e2'));# 9999 * 10 ^ -3var_dump(intval(9999E-3));

执行效果

上述示例在 PHP8.0.0 中执行,得到结果如下:

int(100)int(368)int(9)

intval() 在 PHP 不同版本中的表现差异

PHP7.2.5 版本及以上

intval()PHP7.2.5 及以上版本 中的表现符合预期,与我们对科学计数法的认知相符。

PHP7.2.5 版本以下

intval() 函数PHP7.2.5 以下的某个版本以前(仅测试了 PHP7.2.5 与 PHP7.0.0,PHP7.0.0 中,intval() 的表现存在异常,而在 PHP7.2.5 则表现正常。) 表现异常,intval() 的异常行为具体如下:

var_dump(intval('1E2'));var_dump(intval(1E2));var_dump(intval('3.688e2'));var_dump(intval(3.688e2));var_dump(intval('9999E-3'));var_dump(intval(9999E-3));

执行效果

int(1)int(100)int(3)int(368)int(9999)int(9)

PHP7.2.5 以下的某个版本 以前,intval() 函数无法正确解析字符 Ee,于是 intval 在解析到 Ee 时立即停止,这导致科学计数法实际并未生效。

[WUSTCTF 2020]朴实无华

可能性分析

2020 年举办的 CTF 比赛 WUSTCTF 中存在一道名为 朴实无华WEB 题,其中存在这么一段代码:

if(intval($num) < 2020 && intval($num + 1) > 2021){echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.
"
;}else{die("金钱解决不了穷人的本质问题");}

我们需要传递一个 字符串 作为 $num 的值使得判断语句成立以 使得程序继续进行,而不是因为 die() 函数 的执行而停止。

从逻辑上来说,没有一个数值(字符串形式)可以使得 $num 满足判断语句。但请不要忘记,intval() 在某些 PHP 版本中 对使用科学计数法的数值(字符串)无法正常解析,这也就产生了绕过的可能。

绕过

$num 在第二个 intval() 函数中以 表达式 的形式出现,字符串在与数值进行运算时,PHP 会将字符串转化为数值使用科学计数法的数值(字符串) 在某些版本中无法被 intval() 正确解析,但 PHP 是认得它的,在与数值 1 进行加法运算时,$num 将被 PHP 正确解析。于是,我们尝试将 $num="1e4"。对此,请参考如下示例:

$num = '1e4';if(intval($num) < 2020 && intval($num + 1) > 2021){    echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.
"
;}else{ die("金钱解决不了穷人的本质问题");}# 测试print("\n");var_dump(intval($num));var_dump(intval($num + 1));

执行效果

尝试在 PHP7.0.0 版本下执行上述代码,得到如下结果:

我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>int(1)int(10001)

来源地址:https://blog.csdn.net/qq_44879989/article/details/133418606

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯