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.AbstractCallableBit;
6 import com.jsql.model.injection.strategy.blind.callable.CallableCharInsertion;
7 import com.jsql.util.LogLevelUtil;
8 import org.apache.commons.lang3.RandomStringUtils;
9 import org.apache.commons.lang3.StringUtils;
10 import org.apache.logging.log4j.LogManager;
11 import org.apache.logging.log4j.Logger;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.List;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.ExecutorService;
18 import java.util.concurrent.Future;
19
20 import static name.fraser.neil.plaintext.diff_match_patch.Diff;
21
22
23
24
25 public class InjectionCharInsertion {
26
27
28
29
30 private static final Logger LOGGER = LogManager.getRootLogger();
31
32
33 private String blankFalseMark;
34
35
36
37
38
39
40
41 private List<Diff> constantTrueMark = new ArrayList<>();
42
43 protected final InjectionModel injectionModel;
44
45 private final String prefixSuffix;
46
47 private static final String PREFIX = "prefix";
48
49 private final List<String> falsy;
50
51
52
53
54
55
56 public InjectionCharInsertion(InjectionModel injectionModel, String falseCharInsertion, String prefixSuffix) {
57 this.injectionModel = injectionModel;
58 this.prefixSuffix = prefixSuffix;
59
60 List<String> truthy = this.injectionModel.getMediatorVendor().getVendor().instance().getTruthyBit();
61 this.falsy = this.injectionModel.getMediatorVendor().getVendor().instance().getFalsyBit();
62
63
64 if (truthy.isEmpty() || this.injectionModel.isStoppedByUser()) {
65 return;
66 }
67
68
69 this.blankFalseMark = this.callUrl(
70 falseCharInsertion,
71 "prefix:" + prefixSuffix.replace(InjectionCharInsertion.PREFIX, StringUtils.EMPTY)
72 );
73
74
75
76 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableCharInsertionTagTrue");
77 Collection<CallableCharInsertion> listCallableTagTrue = new ArrayList<>();
78
79 for (String urlTest: truthy) {
80 listCallableTagTrue.add(
81 new CallableCharInsertion(
82 String.join(
83 StringUtils.SPACE,
84 prefixSuffix.replace(InjectionCharInsertion.PREFIX, RandomStringUtils.secure().next(10, "345")),
85 this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy().getBinary().getModeOr(),
86 urlTest
87 ),
88 this,
89 "prefix#true"
90 )
91 );
92 }
93
94
95
96
97 try {
98 List<Future<CallableCharInsertion>> listTagTrue = taskExecutor.invokeAll(listCallableTagTrue);
99 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
100 for (var i = 1 ; i < listTagTrue.size() ; i++) {
101 if (this.injectionModel.isStoppedByUser()) {
102 return;
103 }
104
105 if (this.constantTrueMark.isEmpty()) {
106 this.constantTrueMark = listTagTrue.get(i).get().getOpcodes();
107 } else {
108 this.constantTrueMark.retainAll(listTagTrue.get(i).get().getOpcodes());
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 Thread.currentThread().interrupt();
116 }
117
118 this.initFalseMarks();
119 }
120
121 private void initFalseMarks() {
122
123
124 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableGetCharInsertionTagFalse");
125 Collection<CallableCharInsertion> listCallableTagFalse = new ArrayList<>();
126
127 for (String urlTest: this.falsy) {
128 listCallableTagFalse.add(
129 new CallableCharInsertion(
130 String.join(
131 StringUtils.SPACE,
132 this.prefixSuffix.replace(InjectionCharInsertion.PREFIX, RandomStringUtils.secure().next(10, "345")),
133 this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy().getBinary().getModeOr(),
134 urlTest
135 ),
136 this,
137 "prefix#false"
138 )
139 );
140 }
141
142
143
144
145 try {
146 List<Future<CallableCharInsertion>> listTagFalse = taskExecutor.invokeAll(listCallableTagFalse);
147 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
148
149 for (Future<CallableCharInsertion> falseTag: listTagFalse) {
150 if (this.injectionModel.isStoppedByUser()) {
151 return;
152 }
153 this.constantTrueMark.removeAll(falseTag.get().getOpcodes());
154 }
155 } catch (ExecutionException e) {
156 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
157 } catch (InterruptedException e) {
158 LOGGER.log(LogLevelUtil.IGNORE, e, e);
159 Thread.currentThread().interrupt();
160 }
161 }
162
163 public boolean isInjectable() throws StoppedByUserSlidingException {
164 if (this.injectionModel.isStoppedByUser()) {
165 throw new StoppedByUserSlidingException();
166 }
167 var blindTest = new CallableCharInsertion(
168 String.join(
169 StringUtils.SPACE,
170 this.prefixSuffix.replace(InjectionCharInsertion.PREFIX, RandomStringUtils.secure().next(10, "678")),
171 this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy().getBinary().getModeOr(),
172 this.injectionModel.getMediatorVendor().getVendor().instance().sqlBlindConfirm()
173 ),
174 this,
175 "prefix#confirm"
176 );
177 try {
178 blindTest.call();
179 } catch (Exception e) {
180 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
181 }
182 return blindTest.isTrue() && !this.constantTrueMark.isEmpty();
183 }
184
185 public String callUrl(String urlString, String metadataInjectionProcess) {
186 return this.injectionModel.injectWithoutIndex(urlString, metadataInjectionProcess);
187 }
188
189 public String callUrl(String urlString, String metadataInjectionProcess, AbstractCallableBit<?> callableBoolean) {
190 return this.injectionModel.injectWithoutIndex(urlString, metadataInjectionProcess, callableBoolean);
191 }
192
193
194
195
196 public String getBlankFalseMark() {
197 return this.blankFalseMark;
198 }
199
200 public List<Diff> getConstantTrueMark() {
201 return this.constantTrueMark;
202 }
203 }