王國慶 发表于 2024-9-9 15:29:36

WMCTF2024 RE wp

AK了逆向
https://img2024.cnblogs.com/blog/2433096/202409/2433096-20240909112439487-1070502814.png
 
一、easyAndroid

二血
思绪:.so层的代码逻辑极其杂乱,简直无从下手,不过经过分析后发现标题采用了单字节加密,可以直接爆破出flag解题流程如下:实验trace跟踪一下字符串这里使用unidbg对输入字符串地址下内存访问断点,跟踪log如下: Memory READ at 0x400e1000, data size = 8, data value = 0x3333323231313030, PC=RX@0x4021cbf40x1cbf4, LR=RX@0x400383380x38338
Memory READ at 0x400e1008, data size = 8, data value = 0x3737363635353434, PC=RX@0x4021cbf40x1cbf4, LR=RX@0x400383380x38338
Memory READ at 0x400e1010, data size = 8, data value = 0x6262616139393838, PC=RX@0x4021cbf40x1cbf4, LR=RX@0x400383380x38338
Memory READ at 0x400e1018, data size = 8, data value = 0x6666656564646363, PC=RX@0x4021cbf40x1cbf4, LR=RX@0x400383380x38338
Memory READ at 0x400e1020, data size = 8, data value = 0x6e736c74, PC=RX@0x4021cbf40x1cbf4, LR=RX@0x400383380x38338
Memory READ at 0x400e1010, data size = 4, data value = 0x39393838, PC=RX@0x40021c000x21c00, LR=RX@0x400383480x38348
Memory READ at 0x400e1020, data size = 4, data value = 0x6e736c74, PC=RX@0x40021c000x21c00, LR=RX@0x400383480x38348
Memory READ at 0x400e1008, data size = 4, data value = 0x35353434, PC=RX@0x40021c000x21c00, LR=RX@0x400383480x38348
Memory READ at 0x400e1000, data size = 4, data value = 0x31313030, PC=RX@0x40021c000x21c00, LR=RX@0x400383480x38348
Memory READ at 0x400e1000, data size = 8, data value = 0x3333323231313030, PC=RX@0x4021c1800x1c180, LR=RX@0x40021d880x21d88
Memory READ at 0x400e1008, data size = 8, data value = 0x3737363635353434, PC=RX@0x4021c1800x1c180, LR=RX@0x40021d880x21d88
Memory READ at 0x400e1010, data size = 8, data value = 0x6262616139393838, PC=RX@0x4021c1800x1c180, LR=RX@0x40021d880x21d88
Memory READ at 0x400e1018, data size = 8, data value = 0x6666656564646363, PC=RX@0x4021c1800x1c180, LR=RX@0x40021d880x21d88
Memory READ at 0x400e1014, data size = 8, data value = 0x6464636362626161, PC=RX@0x4021c1980x1c198, LR=RX@0x40021d880x21d88
Memory READ at 0x400e101c, data size = 8, data value = 0x6e736c7466666565, PC=RX@0x4021c1980x1c198, LR=RX@0x40021d880x21d88 
定位到地址 偏移为 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);
    }
    publicvoid 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();
      }


    }
    privatevoid 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
    for j in range(len(mp2)):
      
      if mp2 == x:
            flag += mp1

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

Rust语言编写的.so文件,没有去符号,加密逻辑也比较简单,直接z3求解即可
 
from struct import unpack,packenstream = key = assert len(enstream)==256assert len(key) == 4def Q2b(m):    return pack("
页: [1]
查看完整版本: WMCTF2024 RE wp