Search in sources :

Example 31 with Request

use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.

the class RessourceAccess method runSqlShell.

/**
 * Execute SQL request into terminal defined by URL path, eventually override with database user/pass identifiers.
 * @param command SQL request to execute
 * @param uuidShell Identifier of terminal sending the request
 * @param urlShell URL to send SQL request against
 * @param username User name [optional]
 * @param password USEr password [optional]
 */
public static void runSqlShell(String command, UUID uuidShell, String urlShell, String username, String password) {
    String result = "";
    try {
        result = runCommandShell(urlShell + "?q=" + URLEncoder.encode(command.trim(), "ISO-8859-1") + "&u=" + username + "&p=" + password);
        if (result.indexOf("<SQLr>") > -1) {
            List<List<String>> listRows = new ArrayList<>();
            Matcher rowsMatcher = Pattern.compile("(?si)<tr>(<td>.*?</td>)</tr>").matcher(result);
            while (rowsMatcher.find()) {
                String values = rowsMatcher.group(1);
                Matcher fieldsMatcher = Pattern.compile("(?si)<td>(.*?)</td>").matcher(values);
                List<String> listFields = new ArrayList<>();
                listRows.add(listFields);
                while (fieldsMatcher.find()) {
                    String field = fieldsMatcher.group(1);
                    listFields.add(field);
                }
            }
            if (!listRows.isEmpty()) {
                List<Integer> listFieldsLength = new ArrayList<>();
                for (final int[] indexLongestRowSearch = { 0 }; indexLongestRowSearch[0] < listRows.get(0).size(); indexLongestRowSearch[0]++) {
                    Collections.sort(listRows, (firstRow, secondRow) -> secondRow.get(indexLongestRowSearch[0]).length() - firstRow.get(indexLongestRowSearch[0]).length());
                    listFieldsLength.add(listRows.get(0).get(indexLongestRowSearch[0]).length());
                }
                if (!"".equals(result)) {
                    StringBuilder tableText = new StringBuilder("+");
                    for (Integer fieldLength : listFieldsLength) {
                        tableText.append("-" + StringUtils.repeat("-", fieldLength) + "-+");
                    }
                    tableText.append("\n");
                    for (List<String> listFields : listRows) {
                        tableText.append("|");
                        int cursorPosition = 0;
                        for (String field : listFields) {
                            tableText.append(" " + field + StringUtils.repeat(" ", listFieldsLength.get(cursorPosition) - field.length()) + " |");
                            cursorPosition++;
                        }
                        tableText.append("\n");
                    }
                    tableText.append("+");
                    for (Integer fieldLength : listFieldsLength) {
                        tableText.append("-" + StringUtils.repeat("-", fieldLength) + "-+");
                    }
                    tableText.append("\n");
                    result = tableText.toString();
                }
            }
        } else if (result.indexOf("<SQLm>") > -1) {
            result = result.replace("<SQLm>", "") + "\n";
        } else if (result.indexOf("<SQLe>") > -1) {
            result = result.replace("<SQLe>", "") + "\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_SQL_SHELL_RESULT);
        request.setParameters(uuidShell, result, command);
        MediatorModel.model().sendToViews(request);
    }
}
Also used : Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) Request(com.jsql.model.bean.util.Request) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ItemList(com.jsql.view.swing.list.ItemList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 32 with Request

use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.

the class HeaderUtil method checkResponseHeader.

/**
 * Verify the headers received after a request, detect authentication response and
 * send the headers to the view.
 * @param connection contains headers response
 * @param urlByUser the website to request
 * @throws IOException when an error occurs during connection
 */
@SuppressWarnings("unchecked")
public static void checkResponseHeader(HttpURLConnection connection, String urlByUser) throws IOException {
    // TODO Extract
    Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
    msgHeader.put(Header.URL, urlByUser);
    msgHeader.put(Header.RESPONSE, HeaderUtil.getHttpHeaders(connection));
    Map<String, String> mapResponse = (Map<String, String>) msgHeader.get(Header.RESPONSE);
    if (Pattern.matches("4\\d\\d", Integer.toString(connection.getResponseCode())) && mapResponse.containsKey("WWW-Authenticate") && mapResponse.get("WWW-Authenticate") != null && mapResponse.get("WWW-Authenticate").startsWith("Basic ")) {
        LOGGER.warn("Basic Authentication detected.\n" + "Please define and enable authentication information in the panel Preferences.\n" + "Or open Advanced panel, add 'Authorization: Basic b3N..3Jk' to the Header, replace b3N..3Jk with the string 'osUserName:osPassword' encoded in Base64. You can use the Coder in jSQL to encode the string.");
    } else if (Pattern.matches("4\\d\\d", Integer.toString(connection.getResponseCode())) && mapResponse.containsKey("WWW-Authenticate") && "NTLM".equals(mapResponse.get("WWW-Authenticate"))) {
        LOGGER.warn("NTLM Authentication detected.\n" + "Please define and enable authentication information in the panel Preferences.\n" + "Or add username, password and domain information to the URL, e.g. http://domain\\user:password@127.0.0.1/[..]");
    } else if (Pattern.matches("4\\d\\d", Integer.toString(connection.getResponseCode())) && mapResponse.containsKey("WWW-Authenticate") && mapResponse.get("WWW-Authenticate") != null && mapResponse.get("WWW-Authenticate").startsWith("Digest ")) {
        LOGGER.warn("Digest Authentication detected.\n" + "Please define and enable authentication information in the panel Preferences.");
    } else if (Pattern.matches("4\\d\\d", Integer.toString(connection.getResponseCode())) && mapResponse.containsKey("WWW-Authenticate") && "Negotiate".equals(mapResponse.get("WWW-Authenticate"))) {
        LOGGER.warn("Negotiate Authentication detected.\n" + "Please add username, password and domain information to the URL, e.g. http://domain\\user:password@127.0.0.1/[..]");
    } else if (Pattern.matches("1\\d\\d", Integer.toString(connection.getResponseCode()))) {
        LOGGER.trace("Found status HTTP " + connection.getResponseCode() + " Informational");
    } else if (Pattern.matches("2\\d\\d", Integer.toString(connection.getResponseCode()))) {
        LOGGER.debug("Found status HTTP " + connection.getResponseCode() + " Success");
    } else if (Pattern.matches("3\\d\\d", Integer.toString(connection.getResponseCode()))) {
        LOGGER.warn("Found status HTTP " + connection.getResponseCode() + " Redirection");
        if (!PreferencesUtil.isFollowingRedirection()) {
            LOGGER.warn("If injection fails please test again with option 'Follow HTTP redirection' enabled.");
        } else {
            LOGGER.info("Redirecting to the next page...");
        }
    } else if (Pattern.matches("4\\d\\d", Integer.toString(connection.getResponseCode()))) {
        LOGGER.warn("Found status HTTP " + connection.getResponseCode() + " Client Error");
    } else if (Pattern.matches("5\\d\\d", Integer.toString(connection.getResponseCode()))) {
        LOGGER.warn("Found status HTTP " + connection.getResponseCode() + " Server Error");
    } else {
        LOGGER.trace("Found status HTTP " + connection.getResponseCode() + " Unknown");
    }
    // Request the web page to the server
    Exception exception = null;
    StringBuilder pageSource = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
        char[] buffer = new char[4096];
        while (reader.read(buffer) > 0) {
            pageSource.append(buffer);
        }
        reader.close();
    } catch (IOException errorInputStream) {
        exception = errorInputStream;
        InputStream errorStream = connection.getErrorStream();
        if (errorStream != null) {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream))) {
                char[] buffer = new char[4096];
                while (reader.read(buffer) > 0) {
                    pageSource.append(buffer);
                }
                reader.close();
            } catch (Exception errorErrorStream) {
                exception = new IOException("Exception reading Error Stream", errorErrorStream);
            }
        }
    }
    if (PreferencesUtil.isNotTestingConnection()) {
        if (exception != null) {
            LOGGER.debug("Connection test disabled, ignoring response HTTP " + connection.getResponseCode() + "...");
        }
        exception = null;
    } else if (exception != null) {
        LOGGER.info("Please select option 'Disable connection test' and run again");
    }
    // Form parsing;
    // TODO Extract
    Elements elementsForm = Jsoup.parse(pageSource.toString()).select("form");
    StringBuilder result = new StringBuilder();
    Map<Element, List<Element>> mapForms = new HashMap<>();
    for (Element form : elementsForm) {
        mapForms.put(form, new ArrayList<>());
        result.append("\n<form action=\"");
        result.append(form.attr("action"));
        result.append("\" method=\"");
        result.append(form.attr("method"));
        result.append("\" />");
        for (Element input : form.select("input")) {
            result.append("\n    <input name=\"");
            result.append(input.attr("name"));
            result.append("\" value=\"");
            result.append(input.attr("value"));
            result.append("\" />");
            mapForms.get(form).add(input);
        }
        Collections.reverse(mapForms.get(form));
    }
    if (!elementsForm.isEmpty()) {
        if (!PreferencesUtil.isParsingForm()) {
            if (connection.getResponseCode() != 200) {
                LOGGER.trace("Found " + elementsForm.size() + " ignored <form> in HTML body:" + result);
                LOGGER.info("WAF can detect missing form parameters, you may enable 'Add <input> parameters' in Preferences and retry");
            } else {
                LOGGER.trace("Found " + elementsForm.size() + " <form> in HTML body while status 200 Success:" + result);
            }
        } else {
            LOGGER.debug("Found " + elementsForm.size() + " <form> in HTML body, adding input(s) to requests:" + result);
            for (Entry<Element, List<Element>> form : mapForms.entrySet()) {
                for (Element input : form.getValue()) {
                    if ("get".equalsIgnoreCase(form.getKey().attr("method"))) {
                        ParameterUtil.getQueryString().add(0, new SimpleEntry<String, String>(input.attr("name"), input.attr("value")));
                    } else if ("post".equalsIgnoreCase(form.getKey().attr("method"))) {
                        ParameterUtil.getRequest().add(0, new SimpleEntry<String, String>(input.attr("name"), input.attr("value")));
                    }
                }
            }
        }
    }
    // Csrf
    // TODO Extract
    Optional<SimpleEntry<String, String>> optionalTokenCsrf = Jsoup.parse(pageSource.toString()).select("input").select("[name=csrf_token], [name=csrfToken]").stream().findFirst().map(input -> new SimpleEntry<String, String>(input.attr("name"), input.attr("value")));
    if (optionalTokenCsrf.isPresent()) {
        SimpleEntry<String, String> tokenCsrfFound = optionalTokenCsrf.get();
        if (PreferencesUtil.isProcessingCsrf()) {
            LOGGER.debug("Found Csrf token " + tokenCsrfFound.getKey() + "=" + tokenCsrfFound.getValue() + " in HTML body, adding token to querystring, request and header");
            ConnectionUtil.setTokenCsrf(tokenCsrfFound);
        } else {
            LOGGER.warn("Found Csrf token '" + tokenCsrfFound.getKey() + "=" + tokenCsrfFound.getValue() + "' in HTML body");
            exception = new IOException("please activate Csrf processing in Preferences");
        }
    }
    msgHeader.put(Header.SOURCE, pageSource.toString());
    // Inform the view about the log infos
    Request request = new Request();
    request.setMessage(Interaction.MESSAGE_HEADER);
    request.setParameters(msgHeader);
    MediatorModel.model().sendToViews(request);
    if (exception != null) {
        throw new IOException(exception);
    }
}
Also used : HashMap(java.util.HashMap) Element(org.jsoup.nodes.Element) Elements(org.jsoup.select.Elements) ArrayList(java.util.ArrayList) List(java.util.List) EnumMap(java.util.EnumMap) InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) SimpleEntry(java.util.AbstractMap.SimpleEntry) Request(com.jsql.model.bean.util.Request) IOException(java.io.IOException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Header(com.jsql.model.bean.util.Header) BufferedReader(java.io.BufferedReader) HashMap(java.util.HashMap) Map(java.util.Map) EnumMap(java.util.EnumMap)

Example 33 with Request

use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.

the class SuspendableGetVendor method run.

/**
 */
@Override
public Vendor run(Object... args) throws StoppedByUserSlidingException {
    Vendor vendor = null;
    if (MediatorModel.model().getVendorByUser() != Vendor.AUTO) {
        vendor = MediatorModel.model().getVendorByUser();
        LOGGER.info(I18n.valueByKey("LOG_DATABASE_TYPE_FORCED_BY_USER") + " [" + vendor + "]");
    } else {
        // Parallelize the search and let the user stops the process if needed.
        // SQL: force a wrong ORDER BY clause with an inexistent column, order by 1337,
        // and check if a correct error message is sent back by the server:
        // Unknown column '1337' in 'order clause'
        // or   supplied argument is not a valid MySQL result resource
        ExecutorService taskExecutor = Executors.newCachedThreadPool(new ThreadFactoryCallable("CallableGetVendor"));
        CompletionService<CallablePageSource> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
        for (String insertionCharacter : new String[] { "'\"#-)'\"" }) {
            taskCompletionService.submit(new CallablePageSource(insertionCharacter, insertionCharacter));
        }
        int total = 1;
        while (0 < total) {
            if (this.isSuspended()) {
                throw new StoppedByUserSlidingException();
            }
            try {
                CallablePageSource currentCallable = taskCompletionService.take().get();
                total--;
                String pageSource = currentCallable.getContent();
                for (Vendor vendorTest : Stream.of(Vendor.values()).skip(1).toArray(Vendor[]::new)) {
                    if (pageSource.matches("(?si).*(" + vendorTest.instance().fingerprintErrorsAsRegex() + ").*")) {
                        vendor = vendorTest;
                        LOGGER.debug("Found database [" + vendor + "]");
                        break;
                    }
                }
            } catch (InterruptedException | ExecutionException e) {
                LOGGER.error("Interruption while determining the type of database", e);
            }
        }
        // End the job
        try {
            taskExecutor.shutdown();
            taskExecutor.awaitTermination(15, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage(), e);
            Thread.currentThread().interrupt();
        }
        if (vendor == null) {
            vendor = Vendor.MYSQL;
            LOGGER.warn(I18n.valueByKey("LOG_DATABASE_TYPE_NOT_FOUND") + " [" + vendor + "]");
        } else {
            LOGGER.info(I18n.valueByKey("LOG_USING_DATABASE_TYPE") + " [" + vendor + "]");
            Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
            msgHeader.put(Header.URL, ConnectionUtil.getUrlBase() + ParameterUtil.getQueryStringAsString());
            msgHeader.put(Header.VENDOR, vendor);
            Request requestDatabaseIdentified = new Request();
            requestDatabaseIdentified.setMessage(Interaction.DATABASE_IDENTIFIED);
            requestDatabaseIdentified.setParameters(msgHeader);
            MediatorModel.model().sendToViews(requestDatabaseIdentified);
        }
    }
    Request requestSetVendor = new Request();
    requestSetVendor.setMessage(Interaction.SET_VENDOR);
    requestSetVendor.setParameters(vendor);
    MediatorModel.model().sendToViews(requestSetVendor);
    return vendor;
}
Also used : Request(com.jsql.model.bean.util.Request) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) Vendor(com.jsql.model.injection.vendor.Vendor) CallablePageSource(com.jsql.model.suspendable.callable.CallablePageSource) ThreadFactoryCallable(com.jsql.model.suspendable.callable.ThreadFactoryCallable) Header(com.jsql.model.bean.util.Header) ExecutorService(java.util.concurrent.ExecutorService) StoppedByUserSlidingException(com.jsql.model.exception.StoppedByUserSlidingException) ExecutionException(java.util.concurrent.ExecutionException) EnumMap(java.util.EnumMap)

Example 34 with Request

use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.

the class AbstractStrategy method markInvulnerable.

public void markInvulnerable(Interaction message, int i) {
    Request request = new Request();
    request.setMessage(message);
    Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
    msgHeader.put(Header.SOURCE, i);
    request.setParameters(msgHeader);
    MediatorModel.model().sendToViews(request);
}
Also used : Header(com.jsql.model.bean.util.Header) Request(com.jsql.model.bean.util.Request) EnumMap(java.util.EnumMap)

Example 35 with Request

use of com.jsql.model.bean.util.Request in project jsql-injection by ron190.

the class StrategyInjectionBlind method activateStrategy.

@Override
public void activateStrategy() {
    LOGGER.info(I18n.valueByKey("LOG_USING_STRATEGY") + " [" + this.getName() + "]");
    MediatorModel.model().setStrategy(StrategyInjection.BLIND);
    Request requestMarkBlindStrategy = new Request();
    requestMarkBlindStrategy.setMessage(Interaction.MARK_BLIND_STRATEGY);
    MediatorModel.model().sendToViews(requestMarkBlindStrategy);
}
Also used : Request(com.jsql.model.bean.util.Request)

Aggregations

Request (com.jsql.model.bean.util.Request)47 ArrayList (java.util.ArrayList)13 Header (com.jsql.model.bean.util.Header)12 EnumMap (java.util.EnumMap)12 ExecutorCompletionService (java.util.concurrent.ExecutorCompletionService)11 ExecutorService (java.util.concurrent.ExecutorService)11 JSqlException (com.jsql.model.exception.JSqlException)10 SuspendableGetRows (com.jsql.model.suspendable.SuspendableGetRows)9 IOException (java.io.IOException)9 ThreadFactoryCallable (com.jsql.model.suspendable.callable.ThreadFactoryCallable)8 ExecutionException (java.util.concurrent.ExecutionException)8 InjectionFailureException (com.jsql.model.exception.InjectionFailureException)7 ItemList (com.jsql.view.swing.list.ItemList)7 MalformedURLException (java.net.MalformedURLException)6 HttpRequest (java.net.http.HttpRequest)6 URL (java.net.URL)5 List (java.util.List)5 Matcher (java.util.regex.Matcher)5 IgnoreMessageException (com.jsql.model.exception.IgnoreMessageException)4 StoppedByUserSlidingException (com.jsql.model.exception.StoppedByUserSlidingException)4