NSS [鹤城杯 2021]EasyP

NSS 鹤城杯 2021EasyP

直接给了源码

php 复制代码
<?php
include 'utils.php';

if (isset($_POST['guess'])) {
    $guess = (string) $_POST['guess'];
    if ($guess === $secret) {
        $message = 'Congratulations! The flag is: ' . $flag;
    } else {
        $message = 'Wrong. Try Again';
    }
}

if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {
    exit("hacker :)");
}

if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
    exit("hacker :)");
}

if (isset($_GET['show_source'])) {
    highlight_file(basename($_SERVER['PHP_SELF']));
    exit();
}else{
    show_source(__FILE__);
}
?> 

代码解析如下

复制代码
1. `include 'utils.php';` 这行代码用于包含名为 "utils.php" 的外部文件。通过包含该文件,可以访问其中定义的变量和函数。

2. `if (isset($_POST['guess'])) { ... }` 这个条件判断语句检查是否存在名为 "guess" 的 POST 参数。它用于判断用户是否提交了一个名为 "guess" 的表单字段。

3. `$guess = (string) $_POST['guess'];` 这行代码将用户提交的 "guess" 表单字段的值转换为字符串,并将其赋值给变量 `$guess`。

4. `if ($guess === $secret) { ... } else { ... }` 这个条件判断语句用于比较用户提交的猜测值 `$guess` 是否与变量 `$secret` 的值相等。
   - 如果两者相等,将会设置 `$message` 变量的值为 "Congratulations! The flag is: " 加上 `$flag` 的值,表示猜测正确。
   - 如果两者不相等,将会设置 `$message` 变量的值为 "Wrong. Try Again",表示猜测错误。
 
5. `if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) { ... }` 这个条件判断语句用于检查请求的 PHP 文件名是否以 "utils.php" 结尾。如果是的话,会输出 "hacker :)" 并终止程序的执行,以防止直接访问该文件。

6. `if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){ ... }` 这个条件判断语句用于检查请求的 URL 是否包含 "show_source"。如果是的话,会输出 "hacker :)" 并终止程序的执行,以防止直接访问源代码。

7. `if (isset($_GET['show_source'])) { ... } else { ... }` 这个条件判断语句用于检查是否存在名为 "show_source" 的 GET 参数。如果存在,会使用 `highlight_file()` 函数显示show_source变量的源代码,并终止程序的执行。如果不存在,会使用 `show_source()` 函数显示当前 PHP 文件的源代码。

这段代码的作用是:根据用户提交的猜测值判断是否正确,并根据判断结果显示不同的消息。同时,对访问的文件和请求进行一些安全检查,以防止直接访问敏感文件或源代码。如果请求不符合预期的条件,会输出 "hacker :)" 并终止程序的执行。

这个题目出现了$_SERVER'PHP_SELF'

这个是你调用的脚本的路径,意思就是读取文件夹下的一个文件

如果你访问的是

复制代码
如下即为执行脚本的文件:

www.errorr0.com/errorr1/errorr2/        ------>     /errorr1/errorr2/index.php

www.errorr0.com/errorr1/errorr2/index.php   -------->   /errorr1/errorr2/index.php

www.errorr0.com/errorr1/errorr2/flag.php    --------->  /errorr1/errorr2/flag.php

www.errorr0.com/errorr1/errorr2/index.php?key=value    -------->  index.php

而$_SEVER'REQUEST_URL'

它的值这个时候和$_SERVER'PHP_SELF'的值是一样的。

区别在于,如果你用get传参的时候 S E V E R ′ R E Q U E S T U R L ′ 是会加上那个参数的,而 _SEVER'REQUEST_URL'是会加上那个参数的,而 SEVER′REQUESTURL′是会加上那个参数的,而 _SERVER'PHP_SELF'不会。

复制代码
www.errorr0.com/errorr1/errorr2/flag.php    --------->  /errorr1/errorr2/flag.php

www.errorr0.com/errorr1/errorr2/index.php?key=value    -------->  index.php?key=value

basename函数返回路径中的文件名字。

如果你访问的是

http://1.14.71.254:28189/index.php/utils.php

那么它的值就会是utils.php

basename函数遇到非ascii字符时会将其舍弃

思路

代码分析前四点都没有用,主要看这一段:

PHP 复制代码
if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {
    exit("hacker :)");
}

if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
    exit("hacker :)");
}

if (isset($_GET['show_source'])) {
    highlight_file(basename($_SERVER['PHP_SELF']));
    exit();
}else{
    show_source(__FILE__);
}
复制代码
if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
    exit("hacker :)");
}

这个正则的绕过方法就是利用特性来绕过,可以用

 [ (空格) + .

这些都可以被处理成_

复制代码
if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {
    exit("hacker :)");
}

这个正则是匹配末尾有没有/utils.php/+任意字符

绕过办法很简单

因为后面要调用basename,所以可以利用中文来绕过,中文不属于ascii编码中的。

payload:靶机网址+/index.php/utils.php/给我弗莱格?show.source=1可以放vps上试试

相关推荐
辛迪聊物业数字化13 小时前
智慧物业管理平台架构实践:从SaaS物业云到商管系统的全模块落地
大数据·微服务·php
蒲公英eric17 小时前
DVWA通关全记录:从漏洞复现到安全防御——总结篇
web安全·ai·dvwa·ai安全
右耳朵猫AI17 小时前
PHP周刊2026W38 | Laravel AI可观测、Symfony三版本、Webhook零信任、事件溯源架构
后端·php·laravel
专业程序开发源18 小时前
springboot篮球联赛管理系统13635-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
子非鱼a18 小时前
【WEB】cat flag
php
4SAPI19 小时前
大模型 API 聚合平台选型指南:企业与个人用户的接入架构、稳定性与成本评估
人工智能·php·agent
PHP实战开发录19 小时前
PHP Session为什么会拖慢并发请求
系统架构·php·开发
Koi慢热1 天前
DayDayMap学术社区体验:卫星网络测绘专题用下来怎么样
网络·人工智能·windows·web安全·网络安全
闲云野鹤在人间2 天前
docker 入门 | 第5章 网络详解
网络·docker·架构·华为云·php
PHP实战开发录2 天前
MySQL连接数为什么会打满
系统架构·php·开发