use of com.jsql.model.accessible.CallableFile in project jsql-injection by ron190.
the class ManagerFile method readFile.
/**
* Attempt to read files in parallel by their path from the website using injection.
* Reading file needs a FILE right on the server.
* The user can interrupt the process at any time.
* @param pathsFiles List of file paths to read
* @throws JSqlException when an error occurs during injection
* @throws InterruptedException if the current thread was interrupted while waiting
* @throws ExecutionException if the computation threw an exception
*/
public void readFile(List<ItemList> pathsFiles) throws JSqlException, InterruptedException, ExecutionException {
if (!MediatorHelper.model().getResourceAccess().isReadingAllowed()) {
return;
}
var countFileFound = 0;
ExecutorService taskExecutor = Executors.newFixedThreadPool(10, new ThreadFactoryCallable("CallableReadFile"));
CompletionService<CallableFile> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
for (ItemList pathFile : pathsFiles) {
var callableFile = new CallableFile(pathFile.toString(), MediatorHelper.model());
taskCompletionService.submit(callableFile);
MediatorHelper.model().getResourceAccess().getCallablesReadFile().add(callableFile);
}
List<String> duplicate = new ArrayList<>();
int submittedTasks = pathsFiles.size();
int tasksHandled;
for (tasksHandled = 0; tasksHandled < submittedTasks && !MediatorHelper.model().getResourceAccess().isSearchFileStopped(); tasksHandled++) {
var currentCallable = taskCompletionService.take().get();
if (StringUtils.isNotEmpty(currentCallable.getSourceFile())) {
var name = currentCallable.getPathFile().substring(currentCallable.getPathFile().lastIndexOf('/') + 1, currentCallable.getPathFile().length());
String content = currentCallable.getSourceFile();
String path = currentCallable.getPathFile();
var request = new Request();
request.setMessage(Interaction.CREATE_FILE_TAB);
request.setParameters(name, content, path);
MediatorHelper.model().sendToViews(request);
if (!duplicate.contains(path.replace(name, StringUtils.EMPTY))) {
LOGGER.log(LogLevel.CONSOLE_INFORM, "Shell might be possible in folder {}", () -> path.replace(name, StringUtils.EMPTY));
}
duplicate.add(path.replace(name, StringUtils.EMPTY));
countFileFound++;
}
}
// Force ongoing suspendables to stop immediately
for (CallableFile callableReadFile : MediatorHelper.model().getResourceAccess().getCallablesReadFile()) {
callableReadFile.getSuspendableReadFile().stop();
}
MediatorHelper.model().getResourceAccess().getCallablesReadFile().clear();
taskExecutor.shutdown();
taskExecutor.awaitTermination(5, TimeUnit.SECONDS);
MediatorHelper.model().getResourceAccess().setSearchFileStopped(false);
var result = String.format("Found %s file%s%s on %s files checked", countFileFound, countFileFound > 1 ? 's' : StringUtils.EMPTY, tasksHandled != submittedTasks ? " of " + tasksHandled + " processed " : StringUtils.EMPTY, submittedTasks);
if (countFileFound > 0) {
LOGGER.log(LogLevel.CONSOLE_SUCCESS, result);
} else {
LOGGER.log(LogLevel.CONSOLE_ERROR, result);
}
var request = new Request();
request.setMessage(Interaction.END_FILE_SEARCH);
MediatorHelper.model().sendToViews(request);
}
Aggregations