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