1 package com.jsql.model.accessible;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.bean.database.MockElement;
5 import com.jsql.model.exception.InjectionFailureException;
6 import com.jsql.model.exception.LoopDetectedSlidingException;
7 import com.jsql.model.exception.StoppedByUserSlidingException;
8 import com.jsql.model.injection.vendor.model.VendorYaml;
9 import com.jsql.model.suspendable.SuspendableGetRows;
10 import com.jsql.util.LogLevelUtil;
11 import org.apache.commons.codec.binary.Hex;
12 import org.apache.commons.lang3.RandomStringUtils;
13 import org.apache.commons.lang3.StringUtils;
14 import org.apache.logging.log4j.LogManager;
15 import org.apache.logging.log4j.Logger;
16
17 import java.nio.charset.StandardCharsets;
18 import java.util.concurrent.Callable;
19
20
21
22
23
24 public class CallableFile implements Callable<CallableFile> {
25
26
27
28
29 private static final Logger LOGGER = LogManager.getRootLogger();
30 private static final String REQUIRE_STACK = "Read file requirement : stack query";
31
32
33
34
35 private final String pathFile;
36
37
38
39
40 private String sourceFile = StringUtils.EMPTY;
41
42
43
44
45 private final SuspendableGetRows suspendableReadFile;
46
47 private final InjectionModel injectionModel;
48
49
50
51
52 public CallableFile(String pathFile, InjectionModel injectionModel) {
53 this.pathFile = pathFile;
54 this.injectionModel= injectionModel;
55 this.suspendableReadFile = new SuspendableGetRows(injectionModel);
56 }
57
58
59
60
61
62 @Override
63 public CallableFile call() throws Exception {
64 var sourcePage = new String[]{ StringUtils.EMPTY };
65
66 String resultToParse = StringUtils.EMPTY;
67 try {
68 if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getMysql()) {
69 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Read file requirement : user FILE privilege");
70 resultToParse = this.suspendableReadFile.run(
71 this.injectionModel.getResourceAccess().getExploitMysql().getModelYaml().getFile().getRead().replace(
72 VendorYaml.FILEPATH_HEX,
73 Hex.encodeHexString(this.pathFile.getBytes(StandardCharsets.UTF_8))
74 ),
75 sourcePage,
76 false,
77 1,
78 MockElement.MOCK,
79 ResourceAccess.FILE_READ
80 );
81 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getH2()) {
82 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK);
83 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
84 this.injectionModel.injectWithoutIndex(String.format(
85 this.injectionModel.getResourceAccess().getExploitH2().getModelYaml().getFile().getCreateTable(),
86 nameTable,
87 this.pathFile
88 ), ResourceAccess.TBL_FILL);
89 resultToParse = this.suspendableReadFile.run(
90 String.format(
91 this.injectionModel.getResourceAccess().getExploitH2().getModelYaml().getFile().getRead(),
92 VendorYaml.TRAIL_SQL,
93 nameTable
94 ),
95 sourcePage,
96 false,
97 1,
98 MockElement.MOCK,
99 ResourceAccess.FILE_READ
100 );
101 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getSqlite()) {
102 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Read file requirement : extension fileio loaded");
103 resultToParse = this.suspendableReadFile.run(
104 String.format(
105 this.injectionModel.getResourceAccess().getExploitSqlite().getModelYaml().getExtension().getFileioRead(),
106 this.pathFile
107 ),
108 sourcePage,
109 false,
110 1,
111 MockElement.MOCK,
112 ResourceAccess.FILE_READ
113 );
114 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getDerby()) {
115 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK);
116 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
117 this.injectionModel.injectWithoutIndex(String.format(
118 this.injectionModel.getResourceAccess().getExploitDerby().getModelYaml().getFile().getCreateTable(),
119 nameTable,
120 nameTable, this.pathFile
121 ), ResourceAccess.TBL_FILL);
122 resultToParse = this.suspendableReadFile.run(
123 String.format(
124 this.injectionModel.getResourceAccess().getExploitDerby().getModelYaml().getFile().getRead(),
125 nameTable
126 ),
127 sourcePage,
128 true,
129 0,
130 MockElement.MOCK,
131 ResourceAccess.FILE_READ
132 );
133 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getHsqldb()) {
134 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK);
135 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
136 this.injectionModel.injectWithoutIndex(String.format(
137 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getCreateTable(),
138 nameTable,
139 nameTable, this.pathFile
140 ), ResourceAccess.TBL_FILL);
141 resultToParse = this.suspendableReadFile.run(
142 String.format(
143 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getResult(),
144 VendorYaml.TRAIL_SQL,
145 nameTable
146 ),
147 sourcePage,
148 false,
149 1,
150 MockElement.MOCK,
151 ResourceAccess.TBL_READ
152 );
153 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getPostgres()) {
154 try {
155 resultToParse = this.suspendableReadFile.run(
156 String.format(
157 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getFromDataFolder(),
158 this.pathFile
159 ),
160 sourcePage,
161 false,
162 1,
163 MockElement.MOCK,
164 ResourceAccess.FILE_READ
165 );
166 } catch (InjectionFailureException e) {
167 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Read data folder failure, trying with large object");
168 var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
169 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getLargeObject().getFromPath(),
170 this.pathFile
171 ), ResourceAccess.ADD_LOID);
172 if (StringUtils.isNotEmpty(loid)) {
173 resultToParse = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
174 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getLargeObject().getToText(),
175 loid
176 ), ResourceAccess.READ_LOID);
177 }
178 if (StringUtils.isEmpty(resultToParse)) {
179 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Read large object failure, trying with stack read");
180 var nameLibraryRandom = "tmp_" + RandomStringUtils.secure().nextAlphabetic(8);
181 this.injectionModel.injectWithoutIndex(String.format(
182 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getDrop(),
183 nameLibraryRandom
184 ), ResourceAccess.TBL_DROP);
185 this.injectionModel.injectWithoutIndex(String.format(
186 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getAdd(),
187 nameLibraryRandom
188 ), ResourceAccess.TBL_CREATE);
189 this.injectionModel.injectWithoutIndex(String.format(
190 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getFill(),
191 nameLibraryRandom,
192 this.pathFile
193 ), ResourceAccess.TBL_FILL);
194 resultToParse = this.suspendableReadFile.run(
195 String.format(
196 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getFromTempTable(),
197 nameLibraryRandom
198 ),
199 sourcePage,
200 false,
201 1,
202 MockElement.MOCK,
203 ResourceAccess.TBL_READ
204 );
205 }
206 }
207 } else {
208 LOGGER.log(
209 LogLevelUtil.CONSOLE_DEFAULT,
210 "Read file not implemented for [{}], share a working example to GitHub to speed up release",
211 this.injectionModel.getMediatorVendor().getVendor()
212 );
213 }
214 } catch (InjectionFailureException e) {
215
216 LOGGER.log(LogLevelUtil.IGNORE, e);
217 } catch (LoopDetectedSlidingException | StoppedByUserSlidingException e) {
218
219 if (StringUtils.isNotEmpty(e.getSlidingWindowAllRows())) {
220 resultToParse = e.getSlidingWindowAllRows();
221 } else if (StringUtils.isNotEmpty(e.getSlidingWindowCurrentRows())) {
222 resultToParse = e.getSlidingWindowCurrentRows();
223 }
224 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e);
225 }
226
227 this.sourceFile = resultToParse;
228 return this;
229 }
230
231
232
233
234 public String getPathFile() {
235 return this.pathFile;
236 }
237
238 public String getSourceFile() {
239 return this.sourceFile;
240 }
241
242 public SuspendableGetRows getSuspendableReadFile() {
243 return this.suspendableReadFile;
244 }
245 }