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.CallableBlindBit;
6 import com.jsql.util.LogLevelUtil;
7 import org.apache.commons.lang3.StringUtils;
8 import org.apache.logging.log4j.LogManager;
9 import org.apache.logging.log4j.Logger;
10
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.ExecutorService;
16 import java.util.concurrent.Future;
17
18 import static name.fraser.neil.plaintext.diff_match_patch.Diff;
19
20
21
22
23 public class InjectionBlindBit extends AbstractInjectionMonobit<CallableBlindBit> {
24
25
26
27
28 private static final Logger LOGGER = LogManager.getRootLogger();
29
30
31 private String sourceReferencePage;
32
33
34
35
36
37
38
39 private List<Diff> falseDiffs = new ArrayList<>();
40
41
42
43
44
45
46 public InjectionBlindBit(InjectionModel injectionModel, BlindOperator blindMode) {
47 super(injectionModel, blindMode);
48
49
50 if (this.falsyBit.isEmpty() || this.injectionModel.isStoppedByUser()) {
51 return;
52 }
53
54
55 this.sourceReferencePage = this.callUrl(StringUtils.EMPTY, "bit#ref");
56
57
58
59 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetBlindBitTagFalse");
60 Collection<CallableBlindBit> callablesFalseTest = new ArrayList<>();
61 for (String falseTest: this.falsyBit) {
62 callablesFalseTest.add(new CallableBlindBit(
63 falseTest,
64 injectionModel,
65 this,
66 blindMode,
67 "bit#falsy"
68 ));
69 }
70
71
72
73
74 try {
75 List<Future<CallableBlindBit>> futuresFalseTest = taskExecutor.invokeAll(callablesFalseTest);
76 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
77 for (Future<CallableBlindBit> futureFalseTest: futuresFalseTest) {
78 if (this.injectionModel.isStoppedByUser()) {
79 return;
80 }
81 if (this.falseDiffs.isEmpty()) {
82 this.falseDiffs = futureFalseTest.get().getDiffsWithReference();
83 } else {
84 this.falseDiffs.retainAll(futureFalseTest.get().getDiffsWithReference());
85 }
86 }
87 } catch (ExecutionException e) {
88 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
89 } catch (InterruptedException e) {
90 LOGGER.log(LogLevelUtil.IGNORE, e, e);
91 Thread.currentThread().interrupt();
92 }
93
94 if (this.injectionModel.isStoppedByUser()) {
95 return;
96 }
97
98 this.cleanTrueDiffs(injectionModel, blindMode);
99 }
100
101 private void cleanTrueDiffs(InjectionModel injectionModel, BlindOperator blindMode) {
102
103
104 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetBlindBitTagTrue");
105 Collection<CallableBlindBit> callablesTrueTest = new ArrayList<>();
106 for (String trueTest: this.truthyBit) {
107 callablesTrueTest.add(new CallableBlindBit(
108 trueTest,
109 injectionModel,
110 this,
111 blindMode,
112 "bit#truthy"
113 ));
114 }
115
116
117
118
119 try {
120 List<Future<CallableBlindBit>> futuresTrueTest = taskExecutor.invokeAll(callablesTrueTest);
121 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
122 for (Future<CallableBlindBit> futureTrueTest: futuresTrueTest) {
123 if (this.injectionModel.isStoppedByUser()) {
124 return;
125 }
126 this.falseDiffs.removeAll(futureTrueTest.get().getDiffsWithReference());
127 }
128 } catch (ExecutionException e) {
129 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
130 } catch (InterruptedException e) {
131 LOGGER.log(LogLevelUtil.IGNORE, e, e);
132 Thread.currentThread().interrupt();
133 }
134 }
135
136
137 @Override
138 public CallableBlindBit getCallableBitTest(String sqlQuery, int indexChar, int bit) {
139 return new CallableBlindBit(
140 sqlQuery,
141 indexChar,
142 bit,
143 this.injectionModel,
144 this,
145 this.blindOperator,
146 "bit#" + indexChar + "~" + bit
147 );
148 }
149
150 @Override
151 public boolean isInjectable() throws StoppedByUserSlidingException {
152 if (this.injectionModel.isStoppedByUser()) {
153 throw new StoppedByUserSlidingException();
154 }
155 var blindTest = new CallableBlindBit(
156 this.injectionModel.getMediatorVendor().getVendor().instance().sqlBlindConfirm(),
157 this.injectionModel,
158 this,
159 this.blindOperator,
160 "bit#confirm"
161 );
162 try {
163 blindTest.call();
164 } catch (Exception e) {
165 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
166 }
167 return blindTest.isTrue() && !this.falseDiffs.isEmpty();
168 }
169
170 @Override
171 public String getInfoMessage() {
172 return "- Strategy Blind bit: query True when Diffs are matching " + this.falseDiffs + "\n\n";
173 }
174
175
176
177
178 public String getSourceReferencePage() {
179 return this.sourceReferencePage;
180 }
181
182 public List<Diff> getFalseDiffs() {
183 return this.falseDiffs;
184 }
185 }