WMCTF2024 RE wp

打印 上一主题 下一主题

主题 1878|帖子 1878|积分 5638

AK了逆向

 
一、easyAndroid

二血
思绪:.so层的代码逻辑极其杂乱,简直无从下手,不过经过分析后发现标题采用了单字节加密,可以直接爆破出flag解题流程如下:实验trace跟踪一下字符串这里使用unidbg对输入字符串地址下内存访问断点,跟踪log如下:
  1. [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
  2. [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
  3. [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
  4. [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
  5. [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
  6. [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
  7. [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
  8. [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
  9. [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
  10. [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
  11. [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. [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
  13. [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
  14. [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
  15. [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")
  1. abcdefghijklmnopqrstuvwxyz0123456789
  2. e2
  3. be
  4. e3
  5. ed
  6. e3
  7. e3
  8. e2
  9. bf
  10. e3
  11. b9
  12. bf
  13. e2
  14. bf
  15. bb
  16. bf
  17. e2
  18. bf
  19. bf
  20. e2bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  21. abcdefghijklmnopqrstuvwxyz0123456789
  22. 99bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  23. \x99
  24. \x999bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  25. bcdefghijklmnopqrstuvwxyz0123456789
  26. 02bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  27. 9902e3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  28. \x02
  29. \x99\0202e3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  30. cdefghijklmnopqrstuvwxyz0123456789
  31. 4602e3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  32. 990246ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  33. \x46
  34. \x99\x02\x46246ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  35. defghijklmnopqrstuvwxyz0123456789
  36. bdF246ede3e3e2bfe3b9bfe2bfbbbfe2bfbf
  37. 990246bde3e3e2bfe3b9bfe2bfbbbfe2bfbf
  38. \xbd
  39. \x99\x02\x46\xBD46bde3e3e2bfe3b9bfe2bfbbbfe2bfbf
  40. efghijklmnopqrstuvwxyz0123456789
  41. 9eF.46bde3e3e2bfe3b9bfe2bfbbbfe2bfbf
  42. 990246bd9ee3e2bfe3b9bfe2bfbbbfe2bfbf
  43. \x9e
  44. \x99\x02\x46\xbd\x9e6bd9ee3e2bfe3b9bfe2bfbbbfe2bfbf
  45. fghijklmnopqrstuvwxyz0123456789
  46. 3cF\xBD\x9E6bd9ee3e2bfe3b9bfe2bfbbbfe2bfbf
  47. 990246bd9e3ce2bfe3b9bfe2bfbbbfe2bfbf
  48. \x3c
  49. \x99\x02\x46\xBD\x9E\x3Cbd9e3ce2bfe3b9bfe2bfbbbfe2bfbf
  50. ghijklmnopqrstuvwxyz0123456789
  51. 42F\xBD\x9E\x3Cbd9e3ce2bfe3b9bfe2bfbbbfe2bfbf
  52. ...
  53. ...
  54. ...
  55. 9e5112e8ca6d1700271280763df544927f776aeed3f0e8abd16f510c79dd62bed1fe11bc
复制代码
 
通过不断的调试,更换输入字符串,我们可以猜测出,这是一个有关字符串处理惩罚的函数,加密过程中存在一个特定的key: e2bee3ede3e3e2bfe3b9bfe2bfbbbfe2bfbf,同时程序采用了单字节加密的方法且加密的效果与字符所在的序列有关系,明白了这些点之后,我们可以实验爆破flag。这里我先得到了全部字符("0123456789wertyuiopasdfghjklzxcvbnm@!_{}-")的加密后的效果,由于加密效果与字符所在字符串序列有关,因此我得到了全部字符在全部序列的加密效果,之后直接暴力循环映射即可Exp:用unidbg获取全部字符在全部序列的解密效果:
  1. package com.WMCTF;
  2. import com.github.unidbg.Emulator;
  3. import com.github.unidbg.arm.HookStatus;
  4. import com.github.unidbg.AndroidEmulator;
  5. import com.github.unidbg.Module;
  6. import com.github.unidbg.Symbol;
  7. import com.github.unidbg.debugger.BreakPointCallback;
  8. import com.github.unidbg.hook.hookzz.*;
  9. import com.github.unidbg.debugger.DebuggerType;
  10. import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
  11. import com.github.unidbg.linux.android.AndroidResolver;
  12. import com.github.unidbg.linux.android.dvm.DalvikModule;
  13. import com.github.unidbg.linux.android.dvm.DvmClass;
  14. import com.github.unidbg.linux.android.dvm.DvmObject;
  15. import com.github.unidbg.linux.android.dvm.VM;
  16. import com.github.unidbg.memory.Memory;
  17. import com.github.unidbg.virtualmodule.android.AndroidModule;
  18. import java.io.File;
  19. import com.github.unidbg.arm.context.Arm64RegisterContext;
  20. public class soeasy {
  21.     public final AndroidEmulator emulator;
  22.     public final VM vm;
  23.     public final Memory memory;
  24.     public final Module module;
  25.     DvmClass cNative;
  26.     public int hitCount = 0;
  27.     public soeasy(){
  28.         emulator = AndroidEmulatorBuilder.for64Bit().build();
  29.         memory =  emulator.getMemory();
  30.         memory.setLibraryResolver(new AndroidResolver(23));
  31.         emulator.getSyscallHandler().setEnableThreadDispatcher(true);
  32.         vm = emulator.createDalvikVM();
  33. //        vm.setVerbose(true);
  34.         new AndroidModule(emulator,vm).register(memory);
  35.         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);
  36.         module = dalvikModule.getModule();
  37.         vm.callJNI_OnLoad(emulator,module);
  38.     }
  39.     public  void bc(){
  40.         hitCount = 0;
  41.     }
  42.     public static void main(String[] args){
  43.         soeasy mainActivity = new soeasy();
  44.         String mp = "0123456789wertyuiopasdfghjklzxcvbnm@!_{}-";
  45.         for (int i=0;i<mp.length();i++){
  46.             char ch = mp.charAt(i);
  47.             String x = String.valueOf(ch).repeat(36);
  48.             System.out.printf(",");
  49.             mainActivity.debugger(x);
  50.             mainActivity.bc();
  51.         }
  52.     }
  53.     private  void debugger(String x) {
  54. //        emulator.traceCode(module.base + 0x0000000000187D0,module.base  +  0x0000000000B3F00);
  55. //        emulator.traceRead(0x400e1000,0x400e1020);
  56.         emulator.attach(DebuggerType.CONSOLE).addBreakPoint(module.base + 0x21bb8, new BreakPointCallback() {
  57.             @Override
  58.             public boolean onHit(Emulator<?> emulator, long address) {
  59.                 hitCount+=1;
  60.                 if(hitCount !=17+36*5+2){
  61.                     return true;
  62.                 }else{
  63.                     Arm64RegisterContext context = emulator.getContext();
  64.                     long x1Value = context.getXLong(1);
  65.                     Memory memory = emulator.getMemory();
  66.                     String read_data = memory.pointer(x1Value).getString(0).substring(0,72);
  67. //                        System.out.printf("->%x\n",x1Value);
  68.                     System.out.println(read_data);
  69.                     return true;
  70.                 }
  71.             }
  72.         });
  73.         cNative = vm.resolveClass("com.s0rry.easyandroid.MainActivity");
  74. //        String ang0 = "abcdefghijklmnopqrstuvwxyz0123456789";
  75.         DvmObject<?> strRc = cNative.callStaticJniMethodObject(emulator,"aaa(Ljava/lang/String;)Z",x);
  76.     }
  77. }
复制代码
 
python暴力映射:
  1. mp1 = "0123456789wertyuiopasdfghjklzxcvbnm@!_{}-"
  2. mp2 = [
  3. bytes.fromhex("c85015e9cb6a15003a11d6753ce84097762577bcd7f1ebb6d96754047add67ecd8ab14bd")
  4. ,bytes.fromhex("c95114e8ca6b14013b10d7743de94196772476bdd6f0eab7d86655057bdc66edd9aa15bc")
  5. ,bytes.fromhex("ca5217ebc96817023813d4773eea4295742775bed5f3e9b4db65560678df65eedaa916bf")
  6. ,bytes.fromhex("cb5316eac86916033912d5763feb4394752674bfd4f2e8b5da64570779de64efdba817be")
  7. ,bytes.fromhex("cc5411edcf6e11043e15d27138ec4493722173b8d3f5efb2dd6350007ed963e8dcaf10b9")
  8. ,bytes.fromhex("cd5510ecce6f10053f14d37039ed4592732072b9d2f4eeb3dc6251017fd862e9ddae11b8")
  9. ,bytes.fromhex("ce5613efcd6c13063c17d0733aee4691702371bad1f7edb0df6152027cdb61eadead12bb")
  10. ,bytes.fromhex("cf5712eecc6d12073d16d1723bef4790712270bbd0f6ecb1de6053037dda60ebdfac13ba")
  11. ,bytes.fromhex("c0581de1c3621d083219de7d34e0489f7e2d7fb4dff9e3bed16f5c0c72d56fe4d0a31cb5")
  12. ,bytes.fromhex("c1591ce0c2631c093318df7c35e1499e7f2c7eb5def8e2bfd06e5d0d73d46ee5d1a21db4")
  13. ,bytes.fromhex("8f1752ae8c2d52477d5691327baf07d0316230fb90b6acf19e2013433d9a20ab9fec53fa")
  14. ,bytes.fromhex("9d0540bc9e3f40556f44832069bd15c2237022e982a4bee38c3201512f8832b98dfe41e8")
  15. ,bytes.fromhex("8a1257ab89285742785394377eaa02d5346735fe95b3a9f49b251646389f25ae9ae956ff")
  16. ,bytes.fromhex("8c1451ad8f2e51447e55923178ac04d3326133f893b5aff29d2310403e9923a89cef50f9")
  17. ,bytes.fromhex("81195ca082235c4973589f3c75a109de3f6c3ef59eb8a2ff902e1d4d33942ea591e25df4")
  18. ,bytes.fromhex("8d1550ac8e2f50457f54933079ad05d2336032f992b4aef39c2211413f9822a99dee51f8")
  19. ,bytes.fromhex("91094cb092334c5963488f2c65b119ce2f7c2ee58ea8b2ef803e0d5d23843eb581f24de4")
  20. ,bytes.fromhex("970f4ab694354a5f654e892a63b71fc8297a28e388aeb4e986380b5b258238b387f44be2")
  21. ,bytes.fromhex("881055a98b2a55407a5196357ca800d7366537fc97b1abf6992714443a9d27ac98eb54fd")
  22. ,bytes.fromhex("990144b89a3b44516b4087246db911c6277426ed86a0bae7883605552b8c36bd89fa45ec")
  23. ,bytes.fromhex("8b1356aa88295643795295367fab03d4356634ff94b2a8f59a241747399e24af9be857fe")
  24. ,bytes.fromhex("9c0441bd9f3e41546e45822168bc14c3227123e883a5bfe28d3300502e8933b88cff40e9")
  25. ,bytes.fromhex("9e0643bf9d3c43566c4780236abe16c1207321ea81a7bde08f3102522c8b31ba8efd42eb")
  26. ,bytes.fromhex("9f0742be9c3d42576d4681226bbf17c0217220eb80a6bce18e3003532d8a30bb8ffc43ea")
  27. ,bytes.fromhex("90084db193324d5862498e2d64b018cf2e7d2fe48fa9b3ee813f0c5c22853fb480f34ce5")
  28. ,bytes.fromhex("920a4fb391304f5a604b8c2f66b21acd2c7f2de68dabb1ec833d0e5e20873db682f14ee7")
  29. ,bytes.fromhex("930b4eb290314e5b614a8d2e67b31bcc2d7e2ce78caab0ed823c0f5f21863cb783f04fe6")
  30. ,bytes.fromhex("940c49b59736495c664d8a2960b41ccb2a792be08badb7ea853b085826813bb084f748e1")
  31. ,bytes.fromhex("821a5fa381205f4a705b9c3f76a20add3c6f3df69dbba1fc932d1e4e30972da692e15ef7")
  32. ,bytes.fromhex("80185da183225d4872599e3d74a008df3e6d3ff49fb9a3fe912f1c4c32952fa490e35cf5")
  33. ,bytes.fromhex("9b0346ba98394653694285266fbb13c4257624ef84a2b8e58a340757298e34bf8bf847ee")
  34. ,bytes.fromhex("8e1653af8d2c53467c5790337aae06d1306331fa91b7adf09f2112423c9b21aa9eed52fb")
  35. ,bytes.fromhex("9a0247bb99384752684384276eba12c5247725ee85a3b9e48b350656288f35be8af946ef")
  36. ,bytes.fromhex("960e4bb795344b5e644f882b62b61ec9287b29e289afb5e887390a5a248339b286f54ae3")
  37. ,bytes.fromhex("950d48b49637485d674c8b2861b51dca2b782ae18aacb6eb843a095927803ab185f649e0")
  38. ,bytes.fromhex("b8206599bb1a65704a61a6054c9830e7065507cca7819bc6a91724740aad179ca8db64cd")
  39. ,bytes.fromhex("d94104f8da7b04112b00c7642df95186673466adc6e0faa7c87645156bcc76fdc9ba05ac")
  40. ,bytes.fromhex("a73f7a86a4057a6f557eb91a53872ff8194a18d3b89e84d9b6083b6b15b20883b7c47bd2")
  41. ,bytes.fromhex("831b5ea280215e4b715a9d3e77a30bdc3d6e3cf79cbaa0fd922c1f4f31962ca793e05ff6")
  42. ,bytes.fromhex("851d58a48627584d775c9b3871a50dda3b683af19abca6fb942a194937902aa195e659f0")
  43. ,bytes.fromhex("d54d08f4d677081d270ccb6821f55d8a6b386aa1caecf6abc47a491967c07af1c5b609a0")]
  44. 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")
  45. flag = ""
  46. for i in range(len(enc)):
  47.     x = enc[i]
  48.     for j in range(len(mp2)):
  49.         
  50.         if mp2[j][i] == x:
  51.             flag += mp1[j]
  52. print(flag)
复制代码
 
得到flag:WMCTF{f1711720-3f31-459b-b413-8858305b9e51}Ps: 其实这里直接用unidbg 的hook功能直接爆破就完事了,但我不是很熟悉unidbg上的hook,于是才采用了这种方法,借助python脚本完成爆破二、rustdroid

Rust语言编写的.so文件,没有去符号,加密逻辑也比较简单,直接z3求解即可
 
[code]from struct import unpack,packenstream = [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)==256assert len(key) == 4def Q2b(m):    return pack("

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王國慶

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表