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