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

文章目录

  • 参考
  • 环境
  • intval()
      • 主角登场
      • 截断而非四舍五入
      • 进制转化
      • 字符串解析规则
          • 十进制字符串
          • 其他进制
  • 科学计数法
      • e/E 表示法
  • intval() 在 PHP 不同版本中的表现差异
      • PHP7.2.5 版本及以上
      • PHP7.2.5 版本以下
  • [WUSTCTF 2020]朴实无华
      • 可能性分析
      • 绕过

参考

项目描述
搜索引擎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() 函数用于将其他类型的数据转化为整型数据。

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

其中:

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

截断而非四舍五入

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

php"><?php


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

执行效果

php">int(948)
int(0)

进制转化

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

php"><?php


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

执行效果

php">int(36363)
int(15603)

字符串解析规则

十进制字符串

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

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

举个栗子

php"><?php


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

执行效果

php">int(457)
int(0)
int(53)
int(0)
int(0)
其他进制

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

php"><?php


# 十六进制字符串
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));

执行效果

php">int(47)
int(0)
int(47)
int(24)
int(0)
int(0)
int(85)
int(0)
int(85)

注:

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

php"><?php


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));

执行效果

php">int(43)
int(0)
int(43)
int(19)
int(0)
int(19)

科学计数法

e/E 表示法

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

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

举个栗子

php"><?php


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

执行效果

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

php">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() 的异常行为具体如下:

php"><?php


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));

执行效果

php">int(1)
int(100)
int(3)
int(368)
int(9999)
int(9)

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

CTF_2020_251">[WUSTCTF 2020]朴实无华

可能性分析

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

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

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

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

绕过

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

php"><?php


$num = '1e4';

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

# 测试
print("\n");
var_dump(intval($num));
var_dump(intval($num + 1));

执行效果

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

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

http://www.niftyadmin.cn/n/5057924.html

相关文章

linux 监控CPU利用率

监控CPU利用率 使用vmstat来分析CPU使用信息 #!/bin/bashDATE$(date %F" "%H:%M)IP$(ifconfig eth0 |awk -F [ :] /inet addr/{print $4}) # 只支持CentOS6MAIL"examplemail.com"if ! which vmstat &>/dev/null; then echo "vmstat comman…

Python中的数据常见问题

数据可视化在Python中是一个非常重要的主题&#xff0c;它可以帮助我们更好地理解和分析数据。无论是探索数据的特征&#xff0c;还是向其他人展示数据的结果&#xff0c;数据可视化都起到了关键作用。然而&#xff0c;在进行数据可视化时可能会遇到一些常见问题。本文将为您分…

【面试高高手】 —— Java集合篇(23题)

文章目录 1.Java中常见集合有哪些 &#xff1f;2. 说说你对Java集合是怎么理解的&#xff1f;3.请你说一下List&#xff0c;Set&#xff0c;Map三者的特点是 &#xff1f;4.在实际开发过程中如何更好的选择集合 &#xff1f;5. ArrayList和Vector区别 &#xff1f;6. ArrayList…

ES语法以及ajax相关操作

ajax ajax一个前后台配合的技术&#xff0c;它可以让javascript发送http请求&#xff0c;与后台通信&#xff0c;获取数据和信息。ajax技术的原理是实例化xmlhttp对象&#xff0c;使用此对象与后台通信。jquery将它封装成了一个函数$.ajax()&#xff0c;我们可以直接用这个函数…

pyspark 检测任务输出目录是否空,避免读取报错

前言 在跑调度任务时候&#xff0c;有时候子任务需要依赖前置任务的输出&#xff0c;但类似读取 Parquet 或者 Orc 文件时&#xff0c;如果不判断目录是否为空&#xff0c;在输出为空时会报错&#xff0c;所以需要 check 一下&#xff0c;此外Hadoop通常在写入数据时会在目录中…

源码编译postgresql

没什么好研究的了&#xff0c;就试试编译Postgresql源码&#xff0c;按照网站查的资料一步步测试的&#xff0c;方便后期定制数据库时候用&#xff0c;也算是开源的大优势了&#xff0c;只要你愿意折腾&#xff0c;可以自己定制或改进一个数据库来满足特殊业务。后面研究一下他…

K8S-CNI

CNI的设计思想即为:Kubernetes在启动Pod的pause容器之后&#xff0c;直接调用CNI网络插件&#xff0c;从而实现为Pod内部应用容器月在的Network Namespace配置符合预期的网络信息。 这里面需要特别关注两个方面:Container必须有自己的网络命名空间的环境&#xff0c;也就是end…

【RabbitMQ】常用消息模型详解

文章目录 AMQP协议的回顾RabbitMQ支持的消息模型第一种模型(直连)开发生产者开发消费者生产者、消费者开发优化API参数细节 第二种模型(work quene)开发生产者开发消费者消息自动确认机制 第三种模型(fanout)开发生产者开发消费者 第四种模型(Routing)开发生产者开发消费者 第五…