mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-27 02:40:51 +01:00
Updated G-MemZ, added universal macOS binary, improved flash rc4 crack
This commit is contained in:
parent
2087932a5e
commit
f5a88398c5
@ -76,9 +76,7 @@ public class Rc4Obtainer {
|
|||||||
@Override
|
@Override
|
||||||
public void onPacket() {
|
public void onPacket() {
|
||||||
if (handler.isEncryptedStream()) {
|
if (handler.isEncryptedStream()) {
|
||||||
final boolean isShockwave = handler instanceof ShockwavePacketOutgoingHandler;
|
if (counter.incrementAndGet() != 3) {
|
||||||
|
|
||||||
if (isShockwave && counter.incrementAndGet() != 3) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,25 +97,11 @@ public class Rc4Obtainer {
|
|||||||
logger.info("Caught encrypted packet, attempting to find decryption keys");
|
logger.info("Caught encrypted packet, attempting to find decryption keys");
|
||||||
|
|
||||||
final HabboClient client = HabboClientFactory.get(hConnection);
|
final HabboClient client = HabboClientFactory.get(hConnection);
|
||||||
if (client == null) {
|
|
||||||
logger.info("Unsupported platform / client combination, aborting connection");
|
|
||||||
hConnection.abort();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
final long startTime = System.currentTimeMillis();
|
final long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
boolean worked = false;
|
if (!onSendFirstEncryptedMessage(flashPacketHandler, client.getRC4Tables())) {
|
||||||
int i = 0;
|
|
||||||
while (!worked && i < 4) {
|
|
||||||
worked = (i % 2 == 0) ?
|
|
||||||
onSendFirstEncryptedMessage(flashPacketHandler, client.getRC4cached()) :
|
|
||||||
onSendFirstEncryptedMessage(flashPacketHandler, client.getRC4possibilities());
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!worked) {
|
|
||||||
try {
|
try {
|
||||||
Platform.runLater(Rc4Obtainer::showErrorDialog);
|
Platform.runLater(Rc4Obtainer::showErrorDialog);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
@ -153,8 +137,16 @@ public class Rc4Obtainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packetHandler instanceof FlashPacketHandler) {
|
if (packetHandler instanceof FlashPacketHandler) {
|
||||||
|
// Fast-path.
|
||||||
for (byte[] possible : potentialRC4tables) {
|
for (byte[] possible : potentialRC4tables) {
|
||||||
if (bruteFlash(packetHandler, encBuffer, possible)) {
|
if (bruteFlashFast(packetHandler, encBuffer, possible)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow-path.
|
||||||
|
for (byte[] possible : potentialRC4tables) {
|
||||||
|
if (bruteFlashSlow(packetHandler, encBuffer, possible)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,11 +170,13 @@ public class Rc4Obtainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean bruteShockwaveHeaderFast(EncryptedPacketHandler packetHandler, byte[] encBuffer, byte[] tableState) {
|
private boolean bruteShockwaveHeaderFast(EncryptedPacketHandler packetHandler, byte[] encBuffer, byte[] tableState) {
|
||||||
final int HardcodedQ = 164;
|
// Table state Q starts at 152 after premixing.
|
||||||
|
// Add 12 for the 3 headers being encrypted and you get 164.
|
||||||
|
final int EstimatedQ = 164;
|
||||||
|
|
||||||
for (int j = 0; j < 256; j++) {
|
for (int j = 0; j < 256; j++) {
|
||||||
if (bruteShockwaveHeader(packetHandler, encBuffer, tableState, HardcodedQ, j)) {
|
if (bruteShockwaveHeader(packetHandler, encBuffer, tableState, EstimatedQ, j)) {
|
||||||
logger.debug("Brute forced with fast path");
|
logger.debug("Brute forced shockwave with fast path");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +188,7 @@ public class Rc4Obtainer {
|
|||||||
for (int q = 0; q < 256; q++) {
|
for (int q = 0; q < 256; q++) {
|
||||||
for (int j = 0; j < 256; j++) {
|
for (int j = 0; j < 256; j++) {
|
||||||
if (bruteShockwaveHeader(packetHandler, encBuffer, tableState, q, j)) {
|
if (bruteShockwaveHeader(packetHandler, encBuffer, tableState, q, j)) {
|
||||||
logger.debug("Brute forced with slow path");
|
logger.debug("Brute forced shockwave with slow path");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,43 +231,60 @@ public class Rc4Obtainer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean bruteFlash(EncryptedPacketHandler flashPacketHandler, byte[] encBuffer, byte[] possible) {
|
private boolean bruteFlashFast(EncryptedPacketHandler packetHandler, byte[] encBuffer, byte[] tableState) {
|
||||||
|
final int EstimatedQ = encBuffer.length % 256;
|
||||||
|
|
||||||
try {
|
for (int j = 0; j < 256; j++) {
|
||||||
for (int i = 0; i < 256; i++) {
|
if (bruteFlash(packetHandler, encBuffer, tableState, EstimatedQ, j)) {
|
||||||
for (int j = 0; j < 256; j++) {
|
logger.debug("Brute forced flash with fast path");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final byte[] keycpy = Arrays.copyOf(possible, possible.length);
|
return false;
|
||||||
final RC4 rc4Tryout = new RC4(keycpy, i, j);
|
}
|
||||||
|
|
||||||
if (flashPacketHandler.getDirection() == HMessage.Direction.TOSERVER)
|
private boolean bruteFlashSlow(EncryptedPacketHandler packetHandler, byte[] encBuffer, byte[] tableState) {
|
||||||
rc4Tryout.undoRc4(encBuffer);
|
for (int q = 0; q < 256; q++) {
|
||||||
|
for (int j = 0; j < 256; j++) {
|
||||||
if (rc4Tryout.couldBeFresh()) {
|
if (bruteFlash(packetHandler, encBuffer, tableState, q, j)) {
|
||||||
|
logger.debug("Brute forced flash with slow path");
|
||||||
final byte[] encDataCopy = Arrays.copyOf(encBuffer, encBuffer.length);
|
return true;
|
||||||
final RC4 rc4TryCopy = rc4Tryout.deepCopy();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final PayloadBuffer payloadBuffer = new FlashBuffer();
|
|
||||||
final byte[] decoded = rc4TryCopy.cipher(encDataCopy);
|
|
||||||
|
|
||||||
payloadBuffer.push(decoded);
|
|
||||||
payloadBuffer.receive();
|
|
||||||
|
|
||||||
if (payloadBuffer.isEmpty()) {
|
|
||||||
flashPacketHandler.setRc4(rc4Tryout);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean bruteFlash(EncryptedPacketHandler flashPacketHandler, byte[] encBuffer, byte[] tableState, int q, int j) {
|
||||||
|
final byte[] keycpy = Arrays.copyOf(tableState, tableState.length);
|
||||||
|
final RC4 rc4Tryout = new RC4(keycpy, q, j);
|
||||||
|
|
||||||
|
if (flashPacketHandler.getDirection() == HMessage.Direction.TOSERVER) {
|
||||||
|
rc4Tryout.undoRc4(encBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc4Tryout.couldBeFresh()) {
|
||||||
|
final byte[] encDataCopy = Arrays.copyOf(encBuffer, encBuffer.length);
|
||||||
|
final RC4 rc4TryCopy = rc4Tryout.deepCopy();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final PayloadBuffer payloadBuffer = new FlashBuffer();
|
||||||
|
final byte[] decoded = rc4TryCopy.cipher(encDataCopy);
|
||||||
|
|
||||||
|
payloadBuffer.push(decoded);
|
||||||
|
payloadBuffer.receive();
|
||||||
|
|
||||||
|
if (payloadBuffer.isEmpty()) {
|
||||||
|
flashPacketHandler.setRc4(rc4Tryout);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,12 @@
|
|||||||
package gearth.protocol.memory.habboclient;
|
package gearth.protocol.memory.habboclient;
|
||||||
|
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 13/06/18.
|
* Created by Jonas on 13/06/18.
|
||||||
*/
|
*/
|
||||||
public abstract class HabboClient {
|
public interface HabboClient {
|
||||||
|
|
||||||
protected HConnection hConnection;
|
List<byte[]> getRC4Tables();
|
||||||
|
|
||||||
public HabboClient(HConnection connection) {
|
|
||||||
this.hConnection = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional
|
|
||||||
public abstract List<byte[]> getRC4cached();
|
|
||||||
|
|
||||||
public abstract List<byte[]> getRC4possibilities();
|
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,8 @@ package gearth.protocol.memory.habboclient;
|
|||||||
|
|
||||||
import gearth.misc.OSValidator;
|
import gearth.misc.OSValidator;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.connection.HClient;
|
|
||||||
import gearth.protocol.memory.habboclient.linux.LinuxHabboClient;
|
import gearth.protocol.memory.habboclient.linux.LinuxHabboClient;
|
||||||
import gearth.protocol.memory.habboclient.macOs.MacOsHabboClient;
|
import gearth.protocol.memory.habboclient.external.MemoryClient;
|
||||||
import gearth.protocol.memory.habboclient.shockwave.ShockwaveMemoryClient;
|
|
||||||
import gearth.protocol.memory.habboclient.windows.WindowsHabboClient;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 13/06/18.
|
* Created by Jonas on 13/06/18.
|
||||||
@ -14,17 +11,11 @@ import gearth.protocol.memory.habboclient.windows.WindowsHabboClient;
|
|||||||
public class HabboClientFactory {
|
public class HabboClientFactory {
|
||||||
|
|
||||||
public static HabboClient get(HConnection connection) {
|
public static HabboClient get(HConnection connection) {
|
||||||
if (connection.getClientType() == HClient.SHOCKWAVE) {
|
if (OSValidator.isUnix()) {
|
||||||
return new ShockwaveMemoryClient(connection);
|
return new LinuxHabboClient(connection);
|
||||||
} else {
|
|
||||||
if (OSValidator.isWindows()) return new WindowsHabboClient(connection);
|
|
||||||
if (OSValidator.isUnix()) return new LinuxHabboClient(connection);
|
|
||||||
if (OSValidator.isMac()) return new MacOsHabboClient(connection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo use rust if beneficial
|
return new MemoryClient(connection);
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package gearth.protocol.memory.habboclient.shockwave;
|
package gearth.protocol.memory.habboclient.external;
|
||||||
|
|
||||||
import gearth.encoding.HexEncoding;
|
import gearth.encoding.HexEncoding;
|
||||||
import gearth.misc.OSValidator;
|
import gearth.misc.OSValidator;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
|
import gearth.protocol.connection.HClient;
|
||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
import gearth.protocol.memory.habboclient.HabboClient;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -17,21 +18,18 @@ import java.util.Collections;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ShockwaveMemoryClient extends HabboClient {
|
public class MemoryClient implements HabboClient {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ShockwaveMemoryClient.class);
|
private static final Logger logger = LoggerFactory.getLogger(MemoryClient.class);
|
||||||
|
|
||||||
public ShockwaveMemoryClient(HConnection connection) {
|
private final HConnection connection;
|
||||||
super(connection);
|
|
||||||
|
public MemoryClient(HConnection connection) {
|
||||||
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<byte[]> getRC4cached() {
|
public List<byte[]> getRC4Tables() {
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4possibilities() {
|
|
||||||
final List<byte[]> result = new ArrayList<>();
|
final List<byte[]> result = new ArrayList<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -41,7 +39,7 @@ public class ShockwaveMemoryClient extends HabboClient {
|
|||||||
result.add(HexEncoding.toBytes(potentialTable));
|
result.add(HexEncoding.toBytes(potentialTable));
|
||||||
}
|
}
|
||||||
} catch (IOException | URISyntaxException e) {
|
} catch (IOException | URISyntaxException e) {
|
||||||
logger.error("Failed to read RC4 possibilities from the Shockwave client", e);
|
logger.error("Failed to read RC4 possibilities from the client", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse the list so that the most likely keys are at the top.
|
// Reverse the list so that the most likely keys are at the top.
|
||||||
@ -59,7 +57,8 @@ public class ShockwaveMemoryClient extends HabboClient {
|
|||||||
filePath += "/G-MemZ";
|
filePath += "/G-MemZ";
|
||||||
}
|
}
|
||||||
|
|
||||||
final ProcessBuilder pb = new ProcessBuilder(filePath);
|
final String hotelType = connection.getClientType() == HClient.SHOCKWAVE ? "shockwave" : "flash";
|
||||||
|
final ProcessBuilder pb = new ProcessBuilder(filePath, hotelType);
|
||||||
final Process p = pb.start();
|
final Process p = pb.start();
|
||||||
|
|
||||||
final HashSet<String> possibleData = new HashSet<>();
|
final HashSet<String> possibleData = new HashSet<>();
|
@ -7,7 +7,7 @@ import java.io.*;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class LinuxHabboClient extends HabboClient {
|
public class LinuxHabboClient implements HabboClient {
|
||||||
|
|
||||||
|
|
||||||
private static final String[] potentialProcessNames = {"--ppapi-flash-args", "plugin-container", "Habbo"};
|
private static final String[] potentialProcessNames = {"--ppapi-flash-args", "plugin-container", "Habbo"};
|
||||||
@ -25,8 +25,6 @@ public class LinuxHabboClient extends HabboClient {
|
|||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
public LinuxHabboClient(HConnection connection) {
|
public LinuxHabboClient(HConnection connection) {
|
||||||
super(connection);
|
|
||||||
|
|
||||||
File folder = new File("/proc");
|
File folder = new File("/proc");
|
||||||
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
@ -56,12 +54,6 @@ public class LinuxHabboClient extends HabboClient {
|
|||||||
if (DEBUG) System.out.println("* Found flashclient " + potentialProcesses.size() + " potential processes");
|
if (DEBUG) System.out.println("* Found flashclient " + potentialProcesses.size() + " potential processes");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4cached() {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void refreshMemoryMaps() {
|
private void refreshMemoryMaps() {
|
||||||
String filename = "/proc/"+this.PID+"/maps";
|
String filename = "/proc/"+this.PID+"/maps";
|
||||||
BufferedReader reader;
|
BufferedReader reader;
|
||||||
@ -148,7 +140,7 @@ public class LinuxHabboClient extends HabboClient {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<byte[]> getRC4possibilities() {
|
public List<byte[]> getRC4Tables() {
|
||||||
|
|
||||||
int offset = 4;
|
int offset = 4;
|
||||||
List<byte[]> resultSet = new ArrayList<>();
|
List<byte[]> resultSet = new ArrayList<>();
|
||||||
|
@ -1,136 +0,0 @@
|
|||||||
package gearth.protocol.memory.habboclient.macOs;
|
|
||||||
|
|
||||||
import gearth.encoding.HexEncoding;
|
|
||||||
import gearth.misc.Cacher;
|
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
import gearth.protocol.HMessage;
|
|
||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
|
||||||
import org.bouncycastle.util.encoders.Hex;
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.StringJoiner;
|
|
||||||
|
|
||||||
public class MacOsHabboClient extends HabboClient {
|
|
||||||
|
|
||||||
public MacOsHabboClient(HConnection connection) {
|
|
||||||
super(connection);
|
|
||||||
|
|
||||||
connection.addTrafficListener(0, message -> {
|
|
||||||
if (message.getDestination() == HMessage.Direction.TOSERVER && message.getPacket().headerId() == PRODUCTION_ID) {
|
|
||||||
production = message.getPacket().readString();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static final String OFFSETS_CACHE_KEY = "RC4Offsets";
|
|
||||||
private static final int PRODUCTION_ID = 4000;
|
|
||||||
private String production = "";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4cached() {
|
|
||||||
List<byte[]> result = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
List<String> possibleResults = readPossibleBytes(true);
|
|
||||||
|
|
||||||
if (possibleResults == null)
|
|
||||||
return new ArrayList<>();
|
|
||||||
|
|
||||||
for (String s : possibleResults)
|
|
||||||
result.add(HexEncoding.toBytes(s));
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<String> readPossibleBytes(boolean useCache) throws IOException, URISyntaxException {
|
|
||||||
ProcessBuilder pb;
|
|
||||||
|
|
||||||
JSONObject revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
|
|
||||||
if (revisionList == null) {
|
|
||||||
Cacher.put(OFFSETS_CACHE_KEY, new JSONObject());
|
|
||||||
revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert revisionList != null;
|
|
||||||
JSONArray cachedOffsets;
|
|
||||||
if (revisionList.has(production))
|
|
||||||
cachedOffsets = (JSONArray) revisionList.get(production);
|
|
||||||
else
|
|
||||||
cachedOffsets = null;
|
|
||||||
|
|
||||||
StringJoiner joiner = new StringJoiner(" ");
|
|
||||||
|
|
||||||
if (useCache) {
|
|
||||||
if (cachedOffsets == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Object s : cachedOffsets) {
|
|
||||||
joiner.add((String)s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String g_mem = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "/G-Mem";
|
|
||||||
if (!useCache)
|
|
||||||
pb = new ProcessBuilder(g_mem, hConnection.getClientHost() , Integer.toString(hConnection.getClientPort()));
|
|
||||||
else
|
|
||||||
pb = new ProcessBuilder(g_mem, hConnection.getClientHost() , Integer.toString(hConnection.getClientPort()), "-c" + joiner.toString());
|
|
||||||
|
|
||||||
|
|
||||||
Process p = pb.start();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
|
||||||
|
|
||||||
String line;
|
|
||||||
ArrayList<String> possibleData = new ArrayList<>();
|
|
||||||
|
|
||||||
if (cachedOffsets == null) {
|
|
||||||
cachedOffsets = new JSONArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
while((line = reader.readLine()) != null) {
|
|
||||||
if (line.length() > 1) {
|
|
||||||
if (!useCache && (count++ % 2 == 0)) {
|
|
||||||
if (!cachedOffsets.toList().contains(line)) {
|
|
||||||
cachedOffsets.put(line);
|
|
||||||
System.out.println("[+] " + line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
possibleData.add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
revisionList.put(production, cachedOffsets);
|
|
||||||
Cacher.put(OFFSETS_CACHE_KEY, revisionList);
|
|
||||||
p.destroy();
|
|
||||||
return possibleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4possibilities() {
|
|
||||||
List<byte[]> result = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
ArrayList<String> possibleData = readPossibleBytes(false);
|
|
||||||
|
|
||||||
for (String possibleHexStr : possibleData) {
|
|
||||||
result.add(HexEncoding.toBytes(possibleHexStr));
|
|
||||||
}
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
package gearth.protocol.memory.habboclient.rust;
|
|
||||||
|
|
||||||
import gearth.encoding.HexEncoding;
|
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RustHabboClient extends HabboClient {
|
|
||||||
public RustHabboClient(HConnection connection) {
|
|
||||||
super(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4cached() {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<byte[]> getRC4possibilities() {
|
|
||||||
ArrayList<String> possibleData = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
String g_mem = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "/G-Mem";
|
|
||||||
ProcessBuilder pb = new ProcessBuilder(g_mem, hConnection.getClientHost() , Integer.toString(hConnection.getClientPort()));
|
|
||||||
|
|
||||||
|
|
||||||
Process p = pb.start();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
|
||||||
|
|
||||||
String line;
|
|
||||||
|
|
||||||
while((line = reader.readLine()) != null) {
|
|
||||||
if (line.length() > 1) {
|
|
||||||
System.out.println("[+] " + line);
|
|
||||||
possibleData.add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (URISyntaxException | IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<byte[]> ret = new ArrayList<>();
|
|
||||||
|
|
||||||
for (String possibleHexStr : possibleData)
|
|
||||||
ret.add(HexEncoding.toBytes(possibleHexStr));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,137 +0,0 @@
|
|||||||
package gearth.protocol.memory.habboclient.windows;
|
|
||||||
|
|
||||||
import gearth.encoding.HexEncoding;
|
|
||||||
import gearth.misc.Cacher;
|
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
import gearth.protocol.HMessage;
|
|
||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Jonas on 27/06/2018.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class WindowsHabboClient extends HabboClient {
|
|
||||||
public WindowsHabboClient(HConnection connection) {
|
|
||||||
super(connection);
|
|
||||||
|
|
||||||
connection.addTrafficListener(0, message -> {
|
|
||||||
if (message.getDestination() == HMessage.Direction.TOSERVER && message.getPacket().headerId() == PRODUCTION_ID) {
|
|
||||||
production = message.getPacket().readString();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String OFFSETS_CACHE_KEY = "RC4Offsets";
|
|
||||||
private static final int PRODUCTION_ID = 4000;
|
|
||||||
private String production = "";
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4cached() {
|
|
||||||
List<byte[]> result = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
List<String> possibleResults = readPossibleBytes(true);
|
|
||||||
|
|
||||||
if (possibleResults == null)
|
|
||||||
return new ArrayList<>();
|
|
||||||
|
|
||||||
for (String s : possibleResults)
|
|
||||||
result.add(HexEncoding.toBytes(s));
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<String> readPossibleBytes(boolean useCache) throws IOException, URISyntaxException {
|
|
||||||
ProcessBuilder pb;
|
|
||||||
|
|
||||||
JSONObject revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
|
|
||||||
if (revisionList == null) {
|
|
||||||
Cacher.put(OFFSETS_CACHE_KEY, new JSONObject());
|
|
||||||
revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert revisionList != null;
|
|
||||||
JSONArray cachedOffsets;
|
|
||||||
if (revisionList.has(production))
|
|
||||||
cachedOffsets = (JSONArray) revisionList.get(production);
|
|
||||||
else
|
|
||||||
cachedOffsets = null;
|
|
||||||
|
|
||||||
StringJoiner joiner = new StringJoiner(" ");
|
|
||||||
|
|
||||||
if (useCache) {
|
|
||||||
if (cachedOffsets == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Object s : cachedOffsets) {
|
|
||||||
joiner.add((String)s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String g_winmem = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "\\G-Mem.exe";
|
|
||||||
String clientHost = hConnection.isRawIpMode() ? "null" : hConnection.getClientHost();
|
|
||||||
String clientPort = hConnection.isRawIpMode() ? "null" : hConnection.getClientPort() + "";
|
|
||||||
|
|
||||||
if (!useCache)
|
|
||||||
pb = new ProcessBuilder(g_winmem, clientHost , clientPort);
|
|
||||||
else
|
|
||||||
pb = new ProcessBuilder(g_winmem, clientHost , clientPort, "-c" + joiner.toString());
|
|
||||||
|
|
||||||
|
|
||||||
Process p = pb.start();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
|
||||||
|
|
||||||
String line;
|
|
||||||
ArrayList<String> possibleData = new ArrayList<>();
|
|
||||||
|
|
||||||
if (cachedOffsets == null) {
|
|
||||||
cachedOffsets = new JSONArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
while((line = reader.readLine()) != null) {
|
|
||||||
if (line.length() > 1) {
|
|
||||||
if (!useCache && (count++ % 2 == 0)) {
|
|
||||||
if (!cachedOffsets.toList().contains(line)) {
|
|
||||||
cachedOffsets.put(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
possibleData.add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
revisionList.put(production, cachedOffsets);
|
|
||||||
Cacher.put(OFFSETS_CACHE_KEY, revisionList);
|
|
||||||
p.destroy();
|
|
||||||
return possibleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4possibilities() {
|
|
||||||
List<byte[]> result = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
ArrayList<String> possibleData = readPossibleBytes(false);
|
|
||||||
|
|
||||||
for (String possibleHexStr : possibleData) {
|
|
||||||
result.add(HexEncoding.toBytes(possibleHexStr));
|
|
||||||
}
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,7 +4,7 @@ import gearth.protocol.crypto.RC4Base64;
|
|||||||
import gearth.protocol.crypto.RC4Cipher;
|
import gearth.protocol.crypto.RC4Cipher;
|
||||||
import gearth.protocol.memory.Rc4Obtainer;
|
import gearth.protocol.memory.Rc4Obtainer;
|
||||||
import gearth.protocol.memory.habboclient.HabboClientFactory;
|
import gearth.protocol.memory.habboclient.HabboClientFactory;
|
||||||
import gearth.protocol.memory.habboclient.shockwave.ShockwaveMemoryClient;
|
import gearth.protocol.memory.habboclient.external.MemoryClient;
|
||||||
import gearth.protocol.packethandler.EncryptedPacketHandler;
|
import gearth.protocol.packethandler.EncryptedPacketHandler;
|
||||||
import gearth.protocol.packethandler.shockwave.ShockwavePacketOutgoingHandler;
|
import gearth.protocol.packethandler.shockwave.ShockwavePacketOutgoingHandler;
|
||||||
import org.bouncycastle.util.encoders.Hex;
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
@ -39,14 +39,9 @@ public class TestRc4Shockwave {
|
|||||||
private final Semaphore waitSemaphore = new Semaphore(0);
|
private final Semaphore waitSemaphore = new Semaphore(0);
|
||||||
private final AtomicReference<RC4Cipher> cipher = new AtomicReference<>();
|
private final AtomicReference<RC4Cipher> cipher = new AtomicReference<>();
|
||||||
|
|
||||||
private final ShockwaveMemoryClient mockShockwaveMemoryClient = new ShockwaveMemoryClient(null) {
|
private final MemoryClient mockShockwaveMemoryClient = new MemoryClient(null) {
|
||||||
@Override
|
@Override
|
||||||
public List<byte[]> getRC4cached() {
|
public List<byte[]> getRC4Tables() {
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4possibilities() {
|
|
||||||
return Arrays.asList(potentialTables);
|
return Arrays.asList(potentialTables);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user