当前位置: 首页 > news >正文

CTF 代码审计之绕过过滤的空白字符

题目

 <?php
header("Content-Type:text/html;charset=utf-8");
highlight_file('02kbzf.php');//引入名为 flag2.php 的文件。
include('f' . 'lag2' . '.php');//初始化变量 $info 和 $req。
$info = "";
$req = [];//读取文件 flag2.php 的内容到变量 $flag 中,使用 trim 函数去除读取结果的首尾空白字符
$flag = trim(@file_get_contents('fl' . 'a' . 'g2' . '.php'));ini_set("display_error", false);
error_reporting(0);//检查 GET 请求参数中是否存在名为 number 的字段,如果不存在,则输出一个提示信息和一个 HTTP 响应头 hint,并终止脚本的执行。
if(!isset($_GET['number'])){header("hint:" . hash("md5", "2djwioadopkwapodkpawkpdw.txt"));die("please refuel!!");
}//对键值进行过滤处理,避免sql注入
foreach([$_GET, $_POST] as $global_var) {foreach($global_var as $key => $value) {$value = trim($value);if(is_string($value)){$req[$key] = addslashes($value);}}
}//定义 is_hwhs_number 函数,用于判断一个数字是否为回文数字。
function is_hwhs_number($number) {$number = strval($number);$i = 0;$j = strlen($number) - 1;while($i < $j) {if($number[$i] !== $number[$j]) {return false;}$i++;$j--;}return true;
}//判断传入的 number 是否为数字类型/整数类型,如果是,则返回一个提示信息。
if(is_numeric($_REQUEST['number'])) {$info="抱歉您输入的是数字";
}
elseif($req['number']!=strval(intval($req['number']))) {$info = "数字必须等于其整数!!";
}
else {//将整数化后的 number 和其反转后的值进行比较,如果不相同,则返回提示信息。$value1 = intval($req["number"]);$value2 = intval(strrev($req["number"]));if($value1!=$value2=232){$info="这不是回文数字!!";}else {//判断 number 是否为回文数字,如果是,则返回一个提示信息,否则输出 flag2.php 文件的内容。if(is_hwhs_number($req["number"])){$info = "{$value1} 是一个回文数字!";}else {var_dump($flag);}}
}
?>

函数

代码中使用到的函数:

  • trim:用于删除字符串两端的空白字符(包括空格、制表符、换行符等)。
  • intval:【取整】
  • strval:将变量转换为字符串
  • strrev:用于翻转字符串,将原先的字符串首尾对调。
  • addslashes:用于对字符串进行转义,将一些特殊字符转换成它们的转义形式,从而避免 SQL 注入。例如,将单引号 ' 转义成 \',将双引号 " 转义成 \",将反斜杠 \ 转义成 \\ 等。

部分代码解释

    $value1 = intval($req["number"]);$value2 = intval(strrev($req["number"]));
  • 这两行代码分别将字符串 $req[“number”] 转成整数,分别存储在 $value1 和 $value2 变量中。

  • 其中,intval 函数将字符串转换为整数,如果 $req[“number”] 实际上不是一个数值字符串,则该函数返回 0。

  • 在第二行代码中,strrev 函数将字符串反转,即将字符串中的字符顺序翻转过来,例如,strrev(‘123’) 的输出结果为 ‘321’。然后再将反转后的字符串转成整数,存储在 $value2 变量中。

  • 这两个变量的作用是为了比较 $req[“number”] 和它的反转字符串是否相等。如果相等,则说明 $req[“number”] 是一个回文数,否则不是回文数。

思路


审计代码可以发现,number必须符合下面3个条件才可以输出flag:

  1. number不为空,且不能是一个数值型数字, 但过滤前得是数字
  2. number不能是一个回文数,过滤后是回文数。
  3. $value1!=$value2=232,限制number只能为232
  • number要为非数值,理所当然想到空格字符%20和空字符%00。注意is_numeric函数对于%20空格字符只能放在数值后,空字符%00无论是放在前后都可以判断为非数值。所以这里选%00.
  • %0C :是 URL 编码中的一种,它代表的是一个 ASCII 控制字符,即换页(Form Feed)\f 。在 PHP 中,%0C 会被解析成一个字符,会被 is_hwhs_number 函数判断为不是回文数字,从而进入 var_dump 的分支,输出 $flag 的内容。

POC

URL?number=%00%0C232

得到flag如下:


C:\phpstudy_pro\WWW\pass2\02kbzf.php:58:string '<?php$flag ="xyctf6d4w68a4dwwa64dw";?>' (length=44)

参考

  1. php代码学习(二)绕过空白过滤
  2. PHP代码审计分段讲解
  3. 绕过过滤的空白字符
http://www.lryc.cn/news/155131.html

相关文章:

  • 【Vue】 Vue3 安装说明,适合小白新手
  • 电脑提示“系统找不到指定的文件”怎么办?
  • 向openssl中添加一个最简单的算法
  • 自己公司开发的ERP系统,怎么对接京东,淘宝等这些电商平台?
  • 联想集团财报不及华尔街预期,财务业绩恐将继续恶化
  • 计网基础面试题
  • 设置Linux CentOS7桥接模式连网
  • Mysql底层数据结构为什么选择B+树
  • R语言列操作函数
  • 【Unity】VS Code 没有自动补全 MonoBehaviour 的方法
  • 计算机竞赛 基于深度学习的人脸性别年龄识别 - 图像识别 opencv
  • 大厂面试 | 百度一面,顶不住
  • c++线程
  • 【Docker】02-安装mysql
  • JAVA每日小知识(关于excel下载时插入和stream流遍历优化)
  • 阿里后端开发:抽象建模经典案例
  • 【车载以太网测试从入门到精通】——DoIP BootLoader刷写测试(含CAPL源码)
  • RK开发板的USB连接(Ubuntu)
  • Redis-Cluster集群的部署(详细步骤)
  • Vulnhub: Hogwarts: Bellatrix靶机
  • 机器学习(吴恩达第一课)
  • 固定资产管理怎么改革
  • 【js】防抖和节流的使用场景和区别:
  • Blazor前后端框架Known-V1.2.14
  • 港陆证券:五日线破位怎么看?
  • 睿趣科技:抖音小店多久可以做起来
  • onnx 模型切割掉conv后面的节点,设置输出层名称和最后节点名称一致,设置输出层shape和输出节点一致.
  • 泛型的学习
  • L1-061 新胖子公式(Python实现) 测试点全过
  • 潜艇来袭(Qt官方案例-2维动画游戏)