Mark's blog 这是 Mark 的个人博客,记录些东西。

宝塔BT7.9.2(含)以下版本RCE安全漏洞及其修复

漏洞原因

宝塔日志处理函数未过滤非法字符串导致的 RCE 安全漏洞(XSS)

影响范围

1、网站日志 (影响最大) 2、Nginx错误日志 3、面板运行日志

解决方法1

升级到宝塔BT最新版(7.9.3及其以上)

解决方法2

不点击上述功能

解决方法3

修改文件,增加过滤即可。我是小于7.9.3以下版本。 1、网站日志(/www/server/panel/class/panelSite.py),大概在4922多行吧,搜索GetSiteLogs,把GetSiteLogs和get_site_errlog用以下替换掉

    # xss 防御
    def xsssec(self,text):
        replace_list = {
            "<":"<",
            ">":">",
            "'":"'",
            '"':""",
        }
        for k,v in replace_list.items():
            text = text.replace(k,v)
        return public.xssencode2(text)    

    #取网站日志
    def GetSiteLogs(self,get):
        serverType = public.get_webserver()
        if serverType == "nginx":
            logPath = '/www/wwwlogs/' + get.siteName + '.log'
        elif serverType == 'apache':
            logPath = '/www/wwwlogs/' + get.siteName + '-access_log'
        else:
            logPath = '/www/wwwlogs/' + get.siteName + '_ols.access_log'
        if not os.path.exists(logPath): return public.returnMsg(False,'日志为空')
        return public.returnMsg(True,self.xsssec(public.GetNumLines(logPath,1000)))

    #取网站错误日志
    def get_site_errlog(self,get):
        serverType = public.get_webserver()
        if serverType == "nginx":
            logPath = '/www/wwwlogs/' + get.siteName + '.error.log'
        elif serverType == 'apache':
            logPath = '/www/wwwlogs/' + get.siteName + '-error_log'
        else:
            logPath = '/www/wwwlogs/' + get.siteName + '_ols.error_log'
        if not os.path.exists(logPath): return public.returnMsg(False,'日志为空')
        return public.returnMsg(True,self.xsssec(public.GetNumLines(logPath,1000)))

2、Nginx错误日志(/www/server/panel/class/ajax.py),大概在1135多行吧,搜索GetOpeLogs,把GetOpeLogs用以下替换掉

    #取指定日志
    def GetOpeLogs(self,get):
        if not os.path.exists(get.path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
        return public.returnMsg(True,public.xsssec(public.GetNumLines(get.path,1000)))

3、面板运行日志(/www/server/panel/class/config.py),大概在1480多行吧,搜索get_panel_error_logs,把get_panel_error_logs用以下替换掉

    # xss 防御
    def xsssec(self,text):
        return text.replace('<', '<').replace('>', '>')
    #取面板运行日志
    def get_panel_error_logs(self,get):
        filename = 'logs/error.log'
        if not os.path.exists(filename): return public.returnMsg(False,'没有找到运行日志')
        result = public.GetNumLines(filename,2000)
        return public.returnMsg(True,self.xsssec(result))
By Mark On