[代碼審計]eyoucms前台未授權任意文件上傳


0x00 背景

來公司差不多一年了,然而我卻依舊沒有轉正。約莫着轉正也要到九月了,去年九月來的,實習,轉正用了一年。2333

廢話不多說了,最近有其他的事要忙,很久沒有代碼審計了。難的挖不了,淺的沒意思。那就隨便選吧。

在A5找了套源碼,找找感覺。花了十來分鍾審了一下,發現了個未授權任意文件上傳。

 

0x01 總體了解

版本: v 1.1.3

框架: tp 5.0

目錄如下:

挺標准的tp二次開發目錄,直接看application目錄下的。

外面的幾個php文件就不解釋了。粗略的看了一下配置文件和路由。

全局過濾用了strip_sql加htmlspecialchars,tp5默認是走pdo的。除非不是故意留的坑,都不太可能會出現比較容易利用的注入點。

application里面有多個模塊。主要是admin,api,common,home四個。

admin 顧名思義是后台處理的

api 是一些接口

common 是基礎類。

home 是前端

 

0x02 發現任意文件上傳的接口

看了一下common和api兩個模塊,在api里面發現了這么一個接口。

看到文件application\api\Uploadify.php

public function preview(){
        
        // 此頁面用來協助 IE6/7 預覽圖片,因為 IE 6/7 不支持 base64
        $DIR = 'preview';
        // Create target dir
        if (!file_exists($DIR)) {
            @mkdir($DIR);
        }
        
        $cleanupTargetDir = true; // Remove old files
        $maxFileAge = 5 * 3600; // Temp file age in seconds
        
        if ($cleanupTargetDir) {
            if (!is_dir($DIR) || !$dir = opendir($DIR)) {
                die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
            }
        
            while (($file = readdir($dir)) !== false) {
                $tmpfilePath = $DIR . DIRECTORY_SEPARATOR . $file;      
                // Remove temp file if it is older than the max age and is not the current file
                if (@filemtime($tmpfilePath) < getTime() - $maxFileAge) {
                    @unlink($tmpfilePath);
                }
            }
            closedir($dir);
        }
        //前面的一大串,不用關注,看下面的就行了
        $src = file_get_contents('php://input');
        if (preg_match("#^data:image/(\w+);base64,(.*)$#", $src, $matches)) {       
            $previewUrl = sprintf(
                "%s://%s%s",
                isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
                $_SERVER['HTTP_HOST'],$_SERVER['REQUEST_URI']
            );
            $previewUrl = str_replace("preview.php", "", $previewUrl);
            $base64 = $matches[2];
            $type = $matches[1];
            if ($type === 'jpeg') {
                $type = 'jpg';
            }
        
            $filename = md5($base64).".$type";
            $filePath = $DIR.DIRECTORY_SEPARATOR.$filename;
        
            if (file_exists($filePath)) {
                die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}');
            } else {
                $data = base64_decode($base64);
                file_put_contents($filePath, $data);
                die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}');
            }
        } else {
            die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "un recoginized source"}}');
        }
    }

這是一個圖片預覽的接口,通過php://input接收圖片base64編碼數據,然后解碼,寫入文件。返回圖片路徑。

正則獲取了圖片的后綴之后,簡單判斷了一下就沒有下文了。然后將獲取到的文件后綴,與base64文件數據的md5值拼接成為文件名。最后解碼數據,寫入。返回路徑

追溯一下這個api是否需要登錄?(=>等於extends)

app\api\controller\Uploadify =>app\api\controller\Base => app\common\controller\Common =>think\Controller

看了一下沒有發現有判斷權限或認證的代碼,在 app\api\controller\Base 類里面看到似乎是權限判斷的代碼:

但這里的代碼都是空的。。。

那么,整個漏洞的利用邏輯就是往http://www.example.com/index.php/api/Uploadify/preview 打一個base64的post數據包。

 

 漏洞原理很簡單。我想這里會出現這么一個問題,大概是作者認為data:image/ 這樣的數據,只能是圖片?

0x03 漏洞影響

在官網下了一個1.0版本的,對比了一下發現,1.0版本也是存在該漏洞。左1.1.3 ,右1.0

這里的差異只是我添加的一個備注。

昨晚用fofa跑了一下,發現存在該漏洞的網站有50%以上。

0x04 漏洞修復建議

使用白名單判斷文件后綴名。

在Uploadify.php中213行到214行的代碼修改為如下:

if ($type !== 'jpeg' || $type !=='png' || $type !=='gif' || $type!=='jpg') {
       exit();
}
if ($type === 'jpeg') {
        $type = 'jpg';
}

0x05 總結

搜了一下這個CMS的歷史漏洞,發現只有seebug上面的一個后台任意文件讀取漏洞。這個洞藏了很久啊。。

整個漏洞很簡單,寫篇文章記錄一下,除除博客上面的草。

之后想總結一下tp框架二次開發CMS的奇葩漏洞,不知道什么時候能總結出來。。

聲明:本文章只用於學習研究之用,禁止用於違法犯罪。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM