1
2
3
4
5
6
7
8
9
10
11 package com.jsql.util;
12
13 import com.jsql.util.bruter.Base16;
14 import com.jsql.util.bruter.Base58;
15 import org.apache.commons.codec.binary.Base32;
16 import org.apache.commons.lang3.ArrayUtils;
17 import org.apache.commons.lang3.StringUtils;
18 import org.apache.commons.text.StringEscapeUtils;
19 import org.apache.logging.log4j.LogManager;
20 import org.apache.logging.log4j.Logger;
21 import org.mozilla.universalchardet.UniversalDetector;
22
23 import java.awt.*;
24 import java.io.*;
25 import java.net.URLDecoder;
26 import java.net.URLEncoder;
27 import java.nio.charset.StandardCharsets;
28 import java.util.ArrayList;
29 import java.util.Base64;
30 import java.util.List;
31 import java.util.Objects;
32 import java.util.zip.DeflaterOutputStream;
33 import java.util.zip.InflaterOutputStream;
34
35
36
37
38
39 public final class StringUtil {
40
41 private static final Logger LOGGER = LogManager.getRootLogger();
42
43
44 private static final CharEncoder DECIMAL_HTML_ENCODER = new CharEncoder("&#", ";", 10);
45 public static final String GET = "GET";
46 public static final String POST = "POST";
47 public static final String INFORMATION_SCHEMA = "information_schema";
48 public static final String APP_NAME = "jSQL Injection";
49
50
51
52
53
54 private static class CharEncoder {
55
56 private final String prefix;
57 private final String suffix;
58 private final int radix;
59
60 public CharEncoder(String prefix, String suffix, int radix) {
61 this.prefix = prefix;
62 this.suffix = suffix;
63 this.radix = radix;
64 }
65
66 protected void encode(char c, StringBuilder buff) {
67 buff
68 .append(this.prefix)
69 .append(Integer.toString(c, this.radix))
70 .append(this.suffix);
71 }
72 }
73
74 private StringUtil() {
75
76 }
77
78
79
80
81
82
83 public static String toHtmlDecimal(String text) {
84 return StringUtil.encode(text);
85 }
86
87
88
89
90
91
92 private static String encode(String text) {
93 var buff = new StringBuilder();
94 for (var i = 0 ; i < text.length() ; i++) {
95 if (text.charAt(i) > 128) {
96 StringUtil.DECIMAL_HTML_ENCODER.encode(text.charAt(i), buff);
97 } else {
98 buff.append(text.charAt(i));
99 }
100 }
101 return buff.toString();
102 }
103
104
105
106
107
108
109 public static String hexstr(String hex) {
110 var bytes = new byte[hex.length() / 2];
111 for (var i = 0 ; i < bytes.length ; i++) {
112 bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
113 }
114 return new String(bytes, StandardCharsets.UTF_8);
115 }
116
117 public static boolean isUtf8(String text) {
118 if (text == null) {
119 return false;
120 }
121
122 var detector = new UniversalDetector(null);
123 detector.handleData(text.getBytes(StandardCharsets.UTF_8), 0, text.length() - 1);
124 detector.dataEnd();
125 String encoding = detector.getDetectedCharset();
126 return encoding != null;
127 }
128
129 public static String detectUtf8(String text) {
130 if (text == null) {
131 return StringUtils.EMPTY;
132 }
133
134 String encoding = null;
135
136
137 try {
138 var detector = new UniversalDetector(null);
139 detector.handleData(text.getBytes(StandardCharsets.UTF_8), 0, text.length() - 1);
140 detector.dataEnd();
141 encoding = detector.getDetectedCharset();
142
143 } catch (ArrayIndexOutOfBoundsException e) {
144 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
145 }
146
147 String result = text;
148 if (encoding != null) {
149 result = new String(text.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
150 }
151 return result;
152 }
153
154 public static String base32Encode(String s) {
155 var base32 = new Base32();
156 return base32.encodeToString(StringUtil.getBytesUtf8(s));
157 }
158
159 public static String base32Decode(String s) {
160 var base32 = new Base32();
161 return StringUtil.newStringUtf8(base32.decode(s));
162 }
163
164 public static String base58Encode(String s) {
165 return Base58.encode(StringUtil.getBytesUtf8(s));
166 }
167
168 public static String base58Decode(String s) {
169 return StringUtil.newStringUtf8(Base58.decode(s));
170 }
171
172 public static String base16Encode(String s) {
173 var base16 = new Base16();
174 return base16.encodeToString(StringUtil.getBytesUtf8(s));
175 }
176
177 public static String base16Decode(String s) {
178 var base16 = new Base16();
179 return StringUtil.newStringUtf8(base16.decode(s));
180 }
181
182 public static String base64Decode(String s) {
183 return StringUtil.newStringUtf8(Base64.getDecoder().decode(s));
184 }
185
186 public static String base64Encode(String s) {
187 return Base64.getEncoder().encodeToString(StringUtil.getBytesUtf8(s));
188 }
189
190 public static String toHex(String text) {
191 return StringUtil.encodeHexString(text.getBytes(StandardCharsets.UTF_8));
192 }
193
194 public static String fromHex(String text) {
195 byte[] hex = StringUtil.decodeHexString(text);
196 return new String(hex, StandardCharsets.UTF_8);
197 }
198
199 public static String toHexZip(String text) throws IOException {
200 byte[] zip = StringUtil.compress(text);
201 return StringUtil.encodeHexString(zip);
202 }
203
204 public static String fromHexZip(String text) throws IOException {
205 return new String(StringUtil.decompress(StringUtil.decodeHexString(text)), StandardCharsets.UTF_8);
206 }
207
208 public static String toBase64Zip(String text) throws IOException {
209 return new String(Base64.getEncoder().encode(StringUtil.compress(text)));
210 }
211
212 public static String fromBase64Zip(String text) throws IOException {
213 byte[] decompressedBArray = StringUtil.decompress(Base64.getDecoder().decode(text));
214 return new String(decompressedBArray, StandardCharsets.UTF_8);
215 }
216
217 public static String toHtml(String text) {
218 return StringEscapeUtils.escapeHtml4(text);
219 }
220
221 public static String fromHtml(String text) {
222 return StringEscapeUtils.unescapeHtml4(text);
223 }
224
225 public static String toUrl(String text) {
226 return URLEncoder.encode(text, StandardCharsets.UTF_8);
227 }
228
229 public static String fromUrl(String text) {
230 return URLDecoder.decode(text, StandardCharsets.UTF_8);
231 }
232
233 public static String cleanSql(String query) {
234 return StringUtil.removeSqlComment(query)
235 .replaceAll("(?s)([^\\s\\w])(\\s+)", "$1")
236 .replaceAll("(?s)(\\s+)([^\\s\\w])", "$2")
237 .replaceAll("(?s)\\s+", " ")
238 .trim();
239 }
240
241
242
243
244
245
246 public static String removeSqlComment(String query) {
247 return query.replaceAll(
248 "(?s)(?!/\\*\\*/|/\\*!.*\\*/)/\\*.*?\\*/",
249 StringUtils.EMPTY
250 );
251 }
252
253 public static String formatReport(Color color, String text) {
254 return String.format(
255 "<span style=color:rgb(%s,%s,%s)>%s</span>",
256 color.getRed(),
257 color.getGreen(),
258 color.getBlue(),
259 text
260 );
261 }
262
263
264
265
266 private static byte[] compress(String text) throws IOException {
267 ByteArrayOutputStream os = new ByteArrayOutputStream();
268 try (DeflaterOutputStream dos = new DeflaterOutputStream(os)) {
269 dos.write(text.getBytes());
270 }
271 return os.toByteArray();
272 }
273
274 private static byte[] decompress(byte[] compressedTxt) throws IOException {
275 ByteArrayOutputStream os = new ByteArrayOutputStream();
276 try (OutputStream ios = new InflaterOutputStream(os)) {
277 ios.write(compressedTxt);
278 }
279 return os.toByteArray();
280 }
281
282 private static byte hexToByte(String hexString) {
283 int firstDigit = StringUtil.toDigit(hexString.charAt(0));
284 int secondDigit = StringUtil.toDigit(hexString.charAt(1));
285 return (byte) ((firstDigit << 4) + secondDigit);
286 }
287
288 private static int toDigit(char hexChar) {
289 int digit = Character.digit(hexChar, 16);
290 if (digit == -1) {
291 throw new IllegalArgumentException("Invalid Hexadecimal Character: "+ hexChar);
292 }
293 return digit;
294 }
295
296 private static String byteToHex(byte num) {
297 char[] hexDigits = new char[2];
298 hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
299 hexDigits[1] = Character.forDigit(num & 0xF, 16);
300 return new String(hexDigits);
301 }
302
303 private static String encodeHexString(byte[] byteArray) {
304 StringBuilder hexStringBuffer = new StringBuilder();
305 for (byte b : byteArray) {
306 hexStringBuffer.append(StringUtil.byteToHex(b));
307 }
308 return hexStringBuffer.toString();
309 }
310
311 private static byte[] decodeHexString(String hexString) {
312 if (hexString.length() % 2 == 1) {
313 throw new IllegalArgumentException("Invalid hexadecimal String supplied.");
314 }
315 byte[] bytes = new byte[hexString.length() / 2];
316 for (int i = 0 ; i < hexString.length() ; i += 2) {
317 bytes[i / 2] = StringUtil.hexToByte(hexString.substring(i, i + 2));
318 }
319 return bytes;
320 }
321
322 private static byte[] getBytesUtf8(String string) {
323 return string == null ? null : string.getBytes(StandardCharsets.UTF_8);
324 }
325
326 private static String newStringUtf8(byte[] bytes) {
327 return bytes == null ? null : new String(bytes, StandardCharsets.UTF_8);
328 }
329
330 public static byte[] xor(byte[] plaintext, int key) {
331 var ciphertext = new byte[plaintext.length];
332 for (var i = 0 ; i < plaintext.length ; i++) {
333 ciphertext[i] = (byte) (plaintext[i] ^ (key >>> (8 * (i % 4))));
334 }
335 return ciphertext;
336 }
337
338 public static List<String> toHexChunks(byte[] fileData) {
339 StringBuilder hexString = new StringBuilder();
340 for (byte b : fileData) {
341 hexString.append(String.format("%02X", b));
342 }
343 int chunkSize = 900;
344 List<String> chunks = new ArrayList<>();
345 for (int i = 0 ; i < hexString.length() ; i += chunkSize) {
346 int endIndex = Math.min(i + chunkSize, hexString.length());
347 chunks.add(hexString.substring(i, endIndex));
348 }
349 return chunks;
350 }
351
352 public static String getFile(String path) {
353 var content = new StringBuilder();
354 try (
355 var inputStream = PreferencesUtil.class.getClassLoader().getResourceAsStream(path);
356 var inputStreamReader = new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8);
357 var reader = new BufferedReader(inputStreamReader)
358 ) {
359 String line;
360 while ((line = reader.readLine()) != null) {
361 content.append(line).append("\n");
362 }
363 } catch (IOException e) {
364 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
365 }
366 return content.toString();
367 }
368
369 public static byte[] uncloak(byte[] fileData) {
370 fileData = StringUtil.xor(fileData, 353837730);
371 ArrayUtils.reverse(fileData);
372 return fileData;
373 }
374 }