[鹤城杯 2021]EasyP

[鹤城杯 2021]EasyP

题目来源:nssctf

题目类型:web

涉及考点:正则绕过

1. 还是先做代码审计

<?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__);
}
?> 

这题出现了挺多没见过的东西,还是先介绍一下:

$_SERVER[...]:是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等信息的数组。根据中括号内传入的参数不同,返回不同的信息,下面是题目涉及的两个参数:

'PHP_SELF':返回当前执行脚本的文件名。例如:在地址为http://example.com/foo/bar.php的脚本中使用 $_SERVER['PHP_SELF'] 将得到 /foo/bar.php

'REQUEST_URI':取得当前URL的路径地址,感觉跟上面那个没啥区别

basename():返回路径中的文件名部分

接着我们看代码:

第一个if语句,当POST传入的参数$guest等于$secret时返回flag,但这里不知道$secret是啥,先不管

第二个if语句,检查当前执行脚本的文件名,从后往前若找到utils.php则过滤掉

模式分隔符后的"i"标记这是一个大小写不敏感的搜索

第三个if语句,检查当前URL的路径地址,若出现show_source则过滤掉

第四个if语句,检查show_source是否有定义

综上,我们先忽略POST传参,其次我们需要GET传入show_source,使得路径包含我们需要查看的文件,利用文件包含highlight_file使得页面回显php代码,即题目提示的utils.php

2. 构造payload

  • 先明确我们需要构造的结构:
/utils.php/?show_source=1

这里show_source随便定义即可

  • 接着一个个过滤,先考虑第二个if语句,我们在utils.php后面加一个非ascii字符即可(因为是从后往前找,遇到非ascii字符就停了):
/utils.php/哈哈?show_source=1
  • 再看第三个if语句,记住以下特性即可:

GET或POST方式传进去的变量名,会自动将空格 + . [转换为_

所以这里我们传入show[source先通过第三个if,在第四个if中GET传参的时候会转换回_

/utils.php/哈哈?show[source=1
  • 第四个if就不用管了,定义了show_source即可

但是传入上述payload没回显,看其他师傅的wp说前面得加上index.php,我也不知道为啥,总之最后payload如下:

/index.php/utils.php/哈哈?show[source=1

得到flag:

NSSCTF{0087c05c-80fd-47cb-b7c6-74c71fae9165}

第一个POST传参也确实是个坑吧,用来迷惑的

日期:2023.8.2

作者:y0Zero

posted @ 2023-08-02 23:09  y0Zero  阅读(392)  评论(0编辑  收藏  举报