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