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上试试

相关推荐
两个人的幸福10 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820713 天前
PHP 扩展——从入门到理解
php
鹏仔先生14 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下14 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
treesforest14 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
xingpanvip14 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
上海云盾第一敬业销售14 天前
深入解析WAF的工作原理与机制
web安全·ddos
憧憬成为web高手14 天前
l33t-hoster
学习·web安全·网络安全