PHP代码审计--Challenge7

题目代码

<?php
$output = "";
if (isset($_GET['code'])) {
  $content = file_get_contents(__FILE__);
  $content = preg_replace('/FLAG\-[0-9a-zA-Z_?!.,]+/i', 'FLAG-XXXXXXXXXXXXXXXXXXXXXXX', $content);
  echo '<div class="code-highlight">';
  highlight_string($content);
  echo '</div>';
}
if (isset($_GET['pass'])) {
  if(!preg_match('/^[^\W_]+$/', $_GET['pass'])) {  //限制输入只能是字母或数字
    $output = "Don't hack me please :(";
  } else {
    $pass = md5("admin1674227342");
    //输入不能与MD5哈希相同但是必须相等(在发生类型混合后)  ==只比较数值,!==既比较数值又比较类型
    if ((((((((($_GET['pass'] == $pass)))) && (((($pass !== $_GET['pass']))))) || ((((($pass == $_GET['pass'])))) && ((($_GET['pass'] !== $pass)))))))) {  
     
     if (strlen($pass) == strlen($_GET['pass'])) {  //输入值必须等于MD5哈希的大小-32个字符(128位)
        $output = "<div class='alert alert-success'>FLAG-XXXXXXXXXXXXXXXXXXXXXXX</div>";
      } else {
        $output = "<div class='alert alert-danger'>Wrong password</div>";
      }
    } else {
      $output = "<div class='alert alert-danger'>Wrong password</div>";
    }
  }
}
?>

本题正常运行是要在一定的环境中,在这里我找到了这个题目的出处:ringzer0team挑战web254-PHP Fairy
在本地复现失败的师傅可以找到在题目出处练习一下这个题目。

首先,我们看到的题目页面页面应该是这样的

题目分析:
这个题目的要求就是输入一串字符串作为密码,然后内部代码会检查这个密码是否合乎限制。

  1. 要求输入的字符串仅包含字母和数字字符
  2. 在输入和生成的MD5哈希之间进行几次比较。也就是说,输入不能与pass的MD5哈希相同,但是必须相等。
  3. 输入值必须等于哈希的大小,md5(“admin1674227342”)等于
    0e463854177790028825434984462555(32个字符,128位)

本题考查的知识点:

  1. 如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。
    该字符串的开始部分决定了它的值。如果该字符串以合法的数值开始,则使用该数值。否则其值为 0(零)。合法数值由可选的正负号,后面跟着一个或多个数字(可能有小数点),再跟着可选的指数部分。指数部分由 ‘e’ 或 ‘E’ 后面跟着一个或多个数字构成。

  2. ==只比较数值,!=====既比较数值又比较类型
    详细解释为:
    如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行(也就是第一条所说的)。此规则也适用于 switch 语句。当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。

    解决问题
    构造一个符合上文题目分析出来的字符串
    0e509367213418206700842008763514

0e509367213418206700842008763514与0e463854177790028825434984462555进行==比较时,都是0,0等于0。显然,0e509367213418206700842008763514与0e463854177790028825434984462555并不相同。0e509367213418206700842008763514满足32个字符。

也就是说,只需构造一个以0e开头的只含有数字和字母的总数为32个字符的字符串即可。

发布了65 篇原创文章 · 获赞 58 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/CliffordR/article/details/104276934