2020-Zer0pts-Web-Can you guess it?

复现环境

https://buuoj.cn/challenges#[Zer0pts2020]Can%20you%20guess%20it?

考察知识点

  • 代码审计
  • PHP_SELF与basename变量特性了解
  • 正则表达式绕过

解题分析

让猜一个什么东西,直接点击Source查看源码。

<?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.';
  }
}
?>

guess 部分是随机一个64比特的随机字节,hash_equals()来比较字符串,等效于使用===,那么爆破密码和弱类型这两种就可以不用考虑了。

source 部分是使当前运行的脚本代码高亮,相当于读取源代码。

$_SERVER['PHP_SELF']返回的是当前正在执行的脚本的名字

'PHP_SELF'

当前执行脚本的文件名,与 document root 有关。例如,在地址为 http://example.com/foo/bar.php 的脚本中使用 $_SERVER['PHP_SELF'] 将得到 /foo/bar.php。FILE 常量包含当前(例如包含)文件的完整路径和文件名。 从 PHP 4.3.0 版本开始,如果 PHP 以命令行模式运行,这个变量将包含脚本名。之前的版本该变量不可用。

basename则可以返回路径中的文件名部分,就算后面跟上多余的字符也会返回文件名部分。
如果传入/index.php/config.php/,则$_SERVER['PHP_SELF']返回/index.php/config.php/basename($_SERVER['PHP_SELF'])返回config.php

/index.php/config.php/运行的是index.php,但是basename()获取到的是config.php

正常我们可以/index.php/config.php?source读取,但是因为存在正则/config\.php\/*$/i来限制URL结尾出现config.php字符串。

burp

ASCII值范围为0-255,但ASCII码并没有规定编号为128~255的字符,ASCII表范围为0-127,也就是我们传入128以上的数值,即可绕过正则,128 -> 0x80

payload:/index.php/config.php/%80?source

参考

https://www.yuque.com/jxswcy/buuoj-wp/iiq1im

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容