WMCTF2024 RE wp

AK了逆向

 

一、easyAndroid

二血

思路:.so层的代码逻辑极其混乱,简直无从下手,不过经过分析后发现题目采用了单字节加密,可以直接爆破出flag
解题流程如下:
尝试trace跟踪一下字符串
这里使用unidbg对输入字符串地址下内存访问断点,跟踪log如下:
[12:41:03 810] Memory READ at 0x400e1000, data size = 8, data value = 0x3333323231313030, PC=RX@0x4021cbf4[libc.so]0x1cbf4, LR=RX@0x40038338[libeasyandroid.so]0x38338 [12:41:03 811] Memory READ at 0x400e1008, data size = 8, data value = 0x3737363635353434, PC=RX@0x4021cbf4[libc.so]0x1cbf4, LR=RX@0x40038338[libeasyandroid.so]0x38338 [12:41:03 811] Memory READ at 0x400e1010, data size = 8, data value = 0x6262616139393838, PC=RX@0x4021cbf4[libc.so]0x1cbf4, LR=RX@0x40038338[libeasyandroid.so]0x38338 [12:41:03 811] Memory READ at 0x400e1018, data size = 8, data value = 0x6666656564646363, PC=RX@0x4021cbf4[libc.so]0x1cbf4, LR=RX@0x40038338[libeasyandroid.so]0x38338 [12:41:03 811] Memory READ at 0x400e1020, data size = 8, data value = 0x6e736c74, PC=RX@0x4021cbf4[libc.so]0x1cbf4, LR=RX@0x40038338[libeasyandroid.so]0x38338 [12:41:03 811] Memory READ at 0x400e1010, data size = 4, data value = 0x39393838, PC=RX@0x40021c00[libeasyandroid.so]0x21c00, LR=RX@0x40038348[libeasyandroid.so]0x38348 [12:41:03 811] Memory READ at 0x400e1020, data size = 4, data value = 0x6e736c74, PC=RX@0x40021c00[libeasyandroid.so]0x21c00, LR=RX@0x40038348[libeasyandroid.so]0x38348 [12:41:03 811] Memory READ at 0x400e1008, data size = 4, data value = 0x35353434, PC=RX@0x40021c00[libeasyandroid.so]0x21c00, LR=RX@0x40038348[libeasyandroid.so]0x38348 [12:41:03 811] Memory READ at 0x400e1000, data size = 4, data value = 0x31313030, PC=RX@0x40021c00[libeasyandroid.so]0x21c00, LR=RX@0x40038348[libeasyandroid.so]0x38348 [12:41:03 812] Memory READ at 0x400e1000, data size = 8, data value = 0x3333323231313030, PC=RX@0x4021c180[libc.so]0x1c180, LR=RX@0x40021d88[libeasyandroid.so]0x21d88 [12:41:03 812] Memory READ at 0x400e1008, data size = 8, data value = 0x3737363635353434, PC=RX@0x4021c180[libc.so]0x1c180, LR=RX@0x40021d88[libeasyandroid.so]0x21d88 [12:41:03 812] Memory READ at 0x400e1010, data size = 8, data value = 0x6262616139393838, PC=RX@0x4021c180[libc.so]0x1c180, LR=RX@0x40021d88[libeasyandroid.so]0x21d88 [12:41:03 812] Memory READ at 0x400e1018, data size = 8, data value = 0x6666656564646363, PC=RX@0x4021c180[libc.so]0x1c180, LR=RX@0x40021d88[libeasyandroid.so]0x21d88 [12:41:03 812] Memory READ at 0x400e1014, data size = 8, data value = 0x6464636362626161, PC=RX@0x4021c198[libc.so]0x1c198, LR=RX@0x40021d88[libeasyandroid.so]0x21d88 [12:41:03 812] Memory READ at 0x400e101c, data size = 8, data value = 0x6e736c7466666565, PC=RX@0x4021c198[libc.so]0x1c198, LR=RX@0x40021d88[libeasyandroid.so]0x21d88

 

定位到地址 偏移为 0x21D88的函数(0x21BB8),在函数首部下断点,使用unidbg调试一下,经过调试,我们可以发现一些端倪,我们可以发现,每次进入0x21BB8的时候 x1寄存器的变化如下(输入字符串为 "abcdefghijklmnopqrstuvwxyz0123456789")
abcdefghijklmnopqrstuvwxyz0123456789 e2 be e3 ed e3 e3 e2 bf e3 b9 bf e2 bf bb bf e2 bf bf e2bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf abcdefghijklmnopqrstuvwxyz0123456789 99bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf \x99 \x999bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf bcdefghijklmnopqrstuvwxyz0123456789 02bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf 9902e3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf \x02 \x99\0202e3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf cdefghijklmnopqrstuvwxyz0123456789 4602e3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf 990246ede3e3e2bfe3b9bfe2bfbbbfe2bfbf \x46 \x99\x02\x46246ede3e3e2bfe3b9bfe2bfbbbfe2bfbf defghijklmnopqrstuvwxyz0123456789 bdF246ede3e3e2bfe3b9bfe2bfbbbfe2bfbf 990246bde3e3e2bfe3b9bfe2bfbbbfe2bfbf \xbd \x99\x02\x46\xBD46bde3e3e2bfe3b9bfe2bfbbbfe2bfbf efghijklmnopqrstuvwxyz0123456789 9eF.46bde3e3e2bfe3b9bfe2bfbbbfe2bfbf 990246bd9ee3e2bfe3b9bfe2bfbbbfe2bfbf \x9e \x99\x02\x46\xbd\x9e6bd9ee3e2bfe3b9bfe2bfbbbfe2bfbf fghijklmnopqrstuvwxyz0123456789 3cF\xBD\x9E6bd9ee3e2bfe3b9bfe2bfbbbfe2bfbf 990246bd9e3ce2bfe3b9bfe2bfbbbfe2bfbf \x3c \x99\x02\x46\xBD\x9E\x3Cbd9e3ce2bfe3b9bfe2bfbbbfe2bfbf ghijklmnopqrstuvwxyz0123456789 42F\xBD\x9E\x3Cbd9e3ce2bfe3b9bfe2bfbbbfe2bfbf ... ... ... 9e5112e8ca6d1700271280763df544927f776aeed3f0e8abd16f510c79dd62bed1fe11bc

 

通过不断的调试,更换输入字符串,我们可以猜测出,这是一个有关字符串处理的函数,加密过程中存在一个特定的key: e2bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf,同时程序采用了单字节加密的方法且加密的结果与字符所在的序列有关系,明白了这些点之后,我们可以尝试爆破flag。
这里我先得到了所有字符("0123456789wertyuiopasdfghjklzxcvbnm@!_{}-")的加密后的结果,由于加密结果与字符所在字符串序列有关,因此我得到了所有字符在所有序列的加密结果,之后直接暴力循环映射即可
Exp:
用unidbg获取所有字符在所有序列的解密结果:
package com.WMCTF; import com.github.unidbg.Emulator; import com.github.unidbg.arm.HookStatus; import com.github.unidbg.AndroidEmulator; import com.github.unidbg.Module; import com.github.unidbg.Symbol; import com.github.unidbg.debugger.BreakPointCallback; import com.github.unidbg.hook.hookzz.*; import com.github.unidbg.debugger.DebuggerType; import com.github.unidbg.linux.android.AndroidEmulatorBuilder; import com.github.unidbg.linux.android.AndroidResolver; import com.github.unidbg.linux.android.dvm.DalvikModule; import com.github.unidbg.linux.android.dvm.DvmClass; import com.github.unidbg.linux.android.dvm.DvmObject; import com.github.unidbg.linux.android.dvm.VM; import com.github.unidbg.memory.Memory; import com.github.unidbg.virtualmodule.android.AndroidModule; import java.io.File; import com.github.unidbg.arm.context.Arm64RegisterContext; public class soeasy { public final AndroidEmulator emulator; public final VM vm; public final Memory memory; public final Module module; DvmClass cNative; public int hitCount = 0; public soeasy(){ emulator = AndroidEmulatorBuilder.for64Bit().build(); memory = emulator.getMemory(); memory.setLibraryResolver(new AndroidResolver(23)); emulator.getSyscallHandler().setEnableThreadDispatcher(true); vm = emulator.createDalvikVM(); // vm.setVerbose(true); new AndroidModule(emulator,vm).register(memory); DalvikModule dalvikModule = vm.loadLibrary(new File("D:\\BTools\\APK_EASY_TOOL\\APK Easy Tool v1.60 Portable\\1-Decompiled APKs\\easyAndroid\\lib\\arm64-v8a\\libeasyandroid.so"), true); module = dalvikModule.getModule(); vm.callJNI_OnLoad(emulator,module); } public void bc(){ hitCount = 0; } public static void main(String[] args){ soeasy mainActivity = new soeasy(); String mp = "0123456789wertyuiopasdfghjklzxcvbnm@!_{}-"; for (int i=0;i<mp.length();i++){ char ch = mp.charAt(i); String x = String.valueOf(ch).repeat(36); System.out.printf(","); mainActivity.debugger(x); mainActivity.bc(); } } private void debugger(String x) { // emulator.traceCode(module.base + 0x0000000000187D0,module.base + 0x0000000000B3F00); // emulator.traceRead(0x400e1000,0x400e1020); emulator.attach(DebuggerType.CONSOLE).addBreakPoint(module.base + 0x21bb8, new BreakPointCallback() { @Override public boolean onHit(Emulator<?> emulator, long address) { hitCount+=1; if(hitCount !=17+36*5+2){ return true; }else{ Arm64RegisterContext context = emulator.getContext(); long x1Value = context.getXLong(1); Memory memory = emulator.getMemory(); String read_data = memory.pointer(x1Value).getString(0).substring(0,72); // System.out.printf("->%x\n",x1Value); System.out.println(read_data); return true; } } }); cNative = vm.resolveClass("com.s0rry.easyandroid.MainActivity"); // String ang0 = "abcdefghijklmnopqrstuvwxyz0123456789"; DvmObject<?> strRc = cNative.callStaticJniMethodObject(emulator,"aaa(Ljava/lang/String;)Z",x); } }

 

python暴力映射:
mp1 = "0123456789wertyuiopasdfghjklzxcvbnm@!_{}-" mp2 = [ bytes.fromhex("c85015e9cb6a15003a11d6753ce84097762577bcd7f1ebb6d96754047add67ecd8ab14bd") ,bytes.fromhex("c95114e8ca6b14013b10d7743de94196772476bdd6f0eab7d86655057bdc66edd9aa15bc") ,bytes.fromhex("ca5217ebc96817023813d4773eea4295742775bed5f3e9b4db65560678df65eedaa916bf") ,bytes.fromhex("cb5316eac86916033912d5763feb4394752674bfd4f2e8b5da64570779de64efdba817be") ,bytes.fromhex("cc5411edcf6e11043e15d27138ec4493722173b8d3f5efb2dd6350007ed963e8dcaf10b9") ,bytes.fromhex("cd5510ecce6f10053f14d37039ed4592732072b9d2f4eeb3dc6251017fd862e9ddae11b8") ,bytes.fromhex("ce5613efcd6c13063c17d0733aee4691702371bad1f7edb0df6152027cdb61eadead12bb") ,bytes.fromhex("cf5712eecc6d12073d16d1723bef4790712270bbd0f6ecb1de6053037dda60ebdfac13ba") ,bytes.fromhex("c0581de1c3621d083219de7d34e0489f7e2d7fb4dff9e3bed16f5c0c72d56fe4d0a31cb5") ,bytes.fromhex("c1591ce0c2631c093318df7c35e1499e7f2c7eb5def8e2bfd06e5d0d73d46ee5d1a21db4") ,bytes.fromhex("8f1752ae8c2d52477d5691327baf07d0316230fb90b6acf19e2013433d9a20ab9fec53fa") ,bytes.fromhex("9d0540bc9e3f40556f44832069bd15c2237022e982a4bee38c3201512f8832b98dfe41e8") ,bytes.fromhex("8a1257ab89285742785394377eaa02d5346735fe95b3a9f49b251646389f25ae9ae956ff") ,bytes.fromhex("8c1451ad8f2e51447e55923178ac04d3326133f893b5aff29d2310403e9923a89cef50f9") ,bytes.fromhex("81195ca082235c4973589f3c75a109de3f6c3ef59eb8a2ff902e1d4d33942ea591e25df4") ,bytes.fromhex("8d1550ac8e2f50457f54933079ad05d2336032f992b4aef39c2211413f9822a99dee51f8") ,bytes.fromhex("91094cb092334c5963488f2c65b119ce2f7c2ee58ea8b2ef803e0d5d23843eb581f24de4") ,bytes.fromhex("970f4ab694354a5f654e892a63b71fc8297a28e388aeb4e986380b5b258238b387f44be2") ,bytes.fromhex("881055a98b2a55407a5196357ca800d7366537fc97b1abf6992714443a9d27ac98eb54fd") ,bytes.fromhex("990144b89a3b44516b4087246db911c6277426ed86a0bae7883605552b8c36bd89fa45ec") ,bytes.fromhex("8b1356aa88295643795295367fab03d4356634ff94b2a8f59a241747399e24af9be857fe") ,bytes.fromhex("9c0441bd9f3e41546e45822168bc14c3227123e883a5bfe28d3300502e8933b88cff40e9") ,bytes.fromhex("9e0643bf9d3c43566c4780236abe16c1207321ea81a7bde08f3102522c8b31ba8efd42eb") ,bytes.fromhex("9f0742be9c3d42576d4681226bbf17c0217220eb80a6bce18e3003532d8a30bb8ffc43ea") ,bytes.fromhex("90084db193324d5862498e2d64b018cf2e7d2fe48fa9b3ee813f0c5c22853fb480f34ce5") ,bytes.fromhex("920a4fb391304f5a604b8c2f66b21acd2c7f2de68dabb1ec833d0e5e20873db682f14ee7") ,bytes.fromhex("930b4eb290314e5b614a8d2e67b31bcc2d7e2ce78caab0ed823c0f5f21863cb783f04fe6") ,bytes.fromhex("940c49b59736495c664d8a2960b41ccb2a792be08badb7ea853b085826813bb084f748e1") ,bytes.fromhex("821a5fa381205f4a705b9c3f76a20add3c6f3df69dbba1fc932d1e4e30972da692e15ef7") ,bytes.fromhex("80185da183225d4872599e3d74a008df3e6d3ff49fb9a3fe912f1c4c32952fa490e35cf5") ,bytes.fromhex("9b0346ba98394653694285266fbb13c4257624ef84a2b8e58a340757298e34bf8bf847ee") ,bytes.fromhex("8e1653af8d2c53467c5790337aae06d1306331fa91b7adf09f2112423c9b21aa9eed52fb") ,bytes.fromhex("9a0247bb99384752684384276eba12c5247725ee85a3b9e48b350656288f35be8af946ef") ,bytes.fromhex("960e4bb795344b5e644f882b62b61ec9287b29e289afb5e887390a5a248339b286f54ae3") ,bytes.fromhex("950d48b49637485d674c8b2861b51dca2b782ae18aacb6eb843a095927803ab185f649e0") ,bytes.fromhex("b8206599bb1a65704a61a6054c9830e7065507cca7819bc6a91724740aad179ca8db64cd") ,bytes.fromhex("d94104f8da7b04112b00c7642df95186673466adc6e0faa7c87645156bcc76fdc9ba05ac") ,bytes.fromhex("a73f7a86a4057a6f557eb91a53872ff8194a18d3b89e84d9b6083b6b15b20883b7c47bd2") ,bytes.fromhex("831b5ea280215e4b715a9d3e77a30bdc3d6e3cf79cbaa0fd922c1f4f31962ca793e05ff6") ,bytes.fromhex("851d58a48627584d775c9b3871a50dda3b683af19abca6fb942a194937902aa195e659f0") ,bytes.fromhex("d54d08f4d677081d270ccb6821f55d8a6b386aa1caecf6abc47a491967c07af1c5b609a0")] enc = bytes.fromhex("9e 51 12 e8 ca 6d 17 00 27 12 80 76 3d f5 44 92 7f 77 6a ee d3 f0 e8 ab d1 6f 51 0c 79 dd 62 be d1 fe 11 bc") flag = "" for i in range(len(enc)): x = enc[i] for j in range(len(mp2)): if mp2[j][i] == x: flag += mp1[j] print(flag)

 

得到flag:
WMCTF{f1711720-3f31-459b-b413-8858305b9e51}
Ps: 其实这里直接用unidbg 的hook功能直接爆破就完事了,但我不是很熟悉unidbg上的hook,于是才采用了这种方法,借助python脚本完成爆破

二、rustdroid

Rust语言编写的.so文件,没有去符号,加密逻辑也比较简单,直接z3求解即可

 

from struct import unpack,pack enstream = [0x66, 0xD1, 0xBB, 0x64, 0x21, 0x57, 0x10, 0x3F, 0xB6, 0xFE, 0x6D, 0xD2, 0x7F, 0xC6, 0x9D, 0xB4, 0xC3, 0x71, 0xE9, 0x5F, 0xF3, 0xA1, 0x2E, 0x34, 0xB2, 0xB3, 0xCA, 0x13, 0xB8, 0xA2, 0xC2, 0x82, 0xB7, 0x95, 0x68, 0x23, 0xA7, 0x41, 0xD5, 0x3C, 0x72, 0x63, 0x3E, 0x19, 0x06, 0x2F, 0x2C, 0xB9, 0xF1, 0xDB, 0x94, 0x1C, 0x56, 0xA3, 0x5E, 0x3B, 0xCE, 0x93, 0xE6, 0x32, 0xB5, 0x49, 0x6A, 0x8A, 0x7C, 0xAA, 0x9F, 0xD6, 0x50, 0xFA, 0x80, 0x15, 0x8E, 0x5A, 0xF8, 0x03, 0x84, 0xE4, 0x98, 0x59, 0x43, 0x67, 0x0E, 0xCB, 0x5D, 0x5C, 0xD4, 0x40, 0xFD, 0xC0, 0x20, 0x70, 0x75, 0x1F, 0x2B, 0xEF, 0x08, 0x8B, 0x2D, 0x09, 0xC7, 0x86, 0x92, 0x28, 0xF7, 0x6F, 0x00, 0x8F, 0x45, 0x85, 0x35, 0xD9, 0xAE, 0x90, 0x14, 0xC5, 0x60, 0x58, 0xD8, 0x27, 0x3A, 0x17, 0x12, 0x76, 0xE1, 0xDF, 0x8D, 0x6C, 0xE0, 0xF4, 0x31, 0x1A, 0xBA, 0xAC, 0xE8, 0xAF, 0x9C, 0x25, 0xAD, 0x54, 0x91, 0xCD, 0x11, 0xEC, 0xE2, 0x01, 0x38, 0x47, 0x7B, 0x22, 0x1B, 0x02, 0xE5, 0xBE, 0xBD, 0x18, 0xA0, 0xC4, 0x99, 0x83, 0xC8, 0xCF, 0x96, 0x46, 0x3D, 0xBF, 0x87, 0xA9, 0xD3, 0xF6, 0x55, 0x24, 0x48, 0x78, 0xE3, 0xD7, 0xF5, 0x07, 0x65, 0xB0, 0xA6, 0x4D, 0x77, 0xFF, 0xA4, 0x1E, 0x9A, 0x4C, 0x30, 0x9E, 0x36, 0xDA, 0x89, 0xEE, 0x52, 0xAB, 0x9B, 0x0A, 0xDD, 0x53, 0x05, 0xEB, 0x51, 0xFB, 0xF9, 0x4B, 0x0F, 0x61, 0x69, 0xDC, 0xA5, 0x79, 0x7E, 0xED, 0x8C, 0xD0, 0xF2, 0x4F, 0x04, 0x33, 0x7A, 0x4E, 0x97, 0x74, 0x62, 0x0B, 0x1D, 0x2A, 0x16, 0xB1, 0x7D, 0x44, 0x42, 0xBC, 0x88, 0xF0, 0x4A, 0x81, 0x29, 0x39, 0xEA, 0x6E, 0xC9, 0x37, 0xE7, 0x5B, 0xFC, 0x0D, 0x73, 0xA8, 0x26, 0x6B, 0xCC, 0x0C, 0xDE, 0xC1] key = [0x77, 0x88, 0x99, 0x66] assert len(enstream)==256 assert len(key) == 4 def Q2b(m):     return pack("<Q",m) def D2b(m):     return pack("<I",m) enc = Q2b(0x4E4FCE594215BA1F)  + Q2b(0xC745BAE69BFD994) + Q2b(0x87081E9C7F8AFCC0) + Q2b(0x2BB08F87F5646BF5) + D2b(0x29FF53E2) idx2 = 0 v11 = 0 from z3 import * s = Solver() inp = [BitVec(f'inp[{i}]', 8) for i in range(36)] for idx in range(36):     idx2+=1     v13 = (LShR(inp[idx],1) | (inp[idx]<<7)) ^ 0xef     v14 = enstream[idx2]     v11 += v14     v11 &= 0xff         x1 = ((LShR(v13,2) | (v13<<6)) ^ 0xBE)     v13 = (LShR(x1 ,3)  | (x1 << 5)) ^ 0xAD     enstream[idx2] = enstream[v11]     enstream[v11] = v14         x2 = (LShR(v13,4) | (v13 << 4)) ^ 0xDE     x = key[idx&3] ^ enstream[(enstream[idx2]+v14) & 0xff] ^ (LShR((x2),5) | (x2 << 3))     s.add(x == enc[idx]) print(s.check()) res = s.model() print("WMCTF{",end = "") for i in range(0,36):     print(chr(res[inp[i]].as_long()),end = "") print("}")

 

Flag即为:

WMCTF{2a04aed7-e736-43c4-80a7-f6ed28de34eb}

 

 

三、ez_learn

题目作者通过控制堆栈修改程序的控制流来达到了代码混淆的作用,IDA静态分析不成功,但实际上只要稍微patch一下,即可还原伪代码:
如图,把阴影部分的汇编全部nop掉,让IDA重新分析一下,即可还原伪代码
 

 

 

接下来是一组加密操作,这组加密操作乍一看有些棘手,不过我们可以把每个函数拆解开来,合并起来一块分析。最后可以化简出加密操作与解密操作的流程:
x = 0x12 ^ inp[i+1] ^ inp[i+2] ^ inp[i+3] 加密操作: inp[i+4] = Ror(sbox[x],8) ^ Ror(sbox[x],14) ^ Ror(sbox[x],22) ^ Ror(sbox[x],30) ^ sbox[x] ^ 0x34343434 ^ inp[i] 解密操作: inp[i] = 0x34343434 ^ inp[i+4] ^ Ror(sbox[x],8) ^ Ror(sbox[x],14) ^ Ror(sbox[x],22) ^ Ror(sbox[x],30) ^ sbox[x]

 

 
Exp:
from struct import pack f_N_a1 = [0xFF055A4E, 0x529CC66A, 0x18E3DA43, 0x0465E0E4, 0xFD58BCB6, 0x2C4E97EC, 0x48A234B8, 0x842EE158, 0x7C55AA74, 0x9BEF3AFE, 0x8779FE09, 0x1685B020, 0x95794366, 0x7AC1501F, 0x7FB0D538, 0x38980B16, 0x33D37C51, 0x5FAACC9B, 0xD47351CC, 0x48CEEAB2, 0x7C296054, 0xF163D1EF, 0x0DDB1E47, 0x9DA4F767, 0xFAF4B1E0, 0xFC5A5FB1, 0xD3FED672, 0x264B1A75, 0xEFA7E6C4, 0x94B344A4, 0xED19375F, 0x58AA0CED] s_box = [0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48] magic= 0 inp = [0] * 36 inp[35] = 0xc676e86f; inp[34] = 0xad67e8f8; inp[33] = 0xca9db9ac; inp[32] = 0xb1ae068e; def Ror(val,r): return (val >> r) | (val << (32 - r)) & 0xffffffff for i in range(31,-1,-1): idx = 0x12121212 ^ inp[i+3] ^ inp[i+2] ^ inp[i+1] ^ f_N_a1[i] sl = s_box[idx&0xff] sm0 = s_box[(idx>>8)&0xff] sm1 = s_box[(idx>>16)&0xff] sh = s_box[(idx>>24)&0xff] s = sl + (sm0<<8) + (sm1 << 16) + (sh << 24) inp[i] = inp[i+4] ^ 0x34343434 ^ Ror(s,8) ^ Ror(s,14) ^ Ror(s,22) ^ Ror(s,30) ^ s flag = b"" for i in range(4): flag +=pack("<I",inp[i]) print(flag) from struct import pack f_N_a1 = [0xFF055A4E, 0x529CC66A, 0x18E3DA43, 0x0465E0E4, 0xFD58BCB6, 0x2C4E97EC, 0x48A234B8, 0x842EE158, 0x7C55AA74, 0x9BEF3AFE, 0x8779FE09, 0x1685B020, 0x95794366, 0x7AC1501F, 0x7FB0D538, 0x38980B16, 0x33D37C51, 0x5FAACC9B, 0xD47351CC, 0x48CEEAB2, 0x7C296054, 0xF163D1EF, 0x0DDB1E47, 0x9DA4F767, 0xFAF4B1E0, 0xFC5A5FB1, 0xD3FED672, 0x264B1A75, 0xEFA7E6C4, 0x94B344A4, 0xED19375F, 0x58AA0CED] s_box = [0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48] magic= 0 inp = [0] * 36 inp[35] = 0xD51B0298; inp[34] = 0xD827C6D3; inp[33] = 0x31A5A335; inp[32] = 0x893A7A66; def Ror(val,r): return (val >> r) | (val << (32 - r)) & 0xffffffff for i in range(31,-1,-1): idx = 0x12121212 ^ inp[i+3] ^ inp[i+2] ^ inp[i+1] ^ f_N_a1[i] sl = s_box[idx&0xff] sm0 = s_box[(idx>>8)&0xff] sm1 = s_box[(idx>>16)&0xff] sh = s_box[(idx>>24)&0xff] s = sl + (sm0<<8) + (sm1 << 16) + (sh << 24) inp[i] = inp[i+4] ^ 0x34343434 ^ Ror(s,8) ^ Ror(s,14) ^ Ror(s,22) ^ Ror(s,30) ^ s for i in range(4): flag +=pack("<I",inp[i]) print(flag)

 

flag即为:
WMCTF{CRC32andAnti_IS_SO_EASY!!}

四、re1

又是Android题目,题目作者通过hook系统函数,实现了魔改的xtea加密,此外需要注意的是,真正的检查函数在这里:
作者通过hook printf,scanf,strftime,fgetws这四个系统函数实现了魔改的xtea加密,同时hook strlen系统函数实现了简单的异或运算:
xtea:
简单的异或运算:
Exp:
from ctypes import * def encrypt(v, key): v0, v1 = c_uint32(v[0]), c_uint32(v[1]) delta = 0x5EEFEF3 total = c_uint32(0) for i in range(66): v0.value += (((v1.value << 6) ^ (v1.value >> 6)) + v1.value) ^ (total.value + key[total.value & 3]) total.value -= delta v1.value += (((v0.value << 6) ^ (v0.value >> 6)) + v0.value) ^ (total.value + key[((total.value&0xff)>>6)]) return v0.value, v1.value def decrypt(v, key): v0, v1 = c_uint32(v[0]), c_uint32(v[1]) delta = 0x5EEFEF3 total = c_uint32(0-(delta * 66)) for i in range(66): v1.value -= (((v0.value << 6) ^ (v0.value >> 6)) + v0.value) ^ (total.value + key[((total.value&0xff) >>6)]) total.value += delta v0.value -= (((v1.value << 6) ^ (v1.value >> 6)) + v1.value) ^ (total.value + key[total.value & 3]) return v0.value, v1.value def xtea(inp:bytes,key:bytes): from struct import pack,unpack k = unpack("<4I",key) inp_len = len(inp) // 4 value = unpack(f"<{inp_len}I",inp) res = b"" for i in range(0,inp_len,2): v = [value[i],value[i+1]] # x = encrypt(v,k) x = decrypt(v,k) res += pack("<2I",*x) return res # cip = b"00112233445566778899aabbccddeeff" cip = bytes([0xD2, 0x5F, 0xC0, 0xEF, 0x5E, 0x62, 0x78, 0x93, 0xA0, 0x41, 0x1F, 0x84, 0x4A, 0x5F, 0xD0, 0x06, 0x9A, 0x8F, 0x89, 0xDC, 0xFC, 0x7C, 0xAA, 0x21, 0x0B, 0xFB, 0x29, 0x42, 0x8B, 0x2B, 0xE5, 0x31]) key = bytes([0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11]) ret = xtea(cip,key) ret = bytearray(ret) for i in range(len(ret)): ret[i] ^= i^0x5a print(bytes(ret))

 

flag为: WMCTF{b86d69bbeedeccb9257782534}

__EOF__

本文作者_TLSN
本文链接https://www.cnblogs.com/lordtianqiyi/p/18404198.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TLSN  阅读(671)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示