Jenkins 远程代码执行漏洞预警

2016-11-21 8,368

前言

11月11日,Jenkins 在官方安全邮件列表中通告了一个可能导致远程代码执行的漏洞,官方将该漏洞定义为 CRITICAL(严重),并强烈建议在公网部署了 Jenkins 的管理员立即禁用 CLI 选项。

11月12日,Jenkins 再次在邮件列表中确认漏洞存在,将声明会在16日发布更新以修复该漏洞。
北京时间11月17号,Jenkins 发布了新的安全更新,修复了该漏洞,并在 GitHub 上给出了漏洞 PoC

影响

  • CVE ID

CVE-2016-9299

  • 披露时间

2016-11-11

  • 影响版本

LTS Release 2.19.3 之前的所有版本

Weekly Release 2.32 之前的所有版本漏洞影响: Jenkins 官方在更新了漏洞修复补丁的同时,也在 GitHub 上添加了相关的测试代码,测试代码中包含针对此漏洞测试的 Payload,通过远程执行代码来测试该漏洞是否存在,这可能造成 Jenkins 应用被大面积攻击。强烈建议 Jenkins 管理员立即升级最新版以修复该漏洞。

  • 漏洞分析

未授权的攻击者可以将精心构造的 Java 反序列化数据传递给 Jenkins CLI,之后可以控制 Jenkins 连接到攻击者控制的 LDAP 服务器,然后 LDAP 服务器响应的 Payload 可以导致远程任意代码执行。

  • 漏洞验证

漏洞测试方法见 Jenkins 官方测试代码:


@PresetData(PresetData.DataSet.ANONYMOUS_READONLY)
@Test
@Issue("SECURITY-360")
public void ldap() throws Exception {
    // with a proper fix, this should fail with EXIT_CODE_REJECTED
    // otherwise this will fail with -1 exit code
    probe(Payload.Ldap, PayloadCaller.EXIT_CODE_REJECTED);
}
 
private void probe(Payload payload, int expectedResultCode) throws Exception {
    File file = File.createTempFile("security-218", payload + "-payload");
    File moved = new File(file.getAbsolutePath() + "-moved");
    
    // Bypassing _main because it does nothing interesting here.
    // Hardcoding CLI protocol version 1 (CliProtocol) because it is easier to sniff.
    int exitCode = new CLI(r.getURL()).execute("send-payload",
            payload.toString(), "mv " + file.getAbsolutePath() + " " + moved.getAbsolutePath());
    assertEquals("Unexpected result code.", expectedResultCode, exitCode);
    assertTrue("Payload should not invoke the move operation " + file, !moved.exists());
    file.delete();
}
    
...
 
public class Ldap extends PayloadRunner implements ObjectPayload {
    
    public Object getObject(final String command) throws Exception {
        // this is not a fully exploit, so we cannot honor the command,
        // but we want to check that we are blocking LdapAttribute
        Class c = Class.forName("com.sun.jndi.ldap.LdapAttribute");
        Constructor ctr = c.getDeclaredConstructor(String.class);
        ctr.setAccessible(true);
        return ctr.newInstance("foo");
    }
    
    public static void main(final String[] args) throws Exception {
        PayloadRunner.run(Ldap.class, args);
    }
}

参考方案

Jenkins 发布了新版 Release,可以升级到以下版本:

  • main line 2.32
  • LTS 2.19.3 参考

延伸阅读

知其一不知其二之Jenkins Hacking

易宝支付某系统命令执行(Jenkins反序列化案例)可入内网

慧聪网Jenkins系统未授权访问可执行系统命令

酷6Jenkins系统未授权访问可执行系统命令

优酷Jenkins系统未授权

官方参考

Jenkins https://jenkins.io/

邮件组 https://groups.google.com/forum/#!msg/jenkinsci-advisories/-fc-w9tNEJE/GRvEzWoJBgAJ

官方 PoC https://github.com/jenkinsci/jenkins/blob/master/test/src/test/java/jenkins/security/Security218CliTest.java

【本文转自长亭科技(ID:Chaitin_Tech)原创,原文链接

Tags:
评论  (0)
快来写下你的想法吧!

Joey

文章数:6 积分: 0

关注我们