VNCTF2022 wp复现

BabyMaze

直接去看原文吧:转自: https://ppppz.net/2022/02/08/BabyMaze/

CM1

gda打开apk.(jadx看不到FileUtils源码)

加载了 classes.dex, 传入FileUtils 和 进行了某些操作然后就变成了ooo。

在 assets中找到 ooo 导出。根据源码用vn2022循环异或 1024为一组。

生成新的dex文件。用jadx打开。

很明显XXTEA。直接解密。。

    k = [0x50703448, 0x4E565F59, 0x21465443, 0x4F764F21]
    res = [0x6CA42744, 0xC948EEAE, 0x0B26C84A, 0xD861543C, 0xAE634757, 0xB92F6878, 0x2100C7C6, 0xD9D4262A, 0x5CFE71C4, 0x32B376B5, 0x96202B87]

CM狗

参考链接贴上,慢慢复现

https://blog.shi1011.cn/ctf/2162#cm%E7%8B%97 https://blog.csdn.net/qq_52974719/article/details/123100965#t2 https://blog.csdn.net/m0_51911432/article/details/122914413#t4 http://s0rry.cn/archives/vnctf2022re-fu-xian#toc-head-6

struct REG
{
  _DWORD R[21]; // 21个寄存器
};

struct func
{
  void *call; // call 地址
  vm *ptr; // vm
};


struct vm
{
  REG reg; // 寄存器
  _DWORD Memory[1000];
  _DWORD rip; // VM下一个执行地址
  _DWORD index;
  void *data; // opcode
  func *func[100];
  _QWORD isExit;
};

下图是offset 值,看一下转的对不对。

init中定义了操作数对应的函数

整理后如下

func *__usercall main___ptr_MzVm__init@<rax>(vm *a1) {
    a1->func[0] = &init;
    a1->func[1] = main___ptr_MzVm__init_func2;
    a1->func[2] = main___ptr_MzVm__init_func3;
    a1->func[3] = main___ptr_MzVm__init_func4;
    a1->func[4] = main___ptr_MzVm__init_func5;
    a1->func[5] = main___ptr_MzVm__init_func6;
    a1->func[6] = main___ptr_MzVm__init_func7;
    a1->func[7] = main___ptr_MzVm__init_func8;
    a1->func[8] = main___ptr_MzVm__init_func9;
    a1->func[9] = main___ptr_MzVm__init_func10;
    a1->func[10] = main___ptr_MzVm__init_func11;
    a1->func[11] = main___ptr_MzVm__init_func12;
    a1->func[12] = main___ptr_MzVm__init_func13;
    a1->func[13] = main___ptr_MzVm__init_func14;
    a1->func[14] = main___ptr_MzVm__init_func15;
    a1->func[15] = main___ptr_MzVm__init_func16;
    a1->func[16] = main___ptr_MzVm__init_func17;
    a1->func[17] = main___ptr_MzVm__init_func18;
    a1->func[98] = main___ptr_MzVm__init_func19;
    a1->func[99] = main___ptr_MzVm__init_func20;
}

右击 a1 转为 struct格式

void __golang main___ptr_MzVm__run(vm *a1)
{
  vm *v1; // rbx
  _DWORD *data; // rsi
  unsigned __int64 rip; // rax
  unsigned __int64 op1; // rdi
  unsigned __int64 v5; // r8
  unsigned int op2; // er8
  unsigned __int64 v7; // rax
  unsigned int op3; // esi
  __int64 v9; // [rsp+0h] [rbp-18h]
  void *retaddr; // [rsp+18h] [rbp+0h] BYREF

  while ( (unsigned __int64)&retaddr <= *(_QWORD *)(*(_QWORD *)NtCurrentTeb()->NtTib.ArbitraryUserPointer + 16LL) )
    runtime_morestack_noctxt();
  v1 = a1;
  while ( !LOBYTE(v1->isExit) )
  {
    data = v1->data;
    rip = (unsigned int)v1->rip;
    if ( rip >= 0xBB8 )
      runtime_panicIndex(v9);
    op1 = (unsigned int)data[rip];
    v5 = (unsigned int)(rip + 1);
    if ( v5 >= 0xBB8 )
      runtime_panicIndex(v9);
    op2 = data[v5];
    v7 = (unsigned int)(rip + 2);
    if ( v7 >= 0xBB8 )
      runtime_panicIndex(v9);
    op3 = data[v7];
    if ( op1 >= 0x64 )
      runtime_panicIndex(v9);
    v9 = __PAIR64__(op3, op2);
    ((void (*)(void))v1->func[op1]->call)();
    v1 = a1;
    a1->rip += 3;
  }
}

双击data来到opcode,每轮使用3个操作数。在ida中这样设置一下看清每一轮。

op=1, func2

HIDWORD测试,小端序 高位

    unsigned char v[] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
    QWORD *a = (QWORD *) v;
    printf("%llX", HIDWORD(*a)); // 88776655
  ptr->reg.R[(unsigned int)a1] = HIDWORD(a1);  //低位取索引,高位取值 R[index]= value

op=2, func3

v2->reg.R[(unsigned int)a1] = v2->reg.R[HIDWORD(a1)];

R[low] = R[hi] , 通过索引赋值到R数组中

op=5, func6

Memory[result] = reg.R[a1];

op=6, func7

reg.R[a1] = Memory[ptr->index];
ptr->index++;

op=7, func8

R[low] += R[hi]

op=7, func9

R[low] -= R[hi]

func11

R[low] *= R[hi]

func12

R[low] ^= R[hi]

func13

  result = (unsigned int)(3 * v2->reg.R[a1]);
  v2->rip = result;
  =>
  rip = 3 * reg.R[a1]
  => jmp reg.R[a1]

func15

  result = (unsigned int)ptr->reg.R[HIDWORD(a1)];
  if ( (_DWORD)result != ptr->reg.R[(unsigned int)a1] ) ; R[HI] != R[LO]
  {
    result = (unsigned int)(3 * ptr->reg.R[19]);        ; JMP R[19]
    ptr->rip = result;
  }
  

op=0x61, func18 输出字符

scanf

op=0x62, func19 输出字符

fmt_Fprint

op=0x63, func20

注释里标了

vmquit

脚本

from string import printable

_m = list(printable.encode())
_m.remove(10)
_m.remove(13)
_hex = lambda _d: f"0x{_d:02x}" if _d > 15 else _d
_chr = lambda _v: hex(_v) if _v not in _m else f"'{chr(_v)}'"
maps = {
    0x1: "nop",
    0x2: "mov R[{num}], {right} ; {ch}",
    0x3: "mov R[{num}], R[{right}]",
    0x4: "mov R[{num}], Memory[{right}]",
    0x5: "mov Memory[num] R[{right}]",
    0x6: "push R[{num}]",
    0x7: "pop R[{num}]",
    0x8: "add R[{num}], R[{right}]",
    0x9: "dec R[{num}], R[{right}]",
    0xa: "div R[{num}], R[{right}]",
    0xb: "mul R[{num}], R[{right}]",
    0xc: "xor R[{num}], R[{right}]",
    0xd: "jmp R[{num}]",
    0xe: "cmp R[{num}] R[{right}], je R[19]",
    0xf: "cmp R[{num}] R[{right}], jne R[19]",
    0x10: "cmp R[{num}] R[{right}], jb R[19]",
    0x11: "cmp R[{num}] R[{right}], ja R[19]",
    0x62: "getchar R[{num}]",
    0x63: "putchar R[{num}]",
    0x64: "vm quit"
}
data = [0, 0, 0, 0, 0, 0, 0x1, 0, 0x57, 0x62, 0, 0, 0x1, 0, 0x65, 0x62, 0, 0, 0x1, 0, 0x6C, 0x62, 0, 0,
        0x1, 0, 0x63, 0x62, 0, 0, 0x1, 0, 0x6F, 0x62, 0, 0, 0x1, 0, 0x6D, 0x62, 0, 0, 0x1, 0, 0x65, 0x62, 0, 0,
        0x1, 0, 0x20, 0x62, 0, 0, 0x1, 0, 0x74, 0x62, 0, 0, 0x1, 0, 0x6F, 0x62, 0, 0, 0x1, 0, 0x20, 0x62, 0, 0,
        0x1, 0, 0x56, 0x62, 0, 0, 0x1, 0, 0x4E, 0x62, 0, 0, 0x1, 0, 0x43, 0x62, 0, 0, 0x1, 0, 0x54, 0x62, 0, 0,
        0x1, 0, 0x46, 0x62, 0, 0, 0x1, 0, 0x32, 0x62, 0, 0, 0x1, 0, 0x30, 0x62, 0, 0, 0x1, 0, 0x32, 0x62, 0, 0,
        0x1, 0, 0x32, 0x62, 0, 0, 0x1, 0, 0x21, 0x62, 0, 0, 0x1, 0, 0xA, 0x62, 0, 0, 0x1, 0, 0x69, 0x62, 0, 0,
        0x1, 0, 0x6E, 0x62, 0, 0, 0x1, 0, 0x70, 0x62, 0, 0, 0x1, 0, 0x75, 0x62, 0, 0, 0x1, 0, 0x74, 0x62, 0, 0,
        0x1, 0, 0x20, 0x62, 0, 0, 0x1, 0, 0x66, 0x62, 0, 0, 0x1, 0, 0x6C, 0x62, 0, 0, 0x1, 0, 0x61, 0x62, 0, 0,
        0x1, 0, 0x67, 0x62, 0, 0, 0x1, 0, 0x3A, 0x62, 0, 0, 0x1, 0, 0xA, 0x62, 0, 0, 0x1, 0x13, 0x49, 0x1, 0x3, 0,
        0x1, 0x1, 0x2B, 0x1, 0x2, 0x1, 0x61, 0, 0, 0x5, 0, 0, 0x8, 0x1, 0x2, 0xE, 0x1, 0x3, 0x1, 0, 0, 0x5, 0, 0,
        0, 0, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0x6, 0, 0x6, 0, 0, 0x7, 0x6, 0,
        0x2, 0, 0x6, 0xA, 0, 0x5, 0x2, 0x6, 0, 0x6, 0, 0, 0x7, 0x6, 0, 0x2, 0, 0x6, 0xA, 0, 0x5, 0x2, 0x6, 0,
        0x6, 0, 0, 0x7, 0x6, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0x7, 0, 0x6, 0, 0,
        0x7, 0x7, 0, 0x2, 0, 0x7, 0xA, 0, 0x5, 0x2, 0x7, 0, 0x6, 0, 0, 0x7, 0x7, 0, 0x2, 0, 0x7, 0xA, 0, 0x5,
        0x2, 0x7, 0, 0x6, 0, 0, 0x7, 0x7, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0x8, 0,
        0x6, 0, 0, 0x7, 0x8, 0, 0x2, 0, 0x8, 0xA, 0, 0x5, 0x2, 0x8, 0, 0x6, 0, 0, 0x7, 0x8, 0, 0x2, 0, 0x8,
        0xA, 0, 0x5, 0x2, 0x8, 0, 0x6, 0, 0, 0x7, 0x8, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5,
        0x2, 0x9, 0, 0x6, 0, 0, 0x7, 0x9, 0, 0x2, 0, 0x9, 0xA, 0, 0x5, 0x2, 0x9, 0, 0x6, 0, 0, 0x7, 0x9, 0,
        0x2, 0, 0x9, 0xA, 0, 0x5, 0x2, 0x9, 0, 0x6, 0, 0, 0x7, 0x9, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100,
        0xA, 0, 0x5, 0x2, 0xA, 0, 0x6, 0, 0, 0x7, 0xA, 0, 0x2, 0, 0xA, 0xA, 0, 0x5, 0x2, 0xA, 0, 0x6, 0, 0,
        0x7, 0xA, 0, 0x2, 0, 0xA, 0xA, 0, 0x5, 0x2, 0xA, 0, 0x6, 0, 0, 0x7, 0xA, 0, 0, 0, 0, 0x6, 0, 0,
        0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0xB, 0, 0x6, 0, 0, 0x7, 0xB, 0, 0x2, 0, 0xB, 0xA, 0, 0x5, 0x2, 0xB, 0,
        0x6, 0, 0, 0x7, 0xB, 0, 0x2, 0, 0xB, 0xA, 0, 0x5, 0x2, 0xB, 0, 0x6, 0, 0, 0x7, 0xB, 0, 0, 0, 0,
        0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0xC, 0, 0x6, 0, 0, 0x7, 0xC, 0, 0x2, 0, 0xC, 0xA, 0, 0x5,
        0x2, 0xC, 0, 0x6, 0, 0, 0x7, 0xC, 0, 0x2, 0, 0xC, 0xA, 0, 0x5, 0x2, 0xC, 0, 0x6, 0, 0, 0x7, 0xC, 0,
        0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0xD, 0, 0x6, 0, 0, 0x7, 0xD, 0, 0x2, 0, 0xD,
        0xA, 0, 0x5, 0x2, 0xD, 0, 0x6, 0, 0, 0x7, 0xD, 0, 0x2, 0, 0xD, 0xA, 0, 0x5, 0x2, 0xD, 0, 0x6, 0, 0,
        0x7, 0xD, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0xE, 0, 0x6, 0, 0, 0x7, 0xE, 0,
        0x2, 0, 0xE, 0xA, 0, 0x5, 0x2, 0xE, 0, 0x6, 0, 0, 0x7, 0xE, 0, 0x2, 0, 0xE, 0xA, 0, 0x5, 0x2, 0xE, 0,
        0x6, 0, 0, 0x7, 0xE, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0xF, 0, 0x6, 0, 0,
        0x7, 0xF, 0, 0x2, 0, 0xF, 0xA, 0, 0x5, 0x2, 0xF, 0, 0x6, 0, 0, 0x7, 0xF, 0, 0x2, 0, 0xF, 0xA, 0, 0x5,
        0x2, 0xF, 0, 0x6, 0, 0, 0x7, 0xF, 0, 0, 0, 0, 0x6, 0, 0, 0x1, 0x5, 0x100, 0xA, 0, 0x5, 0x2, 0x10, 0,
        0x6, 0, 0, 0x7, 0x10, 0, 0x2, 0, 0x10, 0xA, 0, 0x5, 0x2, 0x10, 0, 0x6, 0, 0, 0x7, 0x10, 0, 0x2, 0, 0x10,
        0xA, 0, 0x5, 0x2, 0x10, 0, 0x6, 0, 0, 0x7, 0x10, 0, 0, 0, 0, 0x5, 0x6, 0, 0x5, 0x7, 0, 0x5, 0x8, 0,
        0x5, 0x9, 0, 0x5, 0xA, 0, 0x5, 0xB, 0, 0x5, 0xC, 0, 0x5, 0xD, 0, 0x5, 0xE, 0, 0x5, 0xF, 0, 0x5, 0x10, 0,
        0x6, 0x1, 0, 0x6, 0x2, 0, 0x1, 0x14, 0x11C, 0x1, 0, 0x154, 0xC, 0, 0, 0x1, 0, 0xE8D1D5DF, 0x1, 0x13, 0x183, 0x1, 0x14, 0x153,
        0xE, 0x1, 0, 0x1, 0, 0xF5E3C114, 0xE, 0x2, 0, 0x6, 0x1, 0, 0x6, 0x2, 0, 0x1, 0x14, 0x127, 0x1, 0, 0x154, 0xC, 0, 0,
        0x1, 0, 0x228EC216, 0x1, 0x13, 0x183, 0x1, 0x14, 0x153, 0xE, 0x1, 0, 0x1, 0, 0x89D45A61, 0xE, 0x2, 0, 0x6, 0x1, 0, 0x6, 0x2, 0,
        0x1, 0x14, 0x132, 0x1, 0, 0x154, 0xC, 0, 0, 0x1, 0, 0x655B8F69, 0x1, 0x13, 0x183, 0x1, 0x14, 0x153, 0xE, 0x1, 0, 0x1, 0, 0x2484A07A,
        0xE, 0x2, 0, 0x6, 0x1, 0, 0x6, 0x2, 0, 0x1, 0x14, 0x13D, 0x1, 0, 0x154, 0xC, 0, 0, 0x1, 0, 0xD9E5E7F8, 0x1, 0x13, 0x183,
        0x1, 0x14, 0x153, 0xE, 0x1, 0, 0x1, 0, 0x3A441532, 0xE, 0x2, 0, 0x6, 0x1, 0, 0x6, 0x2, 0, 0x1, 0x14, 0x148, 0x1, 0, 0x154,
        0xC, 0, 0, 0x1, 0, 0x91AB7E88, 0x1, 0x13, 0x183, 0x1, 0x14, 0x153, 0xE, 0x1, 0, 0x1, 0, 0x69FC64BC, 0xE, 0x2, 0, 0x6, 0x1, 0,
        0x1, 0, 0x7D3765, 0xE, 0x1, 0, 0x1, 0, 0x189, 0xC, 0, 0, 0x63, 0, 0, 0x1, 0x3, 0x9E3779B9, 0x1, 0x4, 0x95C4C, 0x1, 0x5, 0x871D,
        0x1, 0x6, 0x1A7B7, 0x1, 0x7, 0x12C7C7, 0x1, 0x8, 0, 0x1, 0x11, 0x10, 0x1, 0x12, 0x20, 0x1, 0x13, 0x160, 0x1, 0xA, 0, 0x1, 0xB, 0x20,
        0x1, 0xC, 0x1, 0x7, 0x8, 0x3, 0x2, 0, 0x2, 0xA, 0, 0x11, 0x7, 0, 0x4, 0x2, 0xE, 0, 0x2, 0, 0x2, 0x7, 0, 0x8,
        0x2, 0xF, 0, 0x2, 0, 0x2, 0x9, 0, 0x12, 0x7, 0, 0x5, 0x2, 0x10, 0, 0x2, 0, 0xE, 0xB, 0, 0xF, 0xB, 0, 0x10,
        0x7, 0x1, 0, 0x2, 0, 0x1, 0xA, 0, 0x11, 0x7, 0, 0x6, 0x2, 0xE, 0, 0x2, 0, 0x1, 0x7, 0, 0x8, 0x2, 0xF, 0,
        0x2, 0, 0x1, 0x9, 0, 0x12, 0x7, 0, 0x7, 0x2, 0x10, 0, 0x2, 0, 0xE, 0xB, 0, 0xF, 0xB, 0, 0x10, 0x7, 0x2, 0,
        0x8, 0xB, 0xC, 0xE, 0xB, 0xA, 0xC, 0x14, 0, 0, 0, 0, 0x1, 0, 0x6E, 0x62, 0, 0, 0x1, 0, 0x6F, 0x62, 0, 0,
        0xC, 0x14, 0, 0, 0, 0, 0x1, 0, 0x79, 0x62, 0, 0, 0x1, 0, 0x65, 0x62, 0, 0, 0x1, 0, 0x73, 0x62, 0, 0,
        0xC, 0x14, 0]


for i in range(0, len(data), 3):
    funcItem, arg1, arg2 = data[i], data[i + 1], data[i + 2]
    # print(funcItem+1, arg1, arg2)
    print(hex(i // 3).rjust(5, " ") + ":", maps[funcItem + 1].format(num=arg1, right=_hex(arg2), ch=_chr(arg2)))

分析汇编。tea。解密。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值