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.model.injection.vendor.model.Vendor;
7 import com.jsql.model.injection.vendor.model.VendorYaml;
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 public class InjectionVendor {
21
22
23
24
25 private static final Logger LOGGER = LogManager.getRootLogger();
26
27
28 private String blankFalseMark;
29
30 private List<Diff> constantTrueMark = new ArrayList<>();
31
32 protected final InjectionModel injectionModel;
33
34 private final List<String> falsy;
35
36 public InjectionVendor(InjectionModel injectionModel, String vendorSpecificWithMode, Vendor vendor) {
37 this.injectionModel = injectionModel;
38
39 List<String> truthy = this.injectionModel.getMediatorVendor().getVendor().instance().getTruthy();
40 this.falsy = this.injectionModel.getMediatorVendor().getVendor().instance().getFalsy();
41
42
43 if (truthy.isEmpty() || this.injectionModel.isStoppedByUser()) {
44 return;
45 }
46
47
48 this.blankFalseMark = this.callUrl(
49 StringUtils.EMPTY,
50 "vendor:" + vendor
51 );
52
53
54
55 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableVendorTagTrue");
56 Collection<CallableVendor> listCallableTagTrue = new ArrayList<>();
57 for (String urlTest: truthy) {
58 listCallableTagTrue.add(
59 new CallableVendor(
60 vendorSpecificWithMode.replace(VendorYaml.TEST, urlTest),
61 this,
62 "vendor#true"
63 )
64 );
65 }
66
67
68
69
70 try {
71 List<Future<CallableVendor>> listTagTrue = taskExecutor.invokeAll(listCallableTagTrue);
72 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
73
74 for (var i = 1 ; i < listTagTrue.size() ; i++) {
75 if (this.injectionModel.isStoppedByUser()) {
76 return;
77 }
78 if (this.constantTrueMark.isEmpty()) {
79 this.constantTrueMark = listTagTrue.get(i).get().getOpcodes();
80 } else {
81 this.constantTrueMark.retainAll(listTagTrue.get(i).get().getOpcodes());
82 }
83 }
84 } catch (ExecutionException e) {
85 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
86 } catch (InterruptedException e) {
87 LOGGER.log(LogLevelUtil.IGNORE, e, e);
88 Thread.currentThread().interrupt();
89 }
90
91 this.initFalseMarks(vendorSpecificWithMode);
92 }
93
94 private void initFalseMarks(String vendorSpecificWithMode) {
95
96
97 ExecutorService taskExecutor = this.injectionModel.getMediatorUtils().getThreadUtil().getExecutor("CallableVendorTagFalse");
98 Collection<CallableVendor> listCallableTagFalse = new ArrayList<>();
99
100 for (String urlTest: this.falsy) {
101 listCallableTagFalse.add(
102 new CallableVendor(
103 vendorSpecificWithMode.replace(VendorYaml.TEST, urlTest),
104 this,
105 "vendor#false"
106 )
107 );
108 }
109
110
111
112
113 try {
114 List<Future<CallableVendor>> listTagFalse = taskExecutor.invokeAll(listCallableTagFalse);
115 this.injectionModel.getMediatorUtils().getThreadUtil().shutdown(taskExecutor);
116
117 for (Future<CallableVendor> falseTag: listTagFalse) {
118
119 if (this.injectionModel.isStoppedByUser()) {
120 return;
121 }
122
123 this.constantTrueMark.removeAll(falseTag.get().getOpcodes());
124 }
125 } catch (ExecutionException e) {
126 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
127 } catch (InterruptedException e) {
128 LOGGER.log(LogLevelUtil.IGNORE, e, e);
129 Thread.currentThread().interrupt();
130 }
131 }
132
133 public boolean isInjectable(String vendorSpecificWithMode) throws StoppedByUserSlidingException {
134 if (this.injectionModel.isStoppedByUser()) {
135 throw new StoppedByUserSlidingException();
136 }
137
138 var blindTest = new CallableVendor(
139 vendorSpecificWithMode.replace(VendorYaml.TEST, this.injectionModel.getMediatorVendor().getVendor().instance().sqlTestBinaryInit()),
140 this,
141 "vendor#confirm"
142 );
143 try {
144 blindTest.call();
145 } catch (Exception e) {
146 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
147 }
148
149 return blindTest.isTrue() && !this.constantTrueMark.isEmpty();
150 }
151
152 public String callUrl(String urlString, String metadataInjectionProcess) {
153 return this.injectionModel.injectWithoutIndex(urlString, metadataInjectionProcess);
154 }
155
156 public String callUrl(String urlString, String metadataInjectionProcess, AbstractCallableBinary<?> callableBoolean) {
157 return this.injectionModel.injectWithoutIndex(urlString, metadataInjectionProcess, callableBoolean);
158 }
159
160
161
162
163 public String getBlankFalseMark() {
164 return this.blankFalseMark;
165 }
166
167 public List<Diff> getConstantTrueMark() {
168 return this.constantTrueMark;
169 }
170 }