InjectionTime.java

1
package com.jsql.model.injection.strategy.blind;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.exception.StoppedByUserSlidingException;
5
import com.jsql.model.injection.strategy.blind.callable.CallableTime;
6
import com.jsql.util.LogLevelUtil;
7
import org.apache.logging.log4j.LogManager;
8
import org.apache.logging.log4j.Logger;
9
10
import java.util.ArrayList;
11
import java.util.Collection;
12
import java.util.List;
13
import java.util.concurrent.ExecutionException;
14
import java.util.concurrent.ExecutorService;
15
import java.util.concurrent.Future;
16
17
/**
18
 * Time attack using parallel threads.
19
 * Waiting time in seconds, response time exceeded means query is false.
20
 * Noting that sleep() functions will add up for each line from request.
21
 * A sleep time of 5 will be executed only if the SELECT returns exactly one line.
22
 */
23
public class InjectionTime extends AbstractInjectionMonobit<CallableTime> {
24
25
    private static final Logger LOGGER = LogManager.getRootLogger();
26
27
    /**
28
     *  Time based works by default, many tests will change it to false if it isn't confirmed.
29
     */
30
    private boolean isTimeInjectable = true;
31
32
    /**
33
     * Create time attack initialization.
34
     * If every false requests are under 5 seconds and every true are below 5 seconds,
35
     * then time attack is confirmed.
36
     */
37
    public InjectionTime(InjectionModel injectionModel, BlindOperator blindOperator) {
38
        super(injectionModel, blindOperator);
39
40
        List<String> falsys = this.injectionModel.getMediatorVendor().getVendor().instance().getFalsyBit();
41 2 1. <init> : negated conditional → NO_COVERAGE
2. <init> : negated conditional → NO_COVERAGE
        if (falsys.isEmpty() || this.injectionModel.isStoppedByUser()) {
42
            return;
43
        }
44
45
        // Concurrent calls to the FALSE statements,
46
        // it will use inject() from the model
47
        ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetTimeTagFalse");
48
        Collection<CallableTime> callablesFalsys = new ArrayList<>();
49
        for (String falsy: falsys) {
50
            callablesFalsys.add(new CallableTime(
51
                falsy,
52
                injectionModel,
53
                this,
54
                blindOperator,
55
                "time#falsy"
56
            ));
57
        }
58
        
59
        // If one FALSE query makes less than X seconds,
60
        // then the test is a failure => exit
61
        // Allow the user to stop the loop
62
        try {
63
            List<Future<CallableTime>> futuresFalsys = taskExecutor.invokeAll(callablesFalsys);
64 1 1. <init> : removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE
            this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
65
            for (Future<CallableTime> futureFalsy: futuresFalsys) {
66 1 1. <init> : negated conditional → NO_COVERAGE
                if (this.injectionModel.isStoppedByUser()) {
67
                    return;
68
                }
69 1 1. <init> : negated conditional → NO_COVERAGE
                if (futureFalsy.get().isTrue()) {
70
                    this.isTimeInjectable = false;
71
                    return;
72
                }
73
            }
74
        } catch (ExecutionException e) {
75
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
76
        } catch (InterruptedException e) {
77
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
78 1 1. <init> : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
79
        }
80
        
81 1 1. <init> : removed call to com/jsql/model/injection/strategy/blind/InjectionTime::checkTruthys → NO_COVERAGE
        this.checkTruthys(blindOperator);
82
    }
83
84
    private void checkTruthys(BlindOperator blindOperator) {
85
        ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetTimeTagTrue");
86
        Collection<CallableTime> callablesTruthys = new ArrayList<>();
87
        List<String> truthys = this.injectionModel.getMediatorVendor().getVendor().instance().getTruthyBit();
88
        for (String truthy: truthys) {
89
            callablesTruthys.add(new CallableTime(
90
                truthy,
91
                this.injectionModel,
92
                this,
93
                blindOperator,
94
                "time#truthy"
95
            ));
96
        }
97
98
        // If one TRUE query makes more than X seconds then the test is a failure => exit
99
        try {
100
            List<Future<CallableTime>> futuresTruthys = taskExecutor.invokeAll(callablesTruthys);
101 1 1. checkTruthys : removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE
            this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
102
            for (Future<CallableTime> futureTruthy: futuresTruthys) {
103 1 1. checkTruthys : negated conditional → NO_COVERAGE
                if (this.injectionModel.isStoppedByUser()) {
104
                    return;
105
                }
106 1 1. checkTruthys : negated conditional → NO_COVERAGE
                if (!futureTruthy.get().isTrue()) {
107
                    this.isTimeInjectable = false;
108
                    return;
109
                }
110
            }
111
        } catch (ExecutionException e) {
112
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
113
        } catch (InterruptedException e) {
114
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
115 1 1. checkTruthys : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
116
        }
117
    }
118
119
    @Override
120
    public CallableTime getCallableBitTest(String sqlQuery, int indexChar, int bit) {
121 1 1. getCallableBitTest : replaced return value with null for com/jsql/model/injection/strategy/blind/InjectionTime::getCallableBitTest → NO_COVERAGE
        return new CallableTime(
122
            sqlQuery,
123
            indexChar,
124
            bit,
125
            this.injectionModel,
126
            this,
127
            this.blindOperator,
128
            "bit#" + indexChar + "~" + bit
129
        );
130
    }
131
132
    @Override
133
    public boolean isInjectable() throws StoppedByUserSlidingException {
134 1 1. isInjectable : negated conditional → NO_COVERAGE
        if (this.injectionModel.isStoppedByUser()) {
135
            throw new StoppedByUserSlidingException();
136
        }
137
        var callable = new CallableTime(
138
            this.injectionModel.getMediatorVendor().getVendor().instance().sqlBlindConfirm(),
139
            this.injectionModel,
140
            this,
141
            this.blindOperator,
142
            "time#confirm"
143
        );
144
        try {
145
            callable.call();
146
        } catch (Exception e) {
147
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
148
        }
149 3 1. isInjectable : replaced boolean return with true for com/jsql/model/injection/strategy/blind/InjectionTime::isInjectable → NO_COVERAGE
2. isInjectable : negated conditional → NO_COVERAGE
3. isInjectable : negated conditional → NO_COVERAGE
        return this.isTimeInjectable && callable.isTrue();
150
    }
151
152
    public int getSleepTime() {
153 2 1. getSleepTime : replaced int return with 0 for com/jsql/model/injection/strategy/blind/InjectionTime::getSleepTime → NO_COVERAGE
2. getSleepTime : negated conditional → NO_COVERAGE
        return this.injectionModel.getMediatorUtils().getPreferencesUtil().isLimitingSleepTimeStrategy()
154
            ? this.injectionModel.getMediatorUtils().getPreferencesUtil().countSleepTimeStrategy()
155
            : 5;
156
    }
157
158
    @Override
159
    public String getInfoMessage() {
160 1 1. getInfoMessage : replaced return value with "" for com/jsql/model/injection/strategy/blind/InjectionTime::getInfoMessage → NO_COVERAGE
        return "- Strategy Time: query True when "+ this.getSleepTime() +"s delay\n\n";
161
    }
162
}

Mutations

41

1.1
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

64

1.1
Location : <init>
Killed by : none
removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE

66

1.1
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

69

1.1
Location : <init>
Killed by : none
negated conditional → NO_COVERAGE

78

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

81

1.1
Location : <init>
Killed by : none
removed call to com/jsql/model/injection/strategy/blind/InjectionTime::checkTruthys → NO_COVERAGE

101

1.1
Location : checkTruthys
Killed by : none
removed call to com/jsql/util/ThreadUtil::shutdown → NO_COVERAGE

103

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

106

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

115

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

121

1.1
Location : getCallableBitTest
Killed by : none
replaced return value with null for com/jsql/model/injection/strategy/blind/InjectionTime::getCallableBitTest → NO_COVERAGE

134

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

149

1.1
Location : isInjectable
Killed by : none
replaced boolean return with true for com/jsql/model/injection/strategy/blind/InjectionTime::isInjectable → NO_COVERAGE

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

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

153

1.1
Location : getSleepTime
Killed by : none
replaced int return with 0 for com/jsql/model/injection/strategy/blind/InjectionTime::getSleepTime → NO_COVERAGE

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

160

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

Active mutators

Tests examined


Report generated by PIT 1.19.1