[jenkins]CVE-2019-10352

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/caiqiiqi/article/details/96431428

昨天Jenkins发布了安全公告,修复了几个漏洞,其中有一个 CVE-2019-10352,绕过了文件名的的限制,导致任意文件写入。但是需要Job/Configure权限(没啥用)。说是问题出在file parameter definition的地方。

Users with Job/Configure permission could specify a relative path escaping the base directory in the file name portion of a file parameter definition. This path would be used to store the uploaded file on the Jenkins master, resulting in an arbitrary file write vulnerability.

而且说是bypass了之前对前面的一个漏洞CVE-2018-1000406

但是我不知道这个file parameter是什么,于是google搜了一下"jenkins file parameter",找到这个youtube教程
在这里插入图片描述
中文的形式是这样的:
参数化构建过程=》Add Parameter=》文件参数
在这里插入图片描述
(这次我才明白了原来jenkins隐藏着那么多参数,需要你在对应的选项上打勾,才能显示出更多。)
这个功能的说明可以参考这个
https://wiki.jenkins.io/display/JENKINS/Parameterized+Build

File parameter allows a build to accept a file, to be submitted by the user when scheduling a new build. The file will be placed inside the workspace at the known location after the check-out/update is done, so that your build scripts can use this file.

即发起构建(build)操作的时候,将这个文件名作为参数传进去。在check-out/update步骤之后,这个文件随后会被放到公共空间的一个已知的位置,这样构建脚本就可以使用这个文件了。

这样添加了文件参数之后,果然到了断点了
在这里插入图片描述

刚才只是指定了文件名,我开始以为是被上传的文件。原来是上传后放在这个路径下。
打开刚才配置的那个job里,选择Build with Parameters
在这里插入图片描述
原来选择上传文件在这个地方
POC大概长这样
在这里插入图片描述
然而并没有成功
在这里插入图片描述
还是太Naive,
看这个文件:
https://github.com/jenkinsci/jenkins/blob/dedde6195362b4aeae75f8a147cdf263b2f9854b/test/src/test/java/hudson/model/FileParameterValueTest.java
这个文件里既有对新补丁SECURITY-1424的修复验证,

    @Test
    @Issue("SECURITY-1424")
    public void fileParameter_cannotCreateFile_outsideOfBuildFolder_SEC1424() throws Exception {
        // you can test the behavior before the correction by setting FileParameterValue.ALLOW_FOLDER_TRAVERSAL_OUTSIDE_WORKSPACE to true

        FilePath root = j.jenkins.getRootPath();

        FreeStyleProject p = j.createFreeStyleProject();
        p.addProperty(new ParametersDefinitionProperty(Collections.singletonList(
                new FileParameterDefinition("dir/../../../pwned", null)
        )));

        assertThat(root.child("pwned").exists(), equalTo(false));

        String uploadedContent = "test-content";
        File uploadedFile = tmp.newFile();
        FileUtils.write(uploadedFile, uploadedContent);

        FreeStyleBuild build = p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
                new FileParameterValue("dir/../../../pwned", uploadedFile, "uploaded-file.txt")
        )).get();

        assertThat(build.getResult(), equalTo(Result.FAILURE));
        assertThat(root.child("pwned").exists(), equalTo(false));

        // ensure also the file is not reachable by request
        JenkinsRule.WebClient wc = j.createWebClient();
        wc.getOptions().setThrowExceptionOnFailingStatusCode(false);
    }

还有对SECURITY-1074,即CVE-2018-1000406对补丁修复之后的验证

    @Test
    @Issue("SECURITY-1074")
    public void fileParameter_cannotCreateFile_outsideOfBuildFolder() throws Exception {
        // you can test the behavior before the correction by setting FileParameterValue.ALLOW_FOLDER_TRAVERSAL_OUTSIDE_WORKSPACE to true
        
        FilePath root = j.jenkins.getRootPath();
        
        FreeStyleProject p = j.createFreeStyleProject();
        p.addProperty(new ParametersDefinitionProperty(Collections.singletonList(
                new FileParameterDefinition("../../../../../root-level.txt", null)
        )));
        
        assertThat(root.child("root-level.txt").exists(), equalTo(false));
        
        String uploadedContent = "test-content";
        File uploadedFile = tmp.newFile();
        FileUtils.write(uploadedFile, uploadedContent);
        
        FreeStyleBuild build = p.scheduleBuild2(0, new Cause.UserIdCause(), new ParametersAction(
                new FileParameterValue("../../../../../root-level.txt", uploadedFile, "uploaded-file.txt")
        )).get();
    
        assertThat(build.getResult(), equalTo(Result.FAILURE));
        assertThat(root.child("root-level.txt").exists(), equalTo(false));
    
        // ensure also the file is not reachable by request
        JenkinsRule.WebClient wc = j.createWebClient();
        wc.getOptions().setThrowExceptionOnFailingStatusCode(false);
    
        checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/..%2F..%2F..%2F..%2F..%2Froot-level.txt/uploaded-file.txt", uploadedContent);
        // encoding dots
        checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Froot-level.txt/uploaded-file.txt", uploadedContent);
        // 16-bit encoding
        checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/%u002e%u002e%u2215%u002e%u002e%u2215%u002e%u002e%u2215%u002e%u002e%u2215%u002e%u002e%u2215root-level.txt/uploaded-file.txt", uploadedContent);
        // double encoding
        checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252froot-level.txt/uploaded-file.txt", uploadedContent);
        // overlong utf-8 encoding
        checkUrlNot200AndNotContains(wc, build.getUrl() + "parameters/parameter/%c0%2e%c0%2e%c0%af%c0%2e%c0%2e%c0%af%c0%2e%c0%2e%c0%af%c0%2e%c0%2e%c0%af%c0%2e%c0%2e%c0%afroot-level.txt/uploaded-file.txt", uploadedContent);
    }

放到Burp Comparer里对比一下
在这里插入图片描述
主要就是从之前的Naive的payload:

../../../../../root-level.txt

改成了这样的payload

dir/../../../pwned
展开阅读全文

没有更多推荐了,返回首页