[紅日安全]Web安全Day5 - 任意文件上傳實戰***

本文由紅日安全成員: MisakiKata 編寫,如有不當,還望斧正。

大家好,我們是紅日安全-Web安全***小組。此項目是關於Web安全的系列文章分享,還包含一個HTB靶場供大家練習,我們給這個項目起了一個名字叫 Web安全實戰 ,希望對想要學習Web安全的朋友們有所幫助。每一篇文章都是於基於漏洞簡介-漏洞原理-漏洞危害-測試方法(手工測試,工具測試)-靶場測試(分爲PHP靶場、JAVA靶場、Python靶場基本上三種靶場全部涵蓋)-實戰演練(主要選擇相應CMS或者是Vulnhub進行實戰演練),如果對大家有幫助請Star鼓勵我們創作更好文章。如果你願意加入我們,一起完善這個項目,歡迎通過郵件形式[email protected]聯繫我們。

1. 文件上傳漏洞

1.1 漏洞簡介

文件上傳,顧名思義就是上傳文件的功能行爲,之所以會被發展爲危害嚴重的漏洞,是程序沒有對訪客提交的數據進行檢驗或者過濾不嚴,可以直接提交修改過的數據繞過擴展名的檢驗。文件上傳漏洞是漏洞中最爲簡單猖獗的利用形式,一般只要能上傳獲取地址,可執行文件被解析就可以獲取系統WebShell。

1.2 漏洞原理

網站WEB應用都有一些文件上傳功能,比如文檔、圖片、頭像、視頻上傳,當上傳功能的實現代碼沒有嚴格校驗上傳文件的後綴和文件類型時,就可以上傳任意文件甚至是可執行文件後門。

1.3 漏洞危害

惡意文件傳遞給解釋器去執行,之後就可以在服務器上執行惡意代碼,進行數據庫執行、服務器文件管理,服務器命令執行等惡意操作。根據網站使用及可解析的程序腳本不同,可以上傳的惡意腳本可以是PHP、ASP、JSP、ASPX文件等。

2. 上傳點和繞過形式

2.1 文件上傳常見點

上傳頭像
上傳相冊
上傳附件
添加文章圖片
前臺留言資料上傳
編輯器文件上傳
......

例如如下編輯器上傳點:

20190919091742-47925c06-da7b-1.png

文件管理處文件上傳:

20190919091744-487b712a-da7b-1.png

前臺用戶發表文章處文件上傳:

20190919091745-49389e08-da7b-1.png

個人頭像處文件上傳:

20190919091746-49ea2af6-da7b-1.png

2.2 後綴繞過

PHP:
php2、php3、php5、phtml、pht(是否解析需要根據配置文件中設置類型來決定)
ASP:
asa、cer、cdx
ASPX:
ascx、ashx、asac
JSP:
jsp、jspx、jspf

2.3 繞過類型

Content-Type繞過
前端繞過
文件解析規則繞過
Windows環境特性繞過
文件名大小寫繞過
雙寫繞過
點空格繞過
文件頭繞過
條件競爭繞過
......

在以下的文章介紹中,將採取其中的幾種常見的繞過形式做演示。

3. 漏洞在系統中的差異

上傳文件漏洞在不同的系統、架構以及行爲中,利用形式也是各不相同。常用的web容器有IIS、Tomcat、Nginx、Apache等。以下主要以比較經典的解析漏洞做解釋。

3.1 IIS 5.x/6.0解析漏洞

1、當創建.asp的文件目錄的時候,在此目錄下的任意文件,服務器都解析爲asp文件。例如如下:
漏洞目錄利用形式:www.xxx.com/xx.asp/xx.jpg。
xx.jpg的內容可以爲一段合法的asp腳本文件。

2、服務器默認不解析”;“以後的內容,導致xx.asp;.jpg被解析成xx.asp
漏洞文件利用形式:www.xxx.com/xx.asp;.jpg
xx.jpg的內容可以爲一段合法的asp腳本文件。

漏洞產生的原因參考詳細文章內容:https://www.cnblogs.com/l1pe1/p/9210094.html

通過對IIS6的核心文件類型解析相關文件的逆向後,整理出下面的核心處理代碼。
//reverse code by golds7n with ida
int __thiscall Url(void *this, char *UrlStruct)
{
  void *pW3_URL_INFO; // esi@1
  int bSuccess; // eax@1
  const wchar_t *i; // eax@2
  wchar_t *wcsSlashTemp; // ebx@6
  int wcsTemp; // eax@6
  int wcs_Exten; // eax@6
  int v8; // esi@9
  int v10; // eax@11
  int v11; // ST04_4@13
  int v12; // eax@13
  int ExtenDll; // eax@19
  int Extenisa; // eax@20
  int ExtenExe; // eax@21
  int ExtenCgi; // eax@22
  int ExtenCom; // eax@23
  int ExtenMap; // eax@24
  int Entry; // [sp+Ch] [bp-148h]@6
  wchar_t *wcsMaohaoTemp; // [sp+10h] [bp-144h]@6
  unsigned int dotCount; // [sp+14h] [bp-140h]@1
  wchar_t *Str; // [sp+18h] [bp-13Ch]@3
  char *url_FileName; // [sp+1Ch] [bp-138h]@1
  char Url_FileExtenName; // [sp+20h] [bp-134h]@1
  char v25; // [sp+50h] [bp-104h]@1

 dotCount = 0;
  pW3_URL_INFO = this;
  STRU::STRU(&Url_FileExtenName, &v25, 0x100u);
  url_FileName = (char *)pW3_URL_INFO + 228;
  bSuccess = STRU::Copy((char *)pW3_URL_INFO + 228, UrlStruct);
  if ( bSuccess < 0 )
    goto SubEnd;
  for ( i = (const wchar_t *)STRU::QueryStr((char *)pW3_URL_INFO + 228); ; i = Str + 1 )
  {
    Str = _wcschr(i, '.');   ***********N1************
    if ( !Str )
      break;
    ++dotCount;
    if ( dotCount > W3_URL_INFO::sm_cMaxDots )
      break;
    bSuccess = STRU::Copy(&Url_FileExtenName, Str);
    if ( bSuccess < 0 )
      goto SubEnd;
    wcsSlashTemp = _wcschr(Str, '/'); ***********N2************
    JUMPOUT(wcsSlashTemp, 0, loc_5A63FD37);
    wcsTemp = STRU::QueryStr(&Url_FileExtenName);
    wcsMaohaoTemp = _wcschr((const wchar_t *)wcsTemp, ':');  ***********N3************
    JUMPOUT(wcsMaohaoTemp, 0, loc_5A63FD51);
    wcs_Exten = STRU::QueryStr(&Url_FileExtenName);
    __wcslwr((wchar_t *)wcs_Exten);
    if ( META_SCRIPT_MAP::FindEntry(&Url_FileExtenName, &Entry) )
    {
      *((_DWORD *)pW3_URL_INFO + 201) = Entry;
      JUMPOUT(wcsSlashTemp, 0, loc_5A63FDAD);
      STRU::Reset((char *)pW3_URL_INFO + 404);
      break;
    }
    if ( STRU::QueryCCH(&Url_FileExtenName) == 4 )
    {
      ExtenDll = STRU::QueryStr(&Url_FileExtenName);
      if ( !_wcscmp(L".dll", (const wchar_t *)ExtenDll)
        || (Extenisa = STRU::QueryStr(&Url_FileExtenName), !_wcscmp(L".isa", (const wchar_t *)Extenisa)) )
        JUMPOUT(loc_5A63FD89);
      ExtenExe = STRU::QueryStr(&Url_FileExtenName);
      if ( !_wcscmp(L".exe", (const wchar_t *)ExtenExe)
        || (ExtenCgi = STRU::QueryStr(&Url_FileExtenName), !_wcscmp(L".cgi", (const wchar_t *)ExtenCgi))
        || (ExtenCom = STRU::QueryStr(&Url_FileExtenName), !_wcscmp(L".com", (const wchar_t *)ExtenCom)) )
        JUMPOUT(loc_5A63FD89);
      ExtenMap = STRU::QueryStr(&Url_FileExtenName);
      JUMPOUT(_wcscmp(L".map", (const wchar_t *)ExtenMap), 0, loc_5A63FD7B);
    }
  }
  if ( *((_DWORD *)pW3_URL_INFO + 201)
    || (v10 = *((_DWORD *)pW3_URL_INFO + 202), v10 == 3)
    || v10 == 2
    || (v11 = *(_DWORD *)(*((_DWORD *)pW3_URL_INFO + 204) + 0xC4C),
        v12 = STRU::QueryStr(url_FileName),
        bSuccess = SelectMimeMappingForFileExt(v12, v11, (char *)pW3_URL_INFO + 756, (char *)pW3_URL_INFO + 1012),
        bSuccess >= 0) )
    v8 = 0;
  else
SubEnd:
    v8 = bSuccess;
  STRU::_STRU(&Url_FileExtenName);
  return v8;
}

以上有三處被標記的位置,這三處是用來檢測點號、反斜槓、分號。、

可以理解爲的檢測流程爲:

www.xxx.com/xxx.asp;xxx.jpg
N1:從頭部查找查找"."號,獲得".asp;xxxx.jpg"
N2:查找";"號,如果有則內存截斷
N3:查找"/",如果有則內存截斷

因此,.asp將最終被保存下來,IIS6只簡單地根據擴展名來識別,所以從腳本映射表中裏查找腳本與擴展名對比,並利用asp.dll來解析。導致最終的問題產生。

對於此問題,微軟並不認爲這是一個漏洞,同樣也沒推出IIS6.0解析漏洞的補丁。因此在IIS6.0的網站下,此問題仍然可以嘗試是否存在。

3.2 Nginx 解析漏洞

Nginx是一個高性能的HTTP和反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務。Nginx是由伊戈爾·賽索耶夫爲俄羅斯訪問量第二的Rambler.ru站點開發的。

在低版本Nginx中存在一個由PHP-CGI導致的文件解析漏洞。爲什麼是由於PHP-CGI的原因呢,因爲在PHP的配置文件中有一個關鍵的選項cgi.fix_pathinfo在本機中位於php.ini配置文件中,默認是開啓的,當URL中有不存在的文件時,PHP就會默認向前解析。

普遍的做法是在Nginx配置文件中通過正則匹配設置SCRIPT_FILENAME。訪問 ”www.xx.com/phpinfo.jpg/1.php” 這個URL時,$fastcgi_script_name會被設置爲“phpinfo.jpg/1.php”,然後構造成SCRIPT_FILENAME傳遞給PHP-CGI,但是PHP爲什麼會接受這樣的參數,並將phpinfo.jpg作爲PHP文件解析呢?這就要說到fix_pathinfo這個選項了。如果開啓了這個選項,那麼就會觸發在PHP中的如下邏輯:PHP會認爲SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就會將phpinfo.jpg作爲PHP文件來解析了

在默認Fast-CGI開啓狀況下上傳名字爲xx.jpg,內容爲:
<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>

然後訪問xx.jpg/.php,在這個目錄下就會生成一句話***shell.php。同樣利用phpstudy說明,上傳1.jpg格式的文件,內容爲訪問phpinfo,如下即可觸發:

20190919091747-4a918814-da7b-1.png

3.3 Apache 解析漏洞

Apache是世界使用排名第一的Web服務器軟件。它可以運行在幾乎所有廣泛使用的計算機平臺上,由於其跨平臺和安全性被廣泛使用,是最流行的Web服務器端軟件之一。它快速、可靠並且可通過簡單的API擴充,將Perl/Python等解釋器編譯到服務器中。

Apache 在1.x和2.x版本中存在解析漏洞,例如如下地址格式:

www.xxxx.com/apache.php.bbb.aaa

Apache從右至左開始判斷後綴,若aaa非可識別後綴,再判斷bbb,直到找到可識別後綴爲止,然後將該可識別後綴進解析,因此如上地址解析爲訪問apache.php文件。

那麼爲什麼會產生此問題原因,在Apache的官方網站上,有一句這麼關於“extension”的解釋:

地址:http://httpd.apache.org/docs/current/mod/directive-dict.html

extension
In general, this is the part of the filename which follows the last dot. However, Apache recognizes multiple filename extensions, so if a filename contains more than one dot, each dot-separated part of the filename following the first dot is an extension. For example, the filename file.html.en contains two extensions: .html and .en. For Apache directives, you may specify extensions with or without the leading dot. In addition, extensions are not case sensitive.

20190919091749-4b44a372-da7b-1.png

通過這個解釋可以看出來,Apache允許文件有多個後綴名,並會按照第一個點來分析文件後綴,例如file.html.en。Apache按照每個點來分割後綴名,因此此文件名爲.html、.en。由於en後綴不被識別,便繼續向前解析。

另外對於Apache解析漏洞的正確說法應該是,使用module模式與php結合的所有版本 apache存在未知擴展名解析漏洞,使用fastcgi模式與php結合的所有版本apache不存在此漏洞。而是否解析的後綴名在文件mime.types中查找是否出現。

此處使用phpstudy測試,利用dvwa的文件上傳功能,上傳1.php.wwe。結果解析如下:

20190919091750-4bf43abc-da7b-1.png

4. 測試

以下采用手工測試和工具測試兩種方法來進行文件上傳測試。

4.1 手工測試

對於文件上傳漏洞方式和舉例此處採用一個文件靶場,地址:https://github.com/c0ny1/upload-labs

以下將利用靶場其中的一部分內容來舉例說明文件上傳漏洞的產生和效果。

環境:Ubuntu 18、Windows phpStudy (採用不一樣的系統,爲了在不同系統的差異做演示)

WEB容器:Apache 2.0

語言:PHP

抓包工具:Burp Suite Pro

驗證工具:Hackbar插件

4.1.1 前端驗證

此種驗證形式在很多網站、CMS都有使用,只在前端利用JS來做效驗,採用禁用JS上傳、抓包上傳都可以繞過此處限制。此處採用抓包演示。

20190919091751-4c970b0c-da7b-1.png

點擊上傳文件,選擇已經改成“.jpg”後綴的後門文件。修改burp中的文件後綴信息。

20190919091753-4e03a93c-da7b-1.png

訪問已經上傳的文件,利用Hackbar訪問phpinfo()。可以看到後門已經得到執行。

20190919091754-4ea39028-da7b-1.png

4.1.2 .htaccess規則文件繞過

在利用.htaccess文件之前,我們先來了解一下什麼是.htaccess規則文件。.htaccess文件(或者"分佈式配置文件"),全稱是Hypertext Access(超文本入口)。提供了針對目錄改變配置的方法, 即,在一個特定的文檔目錄中放置一個包含一個或多個指令的文件, 以作用於此目錄及其所有子目錄。作爲用戶,所能使用的命令受到限制。

概述來說,.htaccess文件是Apache服務器中的一個配置文件,它負責相關目錄下的網頁配置。通過htaccess文件,可以幫我們實現:網頁301重定向、自定義404錯誤頁面、改變文件擴展名、允許/阻止特定的用戶或者目錄的訪問、禁止目錄列表、配置默認文檔等功能。

在一些啓用了.htaccess文件的網站上就可以使用此文件類型來繞過限制較全面的黑名單過濾。

先上傳一個.htaccess文件,內容爲:AddType application/x-httpd-php .aaa。如下:

20190919091756-4f8322ce-da7b-1.png

然後再上傳文件後綴爲.aaa的文件,讓其解析爲php類型文件。

20190919091757-5055f3d4-da7b-1.png

上傳成功後訪問此上傳文件,訪問如下:

20190919091758-510ae190-da7b-1.png

4.1.3 文件名後綴大小寫混合繞過

在對後綴的判斷中,如果只是對字符串進行單獨的比較來判斷是不是限制文件,可以採用後綴名大小寫繞過形式。如下形式:

20190919091759-51c2d61a-da7b-1.png

訪問上傳成功的文件:

20190919091800-5264f170-da7b-1.png

4.1.4 Windows文件流特性繞過

在討論這種特性之前,我們先來認識一下Windows文件流。流文件,即NTFS交換數據流(alternate data streams,簡稱ADS),是NTFS磁盤格式的一個特性,在NTFS文件系統下,每個文件都可以存在多個數據流,就是說除了主文件流之外還可以有許多非主文件流寄宿在主文件流中,它使用資源派生來維持與文件相關的信息。創建一個數據交換流文件的方法很簡單,命令爲“宿主文件:準備與宿主文件關聯的數據流文件”。

詳細相關介紹和內容可以查看文章:https://www.freebuf.com/column/143101.html。此處不做深入解釋。

上傳文件爲xxx.php::$DATA類型的文件。可以看到上傳的文件爲xxx.php::$data。

20190919091802-5365efde-da7b-1.png

我們訪問的時候就可以直接訪問xxx.php文件。

20190919091803-5404b4f2-da7b-1.png

4.1.5 %00截斷繞過

以上問題被繞過的根本原因是採用了一些有缺陷的黑名單限制,一般採用白名單的限制會減少相當多的繞過問題產生,但是並不意味着一定安全,在某些沒有處理嚴格的程序上,仍然可以採用截斷繞過的形式。

首先我們來看這段上傳的代碼:

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上傳失敗";
        }
    } else {
        $msg = "只允許上傳.jpg|.png|.gif類型文件!";
    }
}

可以看出代碼採用的白名單校驗,只允許上傳圖片格式,理論上這個上傳是不好繞過的。但是後面採用保存文件的時候,是路徑拼接的形式,而路徑又是從前端獲取,所以我們可以採用在路徑上截斷。如下上傳,顯示文件路徑中有個空格,這並不是真正意義上的空格,而是%00截斷後顯示成的空格。

20190919091805-54d55602-da7b-1.png

訪問上傳地址路徑:

20190919091806-55750d1e-da7b-1.png

4.1.6 文件頭檢測繞過

提到文件頭檢測,我們就先來認識一下常見文件的文件頭格式。我們先打開一個正常的JPG圖片格式文件,查看文件的文件頭十六進制。採用010Editor。

20190919091807-56133b92-da7b-1.png

右邊欄中有明顯的JFIF存儲格式字樣,文件頭前十個字節爲FF D8 FF E0 00 10 4A 46 49 46,其中開頭標紅的爲標記碼,FF D8代表SOI標記,意思是圖像文件開始值。4A 46 49 46代表字符串JFIF標記。

關於JPEG文件格式介紹可以閱讀:https://www.cnblogs.com/sddai/p/5666924.html

然後我們再打開一份PNG文件格式的圖片,同樣採用010Editor來查看其十六進制。

20190919091808-56a8943a-da7b-1.png

對於的開頭4字節爲右欄中‰PNG字樣,PNG的8字節文件署名域用來識別該文件是不是PNG文件。也就是89 50 4E 47 0D 0A 1A 0A

關於PNG文件格式可以閱讀:https://blog.csdn.net/qq_21950929/article/details/79198814

同樣打開一份GIF文件格式圖片,用010Editor來打開查看文件。

20190919091809-573ad05c-da7b-1.png

文件十六進制中可以看到,其中47 49 46 38 39 61,代表了右欄中的GIF89a,這六個字節作爲了GIF文件格式頭的開頭文件。而在其後的繞過中就採用了GIF89a這個字符串。

關於GIF文件格式可以閱讀:https://www.jianshu.com/p/df52f1511cf8

瞭解過文件格式後,我們來看這個文件格式檢測繞過形式,首先查看代碼,爲了方便演示修改了源代碼對文件格式的獲取,此處只讀取文件的前兩個字節值:

function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只讀2字節
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);    
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
    $fileType = '';    
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知,上傳失敗!";
    }else{
        $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);  //此處爲了方便演示添加了file_ext 變量
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_ext;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上傳出錯!";
        }
    }
}

然後上傳php文件,修改文件內容,添加文件頭GIF89a:

20190919091810-580a78ca-da7b-1.png

這種添加形式類似於在hex中修改添加:

20190919091811-58df35f6-da7b-1.png

然後在訪問以上傳的文件:

20190919091813-599ecb0a-da7b-1.png

4.2 利用工具進行FUZZ

很多網站對上傳進行攔截的時候採取的是黑名單校驗,當我們看到黑名單的時候就可以考慮採取修改後綴、截斷等方式嘗試繞過。

我們採用一個工具:https://github.com/c0ny1/upload-fuzz-dic-builder 來生成fuzz的字典。執行命令:

python upload-fuzz-dic-builder.py -n test -a jpg -l php -m apache --os win -o upload_file.txt

把生成的字典導入burp中,同時取消payload-encoding的選中狀態。執行後可以看到有些php文件上傳成功。然後訪問其中上傳成功的文件,查看是否執行。

20190919091814-5a526624-da7b-1.png

訪問如圖中的地址文件,可以看到上傳成功:

20190919091815-5b0ac534-da7b-1.png

5. 實戰演示

演示漏洞爲:CVE-2018-2894

漏洞環境:Linux Weblogic 12.2

漏洞下載地址:https://github.com/vulhub/vulhub/tree/master/weblogic/CVE-2018-2894

漏洞介紹:WebLogic管理端未授權的兩個頁面存在任意上傳getshell漏洞,可直接獲取權限。兩個頁面分別爲/ws_utc/begin.do,/ws_utc/config.do。

影響範圍爲:Oracle WebLogic Server,版本10.3.6.0,12.1.3.0,12.2.1.2,12.2.1.3。

下載好vulhub後,進入相應的CVE目錄,執行如下命令:

docker-compose up -d

等到docker構建結束,會在7001端口開放一個服務,如下所示:

20190919091816-5bd34c70-da7b-1.png

此處需要登陸賬號和密碼,正常情況下是嘗試弱口令進後臺上傳文件,此處方便演示,從構建日誌中查看密碼:

docker-compose logs | grep password
查看結果:
weblogic_1  |       ----> 'weblogic' admin password: oZUcqr8j
weblogic_1  | admin password  : [oZUcqr8j]
weblogic_1  | *  password assigned to an admin-level user.  For *

登陸後界面如下:

20190919091818-5cb26d42-da7b-1.png

點擊左側中的base_domain選項,再點擊下面的高級選項,從高級中啓用web測試頁,保存。

20190919091819-5d51b3a2-da7b-1.png

然後訪問http://192.168.120.132:7001/ws_utc/config.do頁面,設置Work Home Dir,可以看到其中已經填寫一個目錄,此目錄訪問需要登陸,修改爲P牛的建議路徑:

/u01/oracle/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css

原路徑爲:

/u01/oracle/user_projects/domains/base_domain/tmp/WSTestPageWorkDir

在當前頁面中選擇安全->添加,上傳webshell

20190919091820-5df362ce-da7b-1.png

然後從放回頁面中查看id項時間戳,訪問路徑/ws_utc/css/config/keystore/時間戳_文件名

20190919091821-5e93b4c2-da7b-1.png

然後執行命令whoami:

20190919091822-5f12d856-da7b-1.png

6. CMS實戰演示

6.1 PHPOK 任意文件上傳

演示漏洞爲:phpok 任意文件上傳

漏洞環境:Windows phpStudy

漏洞環境下載:https://download.phpok.com/4.8.338.zip

漏洞介紹:phpok 4.8.338版本管理後臺存在任意文件上傳漏洞,***者可利用漏洞上傳任意文件,獲取網站權限。

下載文件後,把解壓的文件放入phpstudy中的www目錄中,此處修改了版本號目錄爲phpok。然後訪問本地地址:http://localhost/phpok,會自動進入安裝頁面,填寫數據庫密碼,創建賬號後自動進入安裝頁面,安裝完成後顯示如下:

20190919091823-6006be12-da7b-1.png

使用一開始創建的賬號密碼登陸,登陸成功後在後側的選擇欄處選擇工具->附件分類管理。

20190919091825-60e9656e-da7b-1.png

點擊右側上方的創建資源分類,然後在支持的附件類型中創建php文件類型。

20190919091826-61a3c92c-da7b-1.png

選擇左側的內容管理->資訊中心->行業管理

20190919091827-62661d1a-da7b-1.png

點擊頁面中的選擇圖片->上傳附近選擇添加的附件類型->選擇php文件上傳,上傳成功後點擊上傳的圖片,選擇預覽就可以看到文件目錄的地址

20190919091829-63247576-da7b-1.png

訪問地址文件後門,可以看到執行代碼成功

20190919091830-63bfb496-da7b-1.png

漏洞修復:此問題在高版本修復,及時升級到高版本處理,目前最新版本爲5.2.116。

6.2 FCKeditor 2.4.3 文件上傳

演示漏洞爲:FCKeditor 2.4.3 文件上傳

漏洞環境:Windows phpStudy

漏洞環境下載:https://github.com/treadmillian/fckeditor.git

漏洞介紹:FCKeditor /fckeditor/editor/filemanager/upload/php/upload.php 文件上傳漏洞。

首先從GitHub下載文件,放到phpStudy的www目錄中,同時修改config.php文件,修改UserFilesPath參數爲fck目錄下的地址,可以修改爲網站根目錄下的任意目錄中,此處修改如下:

文件地址: \fckeditor\editor\filemanager\browser\default\connectors\php\config.php

20190919091831-645979dc-da7b-1.png

訪問地址:http://localhost/fckeditor/editor/filemanager/browser/default/connectors/test.html#

20190919091832-64f0f334-da7b-1.png

選擇文件上傳,由於2.4.3在文件配置已經進行了後綴的限制,默認限制爲:

array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis','sh','shtml','shtm','phtm')

對於此處漏洞我們採用空格繞過,先上傳一個JPG的圖片,抓包修改後綴,添加空格如下:

20190919091833-6590d44e-da7b-1.png

訪問上傳產生的路徑文件,路徑會顯示在頁面中:

http://localhost/fckeditor/editor/filemanager/browser/default/connectors/uploads/file/05091707156.php

20190919091833-660f6aa2-da7b-1.png

執行一句話***文件:

20190919091834-66993156-da7b-1.png

漏洞修復:由於此處使用黑名單校驗,可以根據需要的類型修改爲白名單參數。

7. 漏洞修復

關於文件上傳漏洞的產生和修改此處討論兩種文件上傳漏洞的情況和修復:

7.1 代碼未判斷文件類型或者文件類型限制不完全,一般這種是黑名單或者沒有限制,建議添加白名單限制參數數組,固定爲圖片或文本格式文件。例如如下:

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上傳失敗";
        }
    } else {
        $msg = "只允許上傳.jpg|.png|.gif類型文件!";
    }
}

7.2 如果是使用WEB中間件存在上傳,或者是CMS存在文件上傳漏洞,根據官方建議安裝補丁升級版本,或者使用官方推薦的臨時修改策略來限制問題的產生和利用。

banner.jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章