前言
说恶补pop就要恶补pop,基础知识已经基本全部过了一遍了,接下来主要就是练题了。
[SWPUCTF 2021 新生赛]pop
入门pop题,查看源码:
1 | <?php |
链子的构建还是很明显的,主要是出入口都太明确了,直接构造exp:
1 | <?php |
[CISCN2019 华北赛区 Day1 Web1]Dropbox
质量很高的一题,同时结合了phar反序列化的考点。首先进入网页,发现要登录,那么注册登录。
登陆后发现存在文件上传,但是发现对后缀进行白名单,因此upload漏洞被堵了,接着发现上传后可以进行文件下载,并且对filename没有进行限制及编码,猜测存在任意文件下载、,接下来我们开始下载文件:
index.php
1 | <?php |
class.php:
1 | <?php |
delete.php:
1 | <?php |
其他代码没有实际作用再次不放出了。class.php发现和数据库交互的语句全部进行了参数绑定,因此不存在sql。
首先看出口,File类的close()中存在file_get_contents,拿来做出口在适合不过。接着发现User类中的__destruct()调用了close(),很有可能要通过这里进行打印。而FileList类中有__call()可以进行调用,那么我们就将$this->db复制为FileList类这样我们就可以直接使用该类中得方法。
而这个__call()几乎明示我们这里要用到phar反序列化了,因此构建exp:
1 | <?php |
将生成的phar文件后缀改成jpg,然后上传,最后利用phar://伪协议删除文件触发反序列化,读取flag。
[SWPUCTF 2018]SimplePHP
和上一题比较类似,首先是任意文件读取漏洞获取源码,我们读取关键代码。
class.php:
1 | <?php |
这次多了几个waf,不过我们依然要先定位出入口。出口很好定位,Test类的file_get(),存在base64_encode(file_get_contents($value)),可以读取文件。那么为了触发这个函数,我们定位到同类下的__get(),利用其到get()来触发。
那么我们发现Show类的__toString()中可以把$content的内容返回对象,而若$show->str[‘str’]为test类的一个实例化对象,则因test类里面没有source属性,从而触发__get()方法。
最后定位到Cle4r类,__destruct()方法可以把$test也就是$str给输出出来。将$str声明为$show对象可以触发show类中的__toString()方法。
链条构造完成,编写exp:
1 | <?php |
上传后在/upload目录下获取文件名,最后在查看文件的目录下用phar://伪协议读取flag。
[第五空间 2021]pklovecloud
审计源码:
1 | <?php |
前面两题做的真的头大,返回来看题简单的。首先pkshow类一看就没用,因此这个pop只用到了两个类。出口显然是ace类的echo_name(),为了触发这个函数,我们发现acp类中的__toString()调用了这个函数,因此我们要想办法调用。acp实例化时会自动调用__construct(),所以要想触发__toString()就要使$this->cinder=对象,正好与上述分析所需的 $this->cinder = new ace() 相呼应。
因此链条梳理完成,但是我们要注意到在echo_name()中有这样几行:
1 | $this->openstack = unserialize($this->docker); |
这里有个非预期,直接空等于空就可以绕过了,exp:
1 | <?php |
那么预期解是怎样的呢,官方wp中将原来为空的docker的值改为O:8:"stdClass":2:{s:7:"neutron";s:1:"a";s:4:"nova";R:2;}
即可。
这个反序列化,尤其是这个R真把我搞迷糊了,这个的原理可以参考下面这篇文章,做出了一定的解释:
2021第五空间CTF pklovecloud
不过经过测试发现,其实直接令neutron和nova的值相等就可以了,好像是由于$cinder变量的属性是protected,导致其实$this->openstack->neutron = $heat;
这句话可以被覆盖,具体原理可能得等之后再探究了。