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

news/2024/5/20 0:06:05 标签: 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.niftyadmin.cn/n/4988278.html

相关文章

随笔 | 写在七月末的这一天

. 前言 这篇本应该是七月底写完&#xff0c;各种原因&#xff0c;在八月末才有时间完成。还是希望可以多记录呀~ . 序言 每年七月&#xff0c;通常是我最喜欢的月份。而今年的七月&#xff0c;比想象中的速度&#xff0c;流走的还要快。 如果用关键词总结&#xff1a; 恢…

PAT编程基础笔记

写在前面&#xff1a; 这篇文章是我之前刷PAT(Basic Level)随手记下来的几个记忆点&#xff0c;希望对大家有所帮助。 1.字符串和数值类型之间的转换&#xff1a; 如果要将数值类型如int、double、long转换为字符串string&#xff0c;可以使用to_string()函数 #include<s…

Caffine和Guava的refreshAfterWrite的异同

背景: guava和caffine的refreshAfterWrite方法在用于本地缓存的场景是非常常用的&#xff0c;本文通过例子列举下caffine的refreshAfterWrite方法和guava的refreshAfterWrite的相同点和不同点 相同点/不同点&#xff1a; 以下都是使用keyXYZ作为例子 场景1&#xff1a;一开…

〖程序员的自我修养 - 认知剖析篇⑤〗- 选择前端还是后端?

人之所以会觉得迷茫,本质上是欠缺对自己的一个控制力、识别庞杂信息、去伪存真的独立思考与认知能力。 说明:该文属于 程序员的自我修养 专栏,购买任意白宝书体系化专栏可加入易编程社区,早鸟价订阅模式除外。福利:加入社区的小伙伴们,除了可以获取博主所有付费专栏的阅读…

Python分享之redis(3)

3、List 操作 redis中的List在在内存中按照一个name对应一个List来存储 lpush(name,values) # 在name对应的list中添加元素&#xff0c;每个新的元素都添加到列表的最左边 r.lpush("list_name",2) r.lpush("list_name",3,4,5)#保存在列表中的顺序为5&am…

SSH远程连接macOS服务器:通过cpolar内网穿透技术实现远程访问的设置方法

文章目录 前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …

【位运算】

二进制中1的个数 #include<iostream> using namespace std;int func(int x){// return x&(-x);return x&(~x1);//补码 }int main(){int n 0;cin>>n;while(n--){int m 0;cin>>m;int res 0;while(m!0){m - func(m);res;}cout<<res<<&q…

怎么用postman连接websocket

点击右侧栏的Collections&#xff0c;然后点击旁边的New&#xff0c;然后点击其中的WebSocket Request,然后输入Url&#xff0c;点击Connection&#xff0c;这里需要注意的是Url不能加上http://&#xff0c;因为这个不是http协议。