[Topic] War Commanders new encryption

06/23/2012 05:35 Morgs888#1
With this last update, WC's code has now changed and is encrypted.

After some probing this morning, it appears as though short integers and long integers have be abolished from the code, they seem to have been substituted for AoB.

Only bytes are being pushed in increments/decrements to form the array.
I'm pretty sure I can sort this part out reasonably easily.

The main thing concerning me is finding and bypassing the checker system that is seems very well hidden inside the encryption. Time will tell.

If anyone else has something to share on this feel free to comment.
06/23/2012 06:13 teddy song#2
yes, cant extract it....i tried to edit the extraction...but not working either...
06/23/2012 06:40 seth1836#3
i hope you guys can figure it out..if only i can help i really would..but i dont know about hacking things :(
06/23/2012 07:03 Morgs888#4
Ok, kix have decided to give as3crypto a try.

Here is the code for those interested.

Code:
/**
 * Crypto

package com.hurlant.crypto
{
        import com.hurlant.crypto.hash.HMAC;
        import com.hurlant.crypto.hash.IHash;
        import com.hurlant.crypto.hash.MD5;
        import com.hurlant.crypto.hash.SHA1;
        import com.hurlant.crypto.hash.SHA224;
        import com.hurlant.crypto.hash.SHA256;
        import com.hurlant.crypto.prng.ARC4;
        import com.hurlant.crypto.symmetric.AESKey;
        import com.hurlant.crypto.symmetric.BlowFishKey;
        import com.hurlant.crypto.symmetric.CBCMode;
        import com.hurlant.crypto.symmetric.CFB8Mode;
        import com.hurlant.crypto.symmetric.CFBMode;
        import com.hurlant.crypto.symmetric.CTRMode;
        import com.hurlant.crypto.symmetric.DESKey;
        import com.hurlant.crypto.symmetric.ECBMode;
        import com.hurlant.crypto.symmetric.ICipher;
        import com.hurlant.crypto.symmetric.IMode;
        import com.hurlant.crypto.symmetric.IPad;
        import com.hurlant.crypto.symmetric.ISymmetricKey;
        import com.hurlant.crypto.symmetric.IVMode;
        import com.hurlant.crypto.symmetric.NullPad;
        import com.hurlant.crypto.symmetric.OFBMode;
        import com.hurlant.crypto.symmetric.PKCS5;
        import com.hurlant.crypto.symmetric.SimpleIVMode;
        import com.hurlant.crypto.symmetric.TripleDESKey;
        import com.hurlant.crypto.symmetric.XTeaKey;
        
        import flash.utils.ByteArray;
        import com.hurlant.crypto.rsa.RSAKey;
        import com.hurlant.util.Base64;
        
        /**
         * A class to make it easy to use the rest of the framework.
         * As a side-effect, using this class will cause most of the framework
         * to be linked into your application, which is not always what you want.
         * 
         * If you want to optimize your download size, don't use this class.
         * (But feel free to read it to get ideas on how to get the algorithm you want.)
         */
        public class Crypto
        {
                private var b64:Base64; // we don't use it, but we want the swc to include it, so cheap trick.
                
                public function Crypto(){
                }
                
                /**
                 * Things that should work, among others:
                 *  "aes"
                 *  "aes-128-ecb"
                 *  "aes-128-cbc"
                 *  "aes-128-cfb"
                 *  "aes-128-cfb8"
                 *  "aes-128-ofb"
                 *  "aes-192-cfb"
                 *  "aes-256-ofb"
                 *  "blowfish-cbc"
                 *  "des-ecb"
                 *  "xtea"
                 *  "xtea-ecb"
                 *  "xtea-cbc"
                 *  "xtea-cfb"
                 *  "xtea-cfb8"
                 *  "xtea-ofb"
                 *  "rc4"
                 *  "simple-aes-cbc"
                 */
                public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
                        // split name into an array.
                        var keys:Array = name.split("-");
                        switch (keys[0]) {
                                /**
                                 * "simple" is a special case. It means:
                                 * "If using an IV mode, prepend the IV to the ciphertext"
                                 */
                                case "simple":
                                        keys.shift();
                                        name = keys.join("-");
                                        var cipher:ICipher = getCipher(name, key, pad);
                                        if (cipher is IVMode) {
                                                return new SimpleIVMode(cipher as IVMode);
                                        } else {
                                                return cipher;
                                        }
                                /**
                                 * we support both "aes-128" and "aes128"
                                 * Technically, you could use "aes192-128", but you'd
                                 * only be hurting yourself.
                                 */
                                case "aes":
                                case "aes128":
                                case "aes192":
                                case "aes256":
                                        keys.shift();
                                        if (key.length==keys[0]) {
                                                // support for "aes-128-..." and such.
                                                keys.shift();
                                        }
                                        return getMode(keys[0], new AESKey(key), pad);
                                break;
                                case "bf":
                                case "blowfish":
                                        keys.shift();
                                        return getMode(keys[0], new BlowFishKey(key), pad);
                                /**
                                 * des-ede and des-ede3 are both equivalent to des3.
                                 * the choice between 2tdes and 3tdes is made based
                                 * on the length of the key provided.
                                 */
                                case "des":
                                        keys.shift();
                                        if (keys[0]!="ede" && keys[0]!="ede3") {
                                                return getMode(keys[0], new DESKey(key), pad);
                                        }
                                        // fall-through to triple des
                                case "3des":
                                case "des3":
                                        keys.shift();
                                        return getMode(keys[0], new TripleDESKey(key), pad);
                                case "xtea":
                                        keys.shift();
                                        return getMode(keys[0], new XTeaKey(key), pad);
                                break;
                                /**
                                 * Technically, you could say "rc4-128" or whatever,
                                 * but really, the length of the key is what counts here.
                                 */
                                case "rc4":
                                        keys.shift();
                                        return new ARC4(key);
                                break;
                        }
                        return null;
                }
                
                private static function getMode(name:String, alg:ISymmetricKey, padding:IPad=null):IMode {
                        switch (name) {
                                case "ecb":
                                        return new ECBMode(alg, padding);
                                case "cfb":
                                        return new CFBMode(alg, padding);
                                case "cfb8":
                                        return new CFB8Mode(alg, padding);
                                case "ofb":
                                        return new OFBMode(alg, padding);
                                case "ctr":
                                        return new CTRMode(alg, padding);
                                case "cbc":
                                default:
                                        return new CBCMode(alg, padding);
                        }
                }
                
                /**
                 * Things that should work:
                 * "md5"
                 * "sha"
                 * "sha1"
                 * "sha224"
                 * "sha256"
                 */
                public static function getHash(name:String):IHash {
                        switch(name) {
                                case "md5":
                                        return new MD5;
                                case "sha": // let's hope you didn't mean sha-0
                                case "sha1":
                                        return new SHA1;
                                case "sha224":
                                        return new SHA224;
                                case "sha256":
                                        return new SHA256;
                        }
                        return null;
                }
                
                /**
                 * Things that should work:
                 * "sha1"
                 * "md5-64"
                 * "hmac-md5-96"
                 * "hmac-sha1-128"
                 * "hmac-sha256-192"
                 * etc.
                 */
                public static function getHMAC(name:String):HMAC {
                        var keys:Array = name.split("-");
                        if (keys[0]=="hmac") keys.shift();
                        var bits:uint = 0;
                        if (keys.length>1) {
                                bits = parseInt(keys[1]);
                        }
                        return new HMAC(getHash(keys[0]), bits);
                }
                
                public static function getPad(name:String):IPad {
                        switch(name) {
                                case "null":
                                        return new NullPad;
                                case "pkcs5":
                                default:
                                        return new PKCS5;
                        }
                }
                
                /** mostly useless.
                 */
                public static function getRSA(E:String, M:String):RSAKey {
                        return RSAKey.parseKey(E,M);
                }
        }
}
06/23/2012 08:42 x1jester#5
thanks.. will we be able to un encrypt their flash with that?
06/23/2012 11:34 snipercannon#6
try it on a bummy account
06/23/2012 17:03 Azathoth1#7
Sigh. I knew this day was coming. Ok so now we have to deal with as3crypto, and that isn't an easy task if the implemented it properly. as3crypto utilizes a public key and a private key, the flash file is encrypted using the private key and checked against the public key once it is sent to a users computer. The public key is they md5 hash of the file, which means at that point ANY alteration to the file will change the hash values.

Also if they added protected domain to the as3crypto as well, it will not allow you to map the file locally, it will only work if it is coming from the WC server.

Now that part can be tricked if you know how to use DNS rebinding, but lets face it, that is a pain in the ass, and makes the hack useless on a mass scale. So if anyone else has any ideas, feel free to share them. Maybe I am missing something.
06/23/2012 23:39 Morgs888#8
Quote:
Originally Posted by Azathoth1 View Post
Sigh. I knew this day was coming. Ok so now we have to deal with as3crypto, and that isn't an easy task if the implemented it properly. as3crypto utilizes a public key and a private key, the flash file is encrypted using the private key and checked against the public key once it is sent to a users computer. The public key is they md5 hash of the file, which means at that point ANY alteration to the file will change the hash values.

Also if they added protected domain to the as3crypto as well, it will not allow you to map the file locally, it will only work if it is coming from the WC server.

Now that part can be tricked if you know how to use DNS rebinding, but lets face it, that is a pain in the ass, and makes the hack useless on a mass scale. So if anyone else has any ideas, feel free to share them. Maybe I am missing something.
Your not missing anything. That's it in a nutshell.

Did someone say private key? I wonder what this one is referring to? Lol.

Code:
     coerce              QName(PackageNamespace("flash.utils"), "ByteArray")
     setlocal2

     getlocal            8
     not
     iffalse             L42

     getlocal2
     pushstring          [COLOR="Red"]"kixeyekey"[/COLOR]
     callpropvoid        QName(PackageNamespace(""), "writeUTF"), 1

L42:
     findpropstrict      QName(PackageNamespace("521423242337123423632234"), "521423702383123423632234")
     getlocal2
     constructprop
06/24/2012 10:32 markling#9
Anything that is created by human can be cracked by human. Don't make it sound like it is from some alien technology that is impenetrable. Maybe we need other hackers from other games to come in and help us with this. :)
06/24/2012 11:27 soulblazer91#10
This is going to sound noobish... but is there anyway to send a false md5 hash value when they test the file to the public key?
06/24/2012 19:26 enorth#11
Lol spending a lot of time on a free game thats kind of crap since the update anyway. Id rather see you guys switch to Battle Pirates and help out hellion and rokon etc.
06/25/2012 14:35 Tageteg#12
It needs to be unencrypted at runtime before execution anyway, this means it needs to be decrypted at some point :)
06/25/2012 14:35 NotiRod#13
We want to work on repairing untis .. not for upgrading now .. just if some one know how he editting repeiring time .. that's will be amazing .. and i can the Complex game files .. But the amendment at the time of repair will suffice .. We will focus on the repair ^^
06/25/2012 14:55 jazzaa561#14
repairs would be brill thats all i need
06/25/2012 16:58 markling#15
Quote:
Originally Posted by enorth View Post
Lol spending a lot of time on a free game thats kind of crap since the update anyway. Id rather see you guys switch to Battle Pirates and help out hellion and rokon etc.
once a wc, always a wc. :)

Quote:
Originally Posted by Tageteg View Post
It needs to be unencrypted at runtime before execution anyway, this means it needs to be decrypted at some point :)
did i hear a melody of hope? :)