1 package com.jsql.model.injection.strategy;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.accessible.DataAccess;
5 import com.jsql.model.bean.util.Interaction;
6 import com.jsql.model.bean.util.Request;
7 import com.jsql.model.injection.vendor.model.VendorYaml;
8 import com.jsql.model.injection.vendor.model.yaml.Configuration;
9 import com.jsql.model.suspendable.AbstractSuspendable;
10 import com.jsql.util.I18nUtil;
11 import com.jsql.util.LogLevelUtil;
12 import com.jsql.util.StringUtil;
13 import org.apache.logging.log4j.LogManager;
14 import org.apache.logging.log4j.Logger;
15
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18
19 public class StrategyInjectionStack extends AbstractStrategy {
20
21
22
23
24 private static final Logger LOGGER = LogManager.getRootLogger();
25
26 private String performanceLength = "0";
27
28 public StrategyInjectionStack(InjectionModel injectionModel) {
29 super(injectionModel);
30 }
31
32 @Override
33 public void checkApplicability() {
34 if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isStrategyStackDisabled()) {
35 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, AbstractStrategy.FORMAT_SKIP_STRATEGY_DISABLED, this.getName());
36 return;
37 }
38
39
40 this.isApplicable = false;
41 var strategyYaml = this.injectionModel.getMediatorVendor().getVendor().instance().getModelYaml().getStrategy();
42 var configurationYaml = strategyYaml.getConfiguration();
43
44 this.logChecking();
45
46 boolean methodIsApplicable = this.isApplicable(configurationYaml, strategyYaml.getStack());
47 if (methodIsApplicable) {
48 Matcher regexSearch = this.getPerformance(configurationYaml, strategyYaml.getStack());
49 if (!regexSearch.find()) {
50 LOGGER.log(
51 LogLevelUtil.CONSOLE_ERROR,
52 "{} {} but injectable size is incorrect",
53 () -> I18nUtil.valueByKey("LOG_VULNERABLE"),
54 () -> "Stack"
55 );
56 methodIsApplicable = false;
57 } else {
58 this.performanceLength = String.valueOf(regexSearch.group(1).length());
59 }
60 }
61
62 if (methodIsApplicable) {
63 LOGGER.log(
64 LogLevelUtil.CONSOLE_SUCCESS,
65 "{} Stack injection showing [{}] characters",
66 () -> I18nUtil.valueByKey("LOG_VULNERABLE"),
67 () -> this.performanceLength
68 );
69 this.allow();
70 } else {
71 this.unallow();
72 }
73 }
74
75 private boolean isApplicable(Configuration configurationYaml, String stack) {
76 var methodIsApplicable = false;
77 var indexZeroToFind = "0";
78 String performanceSourcePage = this.injectionModel.injectWithoutIndex(
79 VendorYaml.replaceTags(
80 stack
81 .replace(VendorYaml.WINDOW, configurationYaml.getSlidingWindow())
82 .replace(VendorYaml.INJECTION, configurationYaml.getFailsafe().replace(VendorYaml.INDICE,indexZeroToFind))
83 .replace(VendorYaml.WINDOW_CHAR, "1")
84 .replace(VendorYaml.CAPACITY, VendorYaml.DEFAULT_CAPACITY)
85 ),
86 "stack#confirm"
87 );
88 String regexIndexZero = String.format(VendorYaml.FORMAT_INDEX, indexZeroToFind);
89 if (performanceSourcePage.matches("(?s).*"+ regexIndexZero +".*")) {
90 methodIsApplicable = true;
91 this.isApplicable = true;
92 }
93 return methodIsApplicable;
94 }
95
96 private Matcher getPerformance(Configuration configurationYaml, String stack) {
97 String performanceSourcePage = this.injectionModel.injectWithoutIndex(
98 VendorYaml.replaceTags(
99 stack
100 .replace(VendorYaml.WINDOW, configurationYaml.getSlidingWindow())
101 .replace(VendorYaml.INJECTION, configurationYaml.getCalibrator())
102 .replace(VendorYaml.WINDOW_CHAR, "1")
103 .replace(VendorYaml.CAPACITY, VendorYaml.DEFAULT_CAPACITY)
104 ),
105 "stack#size"
106 );
107 return Pattern.compile("(?s)"+ DataAccess.LEAD +"("+ VendorYaml.CALIBRATOR_SQL +"+)").matcher(performanceSourcePage);
108 }
109
110 @Override
111 public void allow(int... i) {
112 this.injectionModel.appendAnalysisReport(
113 StringUtil.formatReport(LogLevelUtil.COLOR_BLU, "### Strategy: " + this.getName())
114 + this.injectionModel.getReportWithoutIndex(
115 this.injectionModel.getMediatorVendor().getVendor().instance().sqlStack(StringUtil.formatReport(LogLevelUtil.COLOR_GREEN, "<query>"), "0", true),
116 "metadataInjectionProcess"
117 )
118 );
119 this.markVulnerability(Interaction.MARK_STACK_VULNERABLE);
120 }
121
122 @Override
123 public void unallow(int... i) {
124 this.markVulnerability(Interaction.MARK_STACK_INVULNERABLE);
125 }
126
127 @Override
128 public String inject(String sqlQuery, String startPosition, AbstractSuspendable stoppable, String metadataInjectionProcess) {
129 return this.injectionModel.injectWithoutIndex(
130 this.injectionModel.getMediatorVendor().getVendor().instance().sqlStack(sqlQuery, startPosition, false),
131 metadataInjectionProcess
132 );
133 }
134
135 @Override
136 public void activateWhenApplicable() {
137 if (this.injectionModel.getMediatorStrategy().getStrategy() == null && this.isApplicable()) {
138 LOGGER.log(
139 LogLevelUtil.CONSOLE_INFORM,
140 "{} [{}]",
141 () -> I18nUtil.valueByKey("LOG_USING_STRATEGY"),
142 this::getName
143 );
144 this.injectionModel.getMediatorStrategy().setStrategy(this.injectionModel.getMediatorStrategy().getStack());
145
146 var request = new Request();
147 request.setMessage(Interaction.MARK_STACK_STRATEGY);
148 this.injectionModel.sendToViews(request);
149 }
150 }
151
152 @Override
153 public String getPerformanceLength() {
154 return this.performanceLength;
155 }
156
157 @Override
158 public String getName() {
159 return "Stack";
160 }
161 }