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