From 469e1ace6161bb83d69fdae302a57265a3baac76 Mon Sep 17 00:00:00 2001 From: sirjonasxx <36828922+sirjonasxx@users.noreply.github.com> Date: Thu, 5 Apr 2018 21:23:52 +0200 Subject: [PATCH] autoDetect hotel, autodetect ping headerid --- src/main/Cacher.java | 183 +++++++++++++++++++++ src/main/protocol/HConnection.java | 192 ++++++++++++++-------- src/main/protocol/HMessage.java | 4 + src/main/protocol/memory/Rc4Obtainer.java | 39 ++++- src/main/ui/connection/Connection.java | 7 +- 5 files changed, 355 insertions(+), 70 deletions(-) create mode 100644 src/main/Cacher.java diff --git a/src/main/Cacher.java b/src/main/Cacher.java new file mode 100644 index 0000000..a03df2f --- /dev/null +++ b/src/main/Cacher.java @@ -0,0 +1,183 @@ +package main; + +import java.io.*; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Jonas on 05/04/18. + */ +public class Cacher { + + private static String getCacheDir() { + return System.getProperty("user.home") + File.separator + ".G-Earth/"; + } + + public static boolean exists(String key) { + File f = new File(getCacheDir(), "cache.txt"); + if (f.exists()) { + try { + List lines = Files.readAllLines(f.toPath()); + + for (String line : lines) { + if (line.startsWith(key+":")) { + return true; + } + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + return false; + } + + public static String get(String key) { + File f = new File(getCacheDir(), "cache.txt"); + if (f.exists()) { + try { + List lines = Files.readAllLines(f.toPath()); + + for (String line : lines) { + if (line.startsWith(key+":")) { + return line.split(":")[1]; + } + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + return ""; + } + + public static void remove(String key) { + File targetFile = new File(getCacheDir() + File.separator + "cache.txt"); + File parent = targetFile.getParentFile(); + if (!parent.exists() && !parent.mkdirs()) { + throw new IllegalStateException("Couldn't create dir: " + parent); + } + if (!targetFile.exists()) { + try { + targetFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + try + { + ArrayList lines = new ArrayList(); + File f1 = new File(getCacheDir() + File.separator + "cache.txt"); + FileReader fr = new FileReader(f1); + BufferedReader br = new BufferedReader(fr); + String line = null; + while ((line = br.readLine()) != null) + { + if (!line.startsWith(key + ":")) + lines.add(line); + + } + fr.close(); + br.close(); + + FileWriter fw = new FileWriter(f1); + BufferedWriter out = new BufferedWriter(fw); + + for (int i = 0; i < lines.size(); i++) { + out.write(lines.get(i)); + if (i != lines.size() - 1) out.write("\n"); + } + out.flush(); + out.close(); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public static void add(String key, String value) { + File targetFile = new File(getCacheDir() + File.separator + "cache.txt"); + File parent = targetFile.getParentFile(); + if (!parent.exists() && !parent.mkdirs()) { + throw new IllegalStateException("Couldn't create dir: " + parent); + } + if (!targetFile.exists()) { + try { + targetFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +// File f = new File(getCacheDir(), "cache.txt"); +// if (!f.exists()) { +// try { +// PrintWriter writer = new PrintWriter(f.getPath(), "UTF-8"); +// writer.write(""); +// writer.close(); +// } catch (FileNotFoundException | UnsupportedEncodingException e) { +// e.printStackTrace(); +// } +// } + + try + { + ArrayList lines = new ArrayList(); + File f1 = new File(getCacheDir() + File.separator + "cache.txt"); + FileReader fr = new FileReader(f1); + BufferedReader br = new BufferedReader(fr); + String line = null; + boolean containmmm = false; + while ((line = br.readLine()) != null) + { + if (line.startsWith(key+":")) + containmmm = true; + lines.add(line); + + } + fr.close(); + br.close(); + + FileWriter fw = new FileWriter(f1); + BufferedWriter out = new BufferedWriter(fw); + + if (!containmmm) { + out.write(key+":"+value); + } + + for (int i = 0; i < lines.size(); i++) { + out.write("\n"+ lines.get(i)); + } + + out.flush(); + out.close(); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public static void update(String key, String value) { + remove(key); + add(key, value); + } + + + public static void main(String[] args) { +// System.out.println(exists("hallo")); +// System.out.println(get("hallo")); +// +// add("hallo","doei"); +// +// System.out.println(exists("hallo")); +// System.out.println(get("hallo")); +// +// remove("hallo"); +// System.out.println(get("hallo")); + System.out.println(get("PRODUCTION-201804032203-770536283-pingHeader")); + } +} diff --git a/src/main/protocol/HConnection.java b/src/main/protocol/HConnection.java index 58c2c1e..acabdc8 100644 --- a/src/main/protocol/HConnection.java +++ b/src/main/protocol/HConnection.java @@ -13,9 +13,7 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; public class HConnection { @@ -27,9 +25,9 @@ public class HConnection { CONNECTED // CONNECTED } - private static Set autoDetectHosts; + private static List autoDetectHosts; static { - autoDetectHosts = new HashSet<>(); + autoDetectHosts = new ArrayList<>(); autoDetectHosts.add("game-us.habbo.com:38101"); autoDetectHosts.add("game-nl.habbo.com:30000"); autoDetectHosts.add("game-br.habbo.com:30000"); @@ -47,39 +45,60 @@ public class HConnection { private volatile Object[] trafficListeners = {new ArrayList(), new ArrayList(), new ArrayList()}; private volatile List stateChangeListeners = new ArrayList<>(); private volatile State state = State.NOT_CONNECTED; - private volatile String input_domain = null; // given string representation - private volatile String actual_domain; // actual ip representation - private volatile int port = -1; + private volatile List input_domain = new ArrayList<>(); // given string representation + private volatile List actual_domain = new ArrayList<>(); // actual ip representation + private volatile List port = new ArrayList<>(); + + private volatile List proxy = new ArrayList<>(); + private volatile int realProxyIndex = -1; - private volatile ServerSocket proxy; private volatile Handler inHandler = null; private volatile Handler outHandler = null; + private volatile boolean autoDetectHost = false; + public State getState() { return state; } - private String detourIP() { - return "127.0.0.1"; + + // autodetect method + public void prepare() { + prepare(autoDetectHosts); } + // manual method public void prepare(String domain, int port) { - setState(State.PREPARING); + List potentialHost = new ArrayList<>(); + potentialHost.add(domain+":"+port); + prepare(potentialHost); + realProxyIndex = 0; + } - this.actual_domain = domain; - this.port = port; + private void prepare(List allPotentialHosts) { + setState(State.PREPARING); + input_domain.clear(); + actual_domain.clear(); + port.clear(); + clearAllProxies(); + realProxyIndex = -1; + + for (String host : allPotentialHosts) { + String[] split = host.split(":"); + input_domain.add(split[0]); + port.add(Integer.parseInt(split[1])); + } if (hostRedirected) { - hostsReplacer.removeRedirect(domain, detourIP()); - hostRedirected = false; + removeFromHosts(); } try { - InetAddress address = InetAddress.getByName(domain); - actual_domain = address.getHostAddress(); - if (DEBUG) System.out.println("found dom:" + actual_domain); - input_domain = domain; + for (String host : allPotentialHosts) { + InetAddress address = InetAddress.getByName(host.split(":")[0]); + actual_domain.add(address.getHostAddress()); + } setState(State.PREPARED); } catch (UnknownHostException e) { @@ -87,49 +106,63 @@ public class HConnection { setState(State.NOT_CONNECTED); } } + public void start() throws IOException { if (state == State.PREPARED) { - if (DEBUG) System.out.println("waiting for client on port: " + port); setState(State.WAITING_FOR_CLIENT); if (!hostRedirected) { - hostsReplacer.addRedirect(input_domain, detourIP()); - hostRedirected = true; + addToHosts(); } - proxy = new ServerSocket(port); - try { - while ((state == State.WAITING_FOR_CLIENT) && !proxy.isClosed()) { - try { - Socket client = proxy.accept(); - if (DEBUG) System.out.println("accepted a proxy"); - new Thread(() -> { + for (int i = 0; i < actual_domain.size(); i++) { + ServerSocket proxy = new ServerSocket(port.get(i), 10, InetAddress.getByName("127.0.0." + (i+1))); + this.proxy.add(proxy); + String dom = actual_domain.get(i); + Integer port2 = port.get(i); + + int[] i2 = {i}; + + new Thread(() -> { + try { + Thread.sleep(100); + while ((state == State.WAITING_FOR_CLIENT) && !proxy.isClosed()) { try { - startProxyThread(client); - } catch (InterruptedException | IOException e) { + Socket client = proxy.accept(); + realProxyIndex = i2[0]; + closeAllProxies(i2[0]); + if (DEBUG) System.out.println("accepted a proxy"); + + new Thread(() -> { + try { + startProxyThread(client, dom, port2); + } catch (InterruptedException | IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }).start(); + + + } catch (IOException e1) { // TODO Auto-generated catch block - e.printStackTrace(); + //e1.printStackTrace(); } - }).start(); - - - } catch (IOException e1) { - // TODO Auto-generated catch block - //e1.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace(); } - } - } catch (Exception e) { - e.printStackTrace(); + }).start(); } + if (DEBUG) System.out.println("done waiting for clients with: " + this.state ); } } - private void startProxyThread(Socket client) throws InterruptedException, UnknownHostException, IOException { + private void startProxyThread(Socket client, String ip, int port) throws InterruptedException, UnknownHostException, IOException { final boolean[] datastream = new boolean[1]; - Socket habbo_server = new Socket(actual_domain, port); + Socket habbo_server = new Socket(ip, port); OutputStream client_out = client.getOutputStream(); InputStream client_in = client.getInputStream(); @@ -141,6 +174,7 @@ public class HConnection { final boolean[] aborted = new boolean[1]; Rc4Obtainer rc4Obtainer = new Rc4Obtainer(); + rc4Obtainer.setHConnection(this); // wachten op data van client new Thread(() -> { @@ -243,37 +277,58 @@ public class HConnection { } private void onConnect() { if (hostRedirected) { - hostsReplacer.removeRedirect(input_domain, detourIP()); - hostRedirected = false; + removeFromHosts(); } - if (proxy != null && !proxy.isClosed()) { - try { - proxy.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + clearAllProxies(); } public void abort() { if (hostRedirected) { - hostsReplacer.removeRedirect(input_domain, detourIP()); - hostRedirected = false; + removeFromHosts(); } - port = -1; + + port.clear(); + input_domain.clear(); + actual_domain.clear(); + realProxyIndex = -1; + setState(State.NOT_CONNECTED); - actual_domain = null; - if (proxy != null && !proxy.isClosed()) { - try { - proxy.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + clearAllProxies(); + } + + private void clearAllProxies() { + closeAllProxies(-1); + proxy.clear(); + } + private void closeAllProxies(int except) { + for (int i = 0; i < proxy.size(); i++) { + if (i != except) { + ServerSocket prox = proxy.get(i); + if (prox != null && !prox.isClosed()) { + try { + prox.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } + } } + private void addToHosts() { + for (int i = 0; i < input_domain.size(); i++) { + hostsReplacer.addRedirect(input_domain.get(i), "127.0.0." + (i+1)); + } + hostRedirected = true; + } + private void removeFromHosts(){ + for (int i = 0; i < input_domain.size(); i++) { + hostsReplacer.removeRedirect(input_domain.get(i), "127.0.0." + (i+1)); + } + hostRedirected = false; + } private void setState(State state) { if (state != this.state) { @@ -311,12 +366,17 @@ public class HConnection { } public int getPort() { - return port; + if (realProxyIndex == -1) return -1; + return port.get(realProxyIndex); } public String getHost() { - return actual_domain; + if (realProxyIndex == -1) return ""; + return actual_domain.get(realProxyIndex); + } + public String getDomain() { + if (realProxyIndex == -1) return ""; + return input_domain.get(realProxyIndex); } - public String getDomain() { return input_domain; } public boolean sendToClient(HPacket message) { diff --git a/src/main/protocol/HMessage.java b/src/main/protocol/HMessage.java index 832619d..b4a3127 100644 --- a/src/main/protocol/HMessage.java +++ b/src/main/protocol/HMessage.java @@ -21,6 +21,10 @@ public class HMessage { isBlocked = false; } + public int getIndex() { + return index; + } + public void setBlocked(boolean block) { isBlocked = block; } diff --git a/src/main/protocol/memory/Rc4Obtainer.java b/src/main/protocol/memory/Rc4Obtainer.java index c179f29..6a3e4e8 100644 --- a/src/main/protocol/memory/Rc4Obtainer.java +++ b/src/main/protocol/memory/Rc4Obtainer.java @@ -1,9 +1,14 @@ package main.protocol.memory; +import main.Cacher; +import main.protocol.HConnection; +import main.protocol.HMessage; import main.protocol.HPacket; +import main.protocol.TrafficListener; import main.protocol.crypto.RC4; import main.protocol.packethandler.IncomingHandler; import main.protocol.packethandler.OutgoingHandler; +import sun.misc.Cache; import java.util.List; import java.util.Random; @@ -16,6 +21,9 @@ public class Rc4Obtainer { OutgoingHandler outgoingHandler = null; IncomingHandler incomingHandler = null; + String habboVersion = ""; + int pingHeader = -1; + public Rc4Obtainer() { client = HabboClient.create(); } @@ -35,15 +43,34 @@ public class Rc4Obtainer { incomingHandler = handler; } + public void setHConnection(HConnection hConnection) { + hConnection.addTrafficListener(0, message -> { + if (message.getIndex() == 0 && message.getDestination() == HMessage.Side.TOSERVER) { + habboVersion = message.getPacket().readString(6); + if (Cacher.exists(habboVersion +"-pingHeader")) { + pingHeader = Integer.parseInt(Cacher.get(habboVersion +"-pingHeader")); + } + } + if (pingHeader == -1 && message.getDestination() == HMessage.Side.TOCLIENT && message.getPacket().length() == 2) { + pingHeader = message.getPacket().headerId(); + Cacher.add(habboVersion +"-pingHeader", pingHeader+""); + } + }); + } + private volatile int addedBytes = 0; private void onSendFirstEncryptedMessage() { - incomingHandler.block(); outgoingHandler.block(); new Thread(() -> { if (DEBUG) System.out.println("[+] send encrypted"); sleep(20); + while (pingHeader == -1) { + sleep(50); + } + incomingHandler.block(); + List diff = null; @@ -63,7 +90,7 @@ public class Rc4Obtainer { if (i % 2 == 1) { am = rand.nextInt(30) + 1; for (int j = 0; j < am; j++) { - incomingHandler.sendToStream(new HPacket(3794).toBytes()); + incomingHandler.sendToStream(new HPacket(pingHeader).toBytes()); outgoingHandler.fakePongAlert(); sleep(20); } @@ -111,7 +138,7 @@ public class Rc4Obtainer { MemorySnippet snippet1 = new MemorySnippet(snippet.getOffset(), new byte[snippet.getData().length]); client.fetchMemory(snippet1); - incomingHandler.sendToStream(new HPacket(3794).toBytes()); + incomingHandler.sendToStream(new HPacket(pingHeader).toBytes()); outgoingHandler.fakePongAlert(); sleep(70); @@ -154,6 +181,12 @@ public class Rc4Obtainer { //if result = null ud better reload + if (result == null) { + System.out.println("please try again."); + System.out.println("found RC4 table:"); + printByteArray(data); + return; + } // STEP FOUR: undo all sent packets in the rc4 stream diff --git a/src/main/ui/connection/Connection.java b/src/main/ui/connection/Connection.java index c7e8f54..5e3eed2 100644 --- a/src/main/ui/connection/Connection.java +++ b/src/main/ui/connection/Connection.java @@ -78,7 +78,12 @@ public class Connection extends SubForm { public void btnConnect_clicked(ActionEvent actionEvent) { if (!isBusy) { isBusy = true; - getHConnection().prepare(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText())); + if (cbx_autodetect.isSelected()) { + getHConnection().prepare(); + } + else { + getHConnection().prepare(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText())); + } if (HConnection.DEBUG) System.out.println("connecting");