我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

文章目录

参考

项目描述
搜索引擎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

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录