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