中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Apache Kylin遠程命令執行漏洞CVE-2020-13925報告是怎樣的

發布時間:2021-12-27 18:46:37 來源:億速云 閱讀:160 作者:柒染 欄目:安全技術

這篇文章給大家介紹Apache Kylin遠程命令執行漏洞CVE-2020-13925報告是怎樣的,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

概要

2020年6月,京東安全的藍軍團隊發現了一個 apache kylin 遠程命令執行嚴重漏洞( CVE-2020-13925)。黑客可以利用這個漏洞,登錄任何管理員賬號和密碼默認未修改的賬號,獲得管理員權限。由于Apache Kylin被廣泛應用于企業的大數據分析平臺,因此該漏洞將對企業核心數據具有較大的危害,存在數據泄露風險,建議用戶盡快升級軟件至安全版本。

Apache Kylin遠程命令執行漏洞CVE-2020-13925報告是怎樣的

關于 Apache Kylin

Apache Kylin 最早由 eBay 于 2013 創建并且開源,2015 年成為 Apache 基金會的頂級項目。他是目前大數據領域應用非常廣泛的開源分布式的分析型數據倉庫,能夠提供提供Hadoop/Spark 之上的 SQL 查詢接口及多維分析(OLAP)能力。近年來,大數據行業方興未艾,Apache Kylin被國內外的很多大型互聯網企業廣泛應用,被業界稱為大數據分析界的“神獸”。

主頁:https://kylin.apache.org/

源碼:https://github.com/apache/kylin

《Apache Kylin權威指南(第2版)》: https://book.douban.com/subject/34804888/

漏洞概述

Kylin 系統提供了一個前后端分離的 WEB UI,用戶可以在上面管理項目、創建模型、分析數據等。

系統提供了一組系統診斷接口,用于在發生故障時獲取項目、任務、操作系統的診斷信息,方便調試。

漏洞在于其中兩個接口沒有對輸入參數做安全檢查,并且在后續使用過程中拼接到了一個字符串中作為系統命令執行。黑客可以通過構造惡意參數值調用該接口,實現遠程執行任意系統命令,獲得運行 Apache Kylin 系統的操作系統賬號權限。

調用這個兩個漏洞接口,需要有賬號能夠登陸 WEB 系統,但因為該 WEB 系統在安裝完成后或部署 docker 容器后會有一個默認管理員賬號 admin,并且會設置固定的默認密碼 "KYLIN",如果管理員沒有特意修改,則黑客可以直接登陸并利用漏洞。也可能被通過其他方式得到賬號或Session的黑客或內鬼利用獲得更高權限。

因為 Apache Kylin 是一個大數據分析平臺,需要連接數據源,可能在一些大型企業內直接接觸核心數據,如果被黑客攻破,會造成很高的數據安全風險。

漏洞分析

我們以修復前的最后一個版本 3.0.2 為例分析代碼:

https://github.com/apache/kylin/tree/kylin-3.0.2

漏洞存在于兩個接口中:

* /kylin/api/diag/project/{project}/download * /kylin/api/diag/job/{jobId}/download

兩個接口漏洞路徑一致,我們以第一個為例,代碼:

https://github.com/apache/kylin/blob/kylin-3.0.2/server-base/src/main/java/org/apache/kylin/rest/controller/DiagnosisController.java

@RequestMapping(value = "/project/{project}/download", method = { RequestMethod.GET }, produces = {"application/json" })
@ResponseBody
public void dumpProjectDiagnosisInfo(@PathVariable String project, final HttpServletRequest request,
        final HttpServletResponse response) {
    try (AutoDeleteDirectory diagDir = new AutoDeleteDirectory("diag_project", "")) {
        String filePath = dgService.dumpProjectDiagnosisInfo(project, diagDir.getFile());
        setDownloadResponse(filePath, response);
    } catch (IOException e) {
        throw new InternalErrorException("Failed to dump project diagnosis info. " + e.getMessage(), e);
    }

}

{project} 是一個路徑參數,被映射為變量 project,沒有做任何處理直接傳入 dgService 的 dumpProjectDiagnosisInfo 方法: https://github.com/apache/kylin/blob/kylin-3.0.2/server-base/src/main/java/org/apache/kylin/rest/service/DiagnosisService.java

public String dumpProjectDiagnosisInfo(String project, File exportPath) throws IOException {
    aclEvaluate.checkProjectOperationPermission(project);
    String[] args = { project, exportPath.getAbsolutePath() };
    runDiagnosisCLI(args);
    return getDiagnosisPackageName(exportPath);
}

project 參數被插入 args 數組傳入 runDiagnosisCLI,從這個方法名字可以看出是要執行命令了。 但是在這之前有一個檢查用戶是否有項目操作權限的操作 checkProjectOperationPermission:

public void checkProjectOperationPermission(String projectName) {
    ProjectInstance projectInstance = getProjectInstance(projectName);
    aclUtil.hasProjectOperationPermission(projectInstance);
}

獲取 project instance

private ProjectInstance getProjectInstance(String projectName) {
    return ProjectManager.getInstance(KylinConfig.getInstanceFromEnv()).getProject(projectName);
}

public ProjectInstance getProject(String projectName) {
    // Null check is needed for ConcurrentMap does not supporting .get(null)
    if (projectName == null)
        return null;

    try (AutoLock lock = prjMapLock.lockForRead()) {
        return projectMap.get(projectName);
    }
}

這里實際是在一個 map 中查詢,如果我們輸入 project 是 poc 或 exp,當然是不存在的,會返回 null,回到剛才的權限檢查入口 checkProjectOperationPermission,得到的 projectInstance 為 null,然后傳入 aclUtil.hasProjectOperationPermission:

@PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN +
    " or hasPermission(#project, 'ADMINISTRATION')" +
    " or hasPermission(#project, 'MANAGEMENT')" +
    " or hasPermission(#project, 'OPERATION')")
public boolean hasProjectOperationPermission(ProjectInstance project) {
    return true;
}

這個比較有意思,這里只是用 PreAuthorize 檢查了用戶身份,只要用戶是 admin,或擁有 administration/management/operation 權限,就會返回 true,可能是 project 權限功能還沒有實現,用檢查用戶身份方式暫時替代。

所以只要用戶擁有以上用戶身份或權限,即使我們輸入的 project 不存在也可以通過權限檢查。

接下來看 runDiagnosisCLI 如何執行命令

private void runDiagnosisCLI(String[] args) throws IOException {
    Message msg = MsgPicker.getMsg();

    File cwd = new File("");
    logger.debug("Current path: {}", cwd.getAbsolutePath());
    logger.debug("DiagnosisInfoCLI args: {}", Arrays.toString(args));
    File script = new File(KylinConfig.getKylinHome() + File.separator + "bin", "diag.sh");
    if (!script.exists()) {
        throw new BadRequestException(
                String.format(Locale.ROOT, msg.getDIAG_NOT_FOUND(), script.getAbsolutePath()));
    }

    String diagCmd = script.getAbsolutePath() + " " + StringUtils.join(args, " ");
    CliCommandExecutor executor = KylinConfig.getInstanceFromEnv().getCliCommandExecutor();
    Pair<Integer, String> cmdOutput = executor.execute(diagCmd);

    if (cmdOutput.getFirst() != 0) {
        throw new BadRequestException(msg.getGENERATE_DIAG_PACKAGE_FAIL());
    }
}

public Pair<Integer, String> execute(String command) throws IOException {
    return execute(command, new SoutLogger());
}

public Pair<Integer, String> execute(String command, Logger logAppender) throws IOException {
    Pair<Integer, String> r;
    if (remoteHost == null) {
        r = runNativeCommand(command, logAppender);
    } else {
        r = runRemoteCommand(command, logAppender);
    }

    if (r.getFirst() != 0)
        throw new IOException("OS command error exit with return code: " + r.getFirst() //
                + ", error message: " + r.getSecond() + "The command is: \n" + command
                + (remoteHost == null ? "" : " (remoteHost:" + remoteHost + ")") //
        );

    return r;
}

這里有一個 remoteHost,這個類提供了通過 ssh 在其他服務器執行命令的功能,但我們的場景沒有使用,進入 runNativeCommand:

private Pair<Integer, String> runNativeCommand(String command, Logger logAppender) throws IOException {
    String[] cmd = new String[3];
    String osName = System.getProperty("os.name");
    if (osName.startsWith("Windows")) {
        cmd[0] = "cmd.exe";
        cmd[1] = "/C";
    } else {
        cmd[0] = "/bin/bash";
        cmd[1] = "-c";
    }
    cmd[2] = command;

    ProcessBuilder builder = new ProcessBuilder(cmd);
    builder.redirectErrorStream(true);
    Process proc = builder.start();

    // ...
}

這里我們輸入的 project 參數最終被拼接到了字符串中,作為命令用 java.lang.ProcessBuilder 執行。

影響范圍

漏洞引入時間:

2016-04-29

影響版本:

3.0 - 2.3.2

4.0 - 2.4.1

5.0 - 2.5.2

6.0 - 2.6.4

0.0-alpha, 3.0.0-alpha2, 3.0.0-beta, 3.0.0

修復版本:

3.1.0

修復時間:

2020-06-27

修復方案

升級 Apache Kylin 系統到最新版本。

https://github.com/apache/kylin/releases

https://hub.docker.com/r/apachekylin/apache-kylin-standalone/tags

關于Apache Kylin遠程命令執行漏洞CVE-2020-13925報告是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

元阳县| 安塞县| 衡东县| 营口市| 岳阳市| 砀山县| 东海县| 耿马| 延津县| 新民市| 望谟县| 沅陵县| 黑龙江省| 莆田市| 商洛市| 哈尔滨市| 平江县| 双流县| 木里| 永福县| 庆城县| 洛隆县| 郓城县| 丰城市| 会东县| 莱阳市| 随州市| 肇东市| 鸡泽县| 木兰县| 克什克腾旗| 远安县| 江山市| 吕梁市| 东方市| 建湖县| 休宁县| 清新县| 利川市| 岳普湖县| 贵州省|