分析调试

根据官方通告描述,漏洞出现在Jenkins CLI请求参数解析的时候,关于Jenkins CLI:Jenkins CLI ,首先在本地下载cli客户端,访问jenkins服务的http://localhost/jnlpJars/jenkins-cli.jar
支持的指令如下

客户端随便发送一个指令

java -jar jenkins-cli.jar -s http://localhost:8088 list-plugin

jenkins服务端在hudson.cli.CLIAction#doWs对客户端的websocket请求进行响应

这里的WebSockets.isSupported方法默认返回true,于是走到下边else中,这个线程里,调用了hudson.cli.CLIAction.ServerSideImpl#run

run方法里又调用了hudson.cli.CLICommand#main方法,这里会根据args[0]获取commandName,并且解析出CLICommand类型

这里获取的逻辑是,遍历所有CLICommand的接口类型,取出Command之前的name,遇到大写就用-进行分割,然后全部转为小写(WhoAmICommand对应的命令就是who-am-i)

这里调用了all方法,找到所有CLICommand.class的实现类型,这里除了Command,还有CLIRegister类型,对应的name为:

keep-build
restart
shutdown
safe-shutdown
disable-job
enable-job


然后,调用了Command的main方法,这里获取了CmdLineParser,并在后面解析args

无权限情况

CLICommand

这里需要注意,使用CLICommand,如果不是HelpCommand或者WhoAmICommand的时候,会进行身份检测,所以我们传入who-am-i就能直接进入parseArgument进行参数解析。
在parseArgument里,atSyntax默认为true,所以就会调用expandAtFiles,最终造成文件读取

于是我们传入

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

但是发现只能获取到第一行的内容

因为在expandAtFiles读取完文件内容,会将内容转为String数组,每一行就是一个元素,然后cmdLine里就是文件的内容
这里会进行遍历,调用isOption

如果没有以-开头就会返回false

进入第一个if,而argumens这个值在这里size是0,就会进入throw报错,就只会抛出第一行内容,官方通告中也有提到

Argument是一个注解,比如HelpCommand

如果换成HelpCommand,这里能读到两行


原因是当存在arguments的时候,会调用parseAruments,然后把我们传入的设置到CLICommand的COMMAND属性上,然后输出出来,所以,能读取到的行数取决于Command支持的参数[个数+1],没有权限的情况下,使用WHOAMI和HELP,最多只能读到两行


输出逻辑是在parseArgument抛出CmdLineException之后,在printUsage里打印到终端

CLIRegister

这里是hudson.cli.declarative.CLIRegisterer的main方法,这里就没有之前who-am-i和help 的限制了,所以使用register的那几个命令,也可以读取第一行,调用parseArgument的逻辑和上面一样

Overall/Read 权限

(管理员可以勾选Allow anonymous read access 来开启权限)

在寻找Command的过程中,找到了支持multiValued的Argument

OfflineNodeCommand
ConnectNodeCommand
ReloadJobCommand
OnlineNodeCommand
DeleteNodeCommand
DeleteViewCommand
DisconnectNodeCommand
DeleteJobCommand

以 hudson.cli.ConnectNodeCommand 为例

传入有read aceess权限的用户或者目标服务器开启了Allow anonymous read access,指定connect-node,能够读取到所有行的内容


来看下原因,回到org.kohsuke.args4j.CmdLineParser#parseArgument,在遍历arguments的时候,只要multiValued为true,这里的argIndex就不会增加,就不可能满足argIndex >= arguments,所以不会抛CmdLine异常

调用setter直到把文件内容处理完

接着,调用当前Command的run方法

hudson.cli.ConnectNodeCommand#run,会遍历nodes,也就是之前设置的文件内容

resolveForCLI失败就会抛出异常,并打印nodes,这里throw/catch的异常在while循环内部,不会退出循环,就会继续处理nodes,直到打印完所有异常。

点击收藏 | 0 关注 | 1 打赏
  • 动动手指,沙发就是你的了!
登录 后跟帖