WPE Pro Packet Editing Question

02/17/2016 11:12 nosTa1337#1
Hallo,

Ich versuche zurzeit die Packete von einem Android MMO abzufangen und zu editieren.

Hier sind mal ein paar Pakete, allerdings scheinen diese ne dynamische Verschlüsselung zu haben.

Hier hab ich 4x "a" (ohne Anführungszeichen) im Chat gesendet
Code:
98 6D A1 13 E8 DD 73 1D 91 71 A2 87 74 11 49 98 DB 01 78 3D 86 51 1D 25 1D BD 5C CB 5C C3 EB 8D C7 D5 86 BA 0B 40 06 B0 DA 

62 70 57 2A D9 7D EC 01 F9 B4 A1 E2 63 2B 16 AE CA FB 84 F5 C4 8E B8 3D 4D 95 0F 4F A6 3E B1 6C 33 1F 5D 7B 45 34 2B F6 98 

C1 94 14 5A C4 33 94 30 95 BC 6F 55 6D EA 97 CA FD EF 6D FC FE 30 9A D6 D0 C6 12 FF C7 AD 8C BD 4F 7E BA 15 61 A4 A8 EA 36 

D1 0D 0A 0E CA E9 76 14 9C 10 75 C3 5B 5A F7 EE D1 55 45 7D 66 70 EA F1 63 42 84 C0 18 0B 4A 14 14 7E 3F 15 44 76 DE 72 60
Andere Funktion, welche 3x aufgerufen wurde.
Code:
23 00 47 1C EF 45 89 64 8E DB 55 EC 30 C9 09 6B 8A 3E FB C9 9B 

31 77 33 73 66 4A AA 63 01 33 B6 9E 2B 8E DE CA D0 63 7B 56 3B 

0C EF 95 25 FD 4C D7 FD 5C 0B 34 F3 E2 FA E4 F1 35 8C 69 4E 96
Ich hab mal ein paar interessante Funktionen aufgelistet, welche meiner Meinung nach mit Verschlüsselung arbeiten (reverse engineering der APK).

Code:
public String getHashCode(Map<String, String> params) {
        String afDevKey = (String)params.get("appsflyerKey");
        String timestamp = (String)params.get("af_timestamp");
        String uid = (String)params.get("uid");
        String nativeSha1 = 0x0;
        nativeSha1 = toSHA1(afDevKey.substring(0x0, 0x7) + uid.substring(0x0, 0x7) + timestamp.substring((timestamp.length() - 0x7)));
        return nativeSha1;
    }
    
    public static String toSHA1(String input) {
        String nativeSha1 = 0x0;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(getBytes("UTF-8"));
            return nativeSha1;
        } catch(NoSuchAlgorithmException e) {
            e.printStackTrace();
            return nativeSha1;
        } catch(UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return nativeSha1;
    }
    
    private static String byteToHex(byte[] hash) {
        Formatter formatter = new Formatter();
        byte b = hash[local1]local1 = local1 + 0x1) {
            formatter.format("%02x", new Object[] {Byte.valueOf(b)});
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
}
Code:
private static String b(Context p1) {
        if((i != null) && (i.length() > 0)) {
            return i;
        }
        try {
            d localString1 = new d();
            localString1.a("androidId", b.b(p1));
            localString1.a("deviceId", b.a(p1));
            i = Base64.encodeToString(localString1.toString().getBytes(), 0x2);
        } catch(c localc2) {
            localc2.printStackTrace();
        }
        return i;
    }
Code:
public static String a(String p1) {
        String localString1 = 0x0;
        try {
            localconst/42 = MessageDigest.getInstance("MD5");
        } catch(NoSuchAlgorithmException localNoSuchAlgorithmException3) {
            localNoSuchAlgorithmException3.printStackTrace();
        }
        localString1.update(getBytes(), 0x0, length());
        localbyte[]4 = localString1.digest();
        new String() = 0x0;
        if(new String() >= getBytes().length) {
            return (new String() + 0x1);
        }
        getBytes()[new String()] = getBytes()[new String()] & 0xff;
        if(getBytes()[new String()] <= 0xf) {
            localStringBuilder5 = "0";
        }
        localStringBuilder5 = Integer.toHexString(getBytes()[new String()]);
        return Integer.toHexString(getBytes()[new String()]).toUpperCase();
    }
Hier ein Ausschnitt einer relativ großen Klasse
Code:
 private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
        0x2 = (source[(srcOffset + 0x2)] << 0x18)) {
            switch(numSigBytes) {
            }
            case 3:
            {
                destination[destOffset] = alphabet[(source[(srcOffset + 0x2)] << 0x18)];
                destination[(destOffset + 0x1)] = alphabet[(((source[(srcOffset + 0x1)] << 0x18) | localint1) & 0x3f)];
                destination[(destOffset + 0x2)] = alphabet[(alphabet[(((source[(srcOffset + 0x1)] << 0x18) | localint1) & 0x3f)] & 0x3f)];
                destination[(destOffset + 0x3)] = alphabet[(inBuff & 0x3f)];
                return destination;
            }
            case 2:
            {
                destination[destOffset] = alphabet[(source[(srcOffset + 0x2)] << 0x18)];
                destination[(destOffset + 0x1)] = alphabet[(((source[(srcOffset + 0x1)] << 0x18) | localint1) & 0x3f)];
                destination[(destOffset + 0x2)] = alphabet[(alphabet[(((source[(srcOffset + 0x1)] << 0x18) | localint1) & 0x3f)] & 0x3f)];
                destination[(destOffset + 0x3)] = 0x3d;
                return destination;
            }
            case 1:
            {
                destination[destOffset] = alphabet[(source[(srcOffset + 0x2)] << 0x18)];
                destination[(destOffset + 0x1)] = alphabet[(((source[(srcOffset + 0x1)] << 0x18) | localint1) & 0x3f)];
                destination[(destOffset + 0x2)] = 0x3d;
                destination[(destOffset + 0x3)] = 0x3d;
                break;
            }
        }
        return destination;
    }
Code:
public class b {
    priva = "uLi4/f4+Pb39.T19".getBytes();
    private static b = "nmeug.f9/Om+L823".getBytes();
    
    public static String a(String p1, String p2) throws Exception {
        localString1 = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec localbyte[]2 = new SecretKeySpec(a, "AES");
        IvParameterSpec localIvParameterSpec3 = new IvParameterSpec(b);
        "AES/CBC/PKCS5Padding".init(0x1, localbyte[]2, localIvParameterSpec3);
        localString1 = "AES/CBC/PKCS5Padding".doFinal(getBytes(p2));
        return c.d("AES/CBC/PKCS5Padding");
    }
    
    public static String b(String p1, String p2) throws Exception {
        localString1 = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec localString2 = new SecretKeySpec(a, "AES");
        IvParameterSpec localIvParameterSpec3 = new IvParameterSpec(b);
        "AES/CBC/PKCS5Padding".init(0x2, localString2, localIvParameterSpec3);
        localString1 = "AES/CBC/PKCS5Padding".doFinal(c.b(p1));
        return new String("AES/CBC/PKCS5Padding", p2);
    }
}
02/17/2016 12:27 qqdev#2
Einfach genauso implementieren. Wenn du packets ändern willst, dann kannst du es direkt in der APK machen. Oder du machst einen MITM-Angriff.
02/17/2016 12:38 nosTa1337#3
Mir gehts ja um den MITM Angriff mit WPE Pro.

Allerdings bräuchte ich den Algorithmus um die oben gelisteten Pakete zu entschlüssen bzw einfach das gleiche Paket gültig senden zu können.

Mit Cheat Engine habe ich natürlich auch schon rumexperimentiert und mir den ASM Code betrachtet.

Mein Hauptziel ist es aber, aufgrund der TCP Daten einen Bot zu programmieren, welche nicht auf den Hauptclient angewiesen ist :).

Meine Hauptfrage ist eigentlich, ob mir jemand beim entschlüsseln der Pakete helfen kann.
02/17/2016 15:54 meak1#4
MITM angriff mit wpe pro ist schwachsinn, weil er dir die verschlüsselten packete anzeigt,
wenn das wort MITM für mittelmann steht, dann sollte dies bedeuten, das du selbst die packete abfängst bevor sie überhaupt verschlüsselt werden.

Meistens benutzt man die selbe funktion, um seine eigenen Packete zu verschlüsseln, wenn dies jedoch nicht möglich ist, muss man diese routinen nachbauen und verstehen wie sie und woher sie diese lustigen argumente nehmen(;

Das was du meinst, mit nicht auf Client' bezogen, nennt sich Clientless, dafür musst du die komplette Verschlüsselung nachbauen, um genauso zu agieren wie der Client es tut ;D

Wie es mit Handy Apps reversen aussieht kA, bin eher der praktische typ(Runtime/Analysieren) aber gute programmierer könnten es dir auch sicher offline reversen

Der Client muss ja diese Packete entschlüsseln um sie selbst zu verstehen, diese routinen zu finden und selbst zu benutzen wie schon erwähnt ist eigentlich die leichtere Variante(;
02/18/2016 10:01 nosTa1337#5
Danke für die Antwort, klingt vernünftig.

Hatte gedacht ich könnte einfach mit ein paar Infos das Packet entschlüsseln, verstehen wie es funktioniert und dann genau so wieder verschlüsseln zum senden (mit abegeänderten Infos). Aber werde das mit dem Nachbauen mal in Angriff nehmen.