VNCTF2022-RE

RE

BabyMaze

python3.8以上版本不可直接uncompyle反编译 用py38的dis或decompy++都可以反汇编

这里用decompy++ 执行 .\pycdas BabyMaze.pyc > code.txt

部分字节码如下

BabyMaze.pyc (Python 3.8)
[Code]
    File Name: .\BabyMaze.py
    Object Name: <module>
    Arg Count: 0
    Pos Only Arg Count: 0
    KW Only Arg Count: 0
    Locals: 0
    Stack Size: 61
    Flags: 0x00000040 (CO_NOFREE)
    [Names]
        '_map'
        'maze'
        'main'
        '__name__'
    [Var Names]
    [Free Vars]
    [Cell Vars]
    [Constants]
        1
        5
        0
        7
        [Code]
            File Name: .\BabyMaze.py
            Object Name: maze
            Arg Count: 0
            Pos Only Arg Count: 0
            KW Only Arg Count: 0
            Locals: 4
            Stack Size: 3
            Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)
            [Names]
                'input'
                'range'
                'len'
                '_map'
            [Var Names]
                'x'
                'y'
                'step'
                'i'
            [Free Vars]
            [Cell Vars]
            [Constants]
                None
                1
                'w'
                's'
                'a'
                'd'
                False
                29
                True
            [Disassembly]
                0       LOAD_CONST              1: 1
                2       STORE_FAST              0: x
                4       LOAD_CONST              1: 1
                6       STORE_FAST              1: y
                8       LOAD_GLOBAL             0: input
                10      CALL_FUNCTION           0
                12      STORE_FAST              2: step
                14      LOAD_GLOBAL             1: range
                16      LOAD_GLOBAL             2: len
                18      LOAD_FAST               2: step
                20      CALL_FUNCTION           1
                22      CALL_FUNCTION           1
                24      GET_ITER                
                26      FOR_ITER                142 (to 170)
                28      STORE_FAST              3: i
                30      LOAD_FAST               2: step
                32      LOAD_FAST               3: i
                34      BINARY_SUBSCR           
                36      LOAD_CONST              2: 'w'
                38      COMPARE_OP              2 (==)
                40      POP_JUMP_IF_FALSE       52
                42      LOAD_FAST               0: x
                44      LOAD_CONST              1: 1
                46      INPLACE_SUBTRACT        
                48      STORE_FAST              0: x
                50      JUMP_FORWARD            72 (to 124)
                52      LOAD_FAST               2: step
                54      LOAD_FAST               3: i
                56      BINARY_SUBSCR           
                58      LOAD_CONST              3: 's'
                60      COMPARE_OP              2 (==)
                62      POP_JUMP_IF_FALSE       74
                64      LOAD_FAST               0: x
                66      LOAD_CONST              1: 1
                68      INPLACE_ADD             
                70      STORE_FAST              0: x
                72      JUMP_FORWARD            50 (to 124)
                74      LOAD_FAST               2: step
                76      LOAD_FAST               3: i
                78      BINARY_SUBSCR           
                80      LOAD_CONST              4: 'a'
                82      COMPARE_OP              2 (==)
                84      POP_JUMP_IF_FALSE       96
                86      LOAD_FAST               1: y
                88      LOAD_CONST              1: 1
                90      INPLACE_SUBTRACT        
                92      STORE_FAST              1: y
                94      JUMP_FORWARD            28 (to 124)
                96      LOAD_FAST               2: step
                98      LOAD_FAST               3: i
                100     BINARY_SUBSCR           
                102     LOAD_CONST              5: 'd'
                104     COMPARE_OP              2 (==)
                106     POP_JUMP_IF_FALSE       118
                108     LOAD_FAST               1: y
                110     LOAD_CONST              1: 1
                112     INPLACE_ADD             
                114     STORE_FAST              1: y
                116     JUMP_FORWARD            6 (to 124)
                118     POP_TOP                 
                120     LOAD_CONST              6: False
                122     RETURN_VALUE            
                124     LOAD_GLOBAL             3: _map
                126     LOAD_FAST               0: x
                128     BINARY_SUBSCR           
                130     LOAD_FAST               1: y
                132     BINARY_SUBSCR           
                134     LOAD_CONST              1: 1
                136     COMPARE_OP              2 (==)
                138     POP_JUMP_IF_FALSE       146
                140     POP_TOP                 
                142     LOAD_CONST              6: False
                144     RETURN_VALUE            
                146     LOAD_FAST               0: x
                148     LOAD_CONST              7: 29
                150     COMPARE_OP              2 (==)
                152     POP_JUMP_IF_FALSE       26
                154     LOAD_FAST               1: y
                156     LOAD_CONST              7: 29
                158     COMPARE_OP              2 (==)
                160     POP_JUMP_IF_FALSE       26
                162     POP_TOP                 
                164     LOAD_CONST              8: True
                166     RETURN_VALUE            
                168     JUMP_ABSOLUTE           26
                170     LOAD_CONST              0: None
                172     RETURN_VALUE            

其余主要是map数组,参考py字节码官网写出伪码

 x=1
 y=1
 step=input()
 for i in range(len(step)):
     if step[i]=='w':
         x-=1
     elif step[i]=='s':
         x+=1
     elif step[i]=='a':
         y-=1
     elif step[i]=='d':
         y+=1
     else:
         print('noo')
     if map[31*x+y]==1:
         print('noo')
     else:
         if x==29 and y==29:
             print('yes')

solve maze problem

#include<iostream>
uint8_t map[961] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
uint8_t ans[256] = { 0 };
uint8_t visit[961] = { 0 };
uint8_t next[4] = { 119,115,97,100 };
uint32_t step = 0;
void maze(uint32_t x, uint32_t y) {
	visit[31 * x + y] = 1;
	uint32_t tx, ty;
	if (x == 29 && y == 29) {
		printf("yes\n");
		for (int i = 0; i < step; i++)
		{
			printf("%c", ans[i]);
		}

		exit(0);
	}
	for (int i = 0; i < 4; i++) {
		switch (next[i])
		{
		case 119:
			tx = x - 1;
			ty = y;
			break;
		case 115:
			tx = x + 1;
			ty = y;
			break;
		case 97:
			ty = y - 1;
			tx = x;
			break;
		case 100:
			ty = y + 1;
			tx = x;
			break;
		}

		if ((tx >= 0 && tx < 31) && (ty >= 0 && ty < 31) && map[31 * tx + ty] != 1 && visit[31 * tx + ty] == 0) {
			ans[step] = next[i];
			step += 1;
			maze(tx, ty);
			step -= 1;
		}
	}
	return;
}
int main() {
	maze(1, 1);
	return 0;
}
//print('VNCTF{'+md5('ssssddssaassddddwwwwddwwddddddwwddddddssddwwddddddddssssaawwaassaassaassddssaassaawwwwwwaaaaaaaassaassddddwwddssddssssaassddssssaaaaaawwddwwaawwwwaassssssssssssddddssddssddddddddwwaaaaaawwwwddssddwwwwwwwwddssddssssssssddddss'.encode()).hexdigest()+'}')
//VNCTF{801f190737434100e7d2790bd5b0732e}

cm狗

go的虚拟机 索性是模拟的汇编大致相同,硬静态分析还是可以出的

VM_Init 将一些函数地址存在某偏移处,V1结构体有点大,可以不去定义,但要记住几个重要的偏移。

VM_run

image-20220212233121694

根据VM_Run可知指令长度是3Byte,并且0xFF4偏移处是eip,0x1000偏移是opcode,接下来是对20个fun的分析

为了减少工作量可以提前对opcode的地址码进行遍历,只解释用到的指令即可

部分函数

__int64 __usercall main___ptr_MzVm__init_func2@<rax>(__int64 a1)
{												//高32位为Rnum 低32位为Lnum
  __int64 v1; // rdx
  __int64 v2; // rdx
  __int64 result; // rax
  __int64 v4; // [rsp+0h] [rbp-18h]

  v2 = *(_QWORD *)(v1 + 8);                     // mov r[Lnum],Rnum
  result = (unsigned int)a1;
  if ( (unsigned int)a1 >= 0x15uLL )
    runtime_panicIndex(v4);
  *(_DWORD *)(v2 + 4LL * (unsigned int)a1) = HIDWORD(a1);// 0x14个寄存器 Lnum,Rnum
  return result;
}

unsigned __int64 __usercall main___ptr_MzVm__init_func6@<rax>(unsigned int a1)
{
  __int64 v1; // rdx
  __int64 v2; // rdx
  unsigned __int64 result; // rax
  __int64 v4; // [rsp+0h] [rbp-18h]

  v2 = *(_QWORD *)(v1 + 8);
  result = (unsigned int)(*(_DWORD *)(v2 + 0xFF8) - 1);
  *(_DWORD *)(v2 + 0xFF8) = result;                 //0xFF8类似ESP
  if ( a1 >= 0x15uLL )
    runtime_panicIndex(v4);
  if ( result >= 0x3E8 )
    runtime_panicIndex(v4);
  *(_DWORD *)(v2 + 4 * result + 84) = *(_DWORD *)(v2 + 4LL * a1);// push r[Lnum]
  return result;
}

__int64 __usercall main___ptr_MzVm__init_func13@<rax>(unsigned int a1)
{
  __int64 v1; // rdx
  __int64 v2; // rdx
  __int64 result; // rax
  __int64 v4; // [rsp+0h] [rbp-18h]

  v2 = *(_QWORD *)(v1 + 8);
  if ( a1 >= 0x15uLL )
    runtime_panicIndex(v4);
  result = (unsigned int)(3 * *(_DWORD *)(v2 + 4LL * a1));// jmp r[Lnum]
  *(_DWORD *)(v2 + 0xFF4) = result;
  return result;
}

记住几个重要的偏移(EIP OP ESP),剩下的猜结合调试很快就能了解函数功能

parser

op=[0x00000001, 0x00000000, 0x00000057, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000065, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006C, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000063, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006F, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006D, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000065, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000020, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000074, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006F, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000020, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000056, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000004E, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000043, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000054, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000046, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000032, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000030, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000032, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000032, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000021, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000000A, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000069, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006E, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000070, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000075, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000074, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000020, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000066, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006C, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000061, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000067, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000003A, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000000A, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000013, 0x00000049, 0x00000001, 0x00000003, 0x00000000, 0x00000001, 0x00000001, 0x0000002B, 0x00000001, 0x00000002, 0x00000001, 0x00000061, 0x00000000, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 0x00000008, 0x00000001, 0x00000002, 0x0000000E, 0x00000001, 0x00000003, 0x00000001, 0x00000000, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000006, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000006, 0x00000000, 0x00000002, 0x00000000, 0x00000006, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000006, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000006, 0x00000000, 0x00000002, 0x00000000, 0x00000006, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000006, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000007, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000007, 0x00000000, 0x00000002, 0x00000000, 0x00000007, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000007, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000007, 0x00000000, 0x00000002, 0x00000000, 0x00000007, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000007, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000008, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000008, 0x00000000, 0x00000002, 0x00000000, 0x00000008, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000008, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000008, 0x00000000, 0x00000002, 0x00000000, 0x00000008, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000008, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000009, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000009, 0x00000000, 0x00000002, 0x00000000, 0x00000009, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000009, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000009, 0x00000000, 0x00000002, 0x00000000, 0x00000009, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000009, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000A, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000A, 0x00000000, 0x00000002, 0x00000000, 0x0000000A, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000A, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000A, 0x00000000, 0x00000002, 0x00000000, 0x0000000A, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000A, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000B, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000B, 0x00000000, 0x00000002, 0x00000000, 0x0000000B, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000B, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000B, 0x00000000, 0x00000002, 0x00000000, 0x0000000B, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000B, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000C, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000C, 0x00000000, 0x00000002, 0x00000000, 0x0000000C, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000C, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000C, 0x00000000, 0x00000002, 0x00000000, 0x0000000C, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000C, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000C, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000D, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000D, 0x00000000, 0x00000002, 0x00000000, 0x0000000D, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000D, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000D, 0x00000000, 0x00000002, 0x00000000, 0x0000000D, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000D, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000D, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000E, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000E, 0x00000000, 0x00000002, 0x00000000, 0x0000000E, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000E, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000E, 0x00000000, 0x00000002, 0x00000000, 0x0000000E, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000E, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000F, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000F, 0x00000000, 0x00000002, 0x00000000, 0x0000000F, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000F, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000F, 0x00000000, 0x00000002, 0x00000000, 0x0000000F, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x0000000F, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x0000000F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000001, 0x00000005, 0x00000100, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000010, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000010, 0x00000000, 0x00000002, 0x00000000, 0x00000010, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000010, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000010, 0x00000000, 0x00000002, 0x00000000, 0x00000010, 0x0000000A, 0x00000000, 0x00000005, 0x00000002, 0x00000010, 0x00000000, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x00000006, 0x00000000, 0x00000005, 0x00000007, 0x00000000, 0x00000005, 0x00000008, 0x00000000, 0x00000005, 0x00000009, 0x00000000, 0x00000005, 0x0000000A, 0x00000000, 0x00000005, 0x0000000B, 0x00000000, 0x00000005, 0x0000000C, 0x00000000, 0x00000005, 0x0000000D, 0x00000000, 0x00000005, 0x0000000E, 0x00000000, 0x00000005, 0x0000000F, 0x00000000, 0x00000005, 0x00000010, 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000006, 0x00000002, 0x00000000, 0x00000001, 0x00000014, 0x0000011C, 0x00000001, 0x00000000, 0x00000154, 0x0000000C, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0xE8D1D5DF, 0x00000001, 0x00000013, 0x00000183, 0x00000001, 0x00000014, 0x00000153, 0x0000000E, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0xF5E3C114, 0x0000000E, 0x00000002, 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000006, 0x00000002, 0x00000000, 0x00000001, 0x00000014, 0x00000127, 0x00000001, 0x00000000, 0x00000154, 0x0000000C, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x228EC216, 0x00000001, 0x00000013, 0x00000183, 0x00000001, 0x00000014, 0x00000153, 0x0000000E, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x89D45A61, 0x0000000E, 0x00000002, 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000006, 0x00000002, 0x00000000, 0x00000001, 0x00000014, 0x00000132, 0x00000001, 0x00000000, 0x00000154, 0x0000000C, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x655B8F69, 0x00000001, 0x00000013, 0x00000183, 0x00000001, 0x00000014, 0x00000153, 0x0000000E, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x2484A07A, 0x0000000E, 0x00000002, 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000006, 0x00000002, 0x00000000, 0x00000001, 0x00000014, 0x0000013D, 0x00000001, 0x00000000, 0x00000154, 0x0000000C, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0xD9E5E7F8, 0x00000001, 0x00000013, 0x00000183, 0x00000001, 0x00000014, 0x00000153, 0x0000000E, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x3A441532, 0x0000000E, 0x00000002, 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000006, 0x00000002, 0x00000000, 0x00000001, 0x00000014, 0x00000148, 0x00000001, 0x00000000, 0x00000154, 0x0000000C, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x91AB7E88, 0x00000001, 0x00000013, 0x00000183, 0x00000001, 0x00000014, 0x00000153, 0x0000000E, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x69FC64BC, 0x0000000E, 0x00000002, 0x00000000, 0x00000006, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x007D3765, 0x0000000E, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000189, 0x0000000C, 0x00000000, 0x00000000, 0x00000063, 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x9E3779B9, 0x00000001, 0x00000004, 0x00095C4C, 0x00000001, 0x00000005, 0x0000871D, 0x00000001, 0x00000006, 0x0001A7B7, 0x00000001, 0x00000007, 0x0012C7C7, 0x00000001, 0x00000008, 0x00000000, 0x00000001, 0x00000011, 0x00000010, 0x00000001, 0x00000012, 0x00000020, 0x00000001, 0x00000013, 0x00000160, 0x00000001, 0x0000000A, 0x00000000, 0x00000001, 0x0000000B, 0x00000020, 0x00000001, 0x0000000C, 0x00000001, 0x00000007, 0x00000008, 0x00000003, 0x00000002, 0x00000000, 0x00000002, 0x0000000A, 0x00000000, 0x00000011, 0x00000007, 0x00000000, 0x00000004, 0x00000002, 0x0000000E, 0x00000000, 0x00000002, 0x00000000, 0x00000002, 0x00000007, 0x00000000, 0x00000008, 0x00000002, 0x0000000F, 0x00000000, 0x00000002, 0x00000000, 0x00000002, 0x00000009, 0x00000000, 0x00000012, 0x00000007, 0x00000000, 0x00000005, 0x00000002, 0x00000010, 0x00000000, 0x00000002, 0x00000000, 0x0000000E, 0x0000000B, 0x00000000, 0x0000000F, 0x0000000B, 0x00000000, 0x00000010, 0x00000007, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x0000000A, 0x00000000, 0x00000011, 0x00000007, 0x00000000, 0x00000006, 0x00000002, 0x0000000E, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000007, 0x00000000, 0x00000008, 0x00000002, 0x0000000F, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000009, 0x00000000, 0x00000012, 0x00000007, 0x00000000, 0x00000007, 0x00000002, 0x00000010, 0x00000000, 0x00000002, 0x00000000, 0x0000000E, 0x0000000B, 0x00000000, 0x0000000F, 0x0000000B, 0x00000000, 0x00000010, 0x00000007, 0x00000002, 0x00000000, 0x00000008, 0x0000000B, 0x0000000C, 0x0000000E, 0x0000000B, 0x0000000A, 0x0000000C, 0x00000014, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006E, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0000006F, 0x00000062, 0x00000000, 0x00000000, 0x0000000C, 0x00000014, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000079, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000065, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000073, 0x00000062, 0x00000000, 0x00000000, 0x0000000C, 0x00000014,0]
f=[]
for i in range(0,len(op),3):
   if op[i]+1 not in f:
       f.append(op[i]+1)

print(bytes.fromhex('61336366'))
for i in range(0,len(op),3):

    adr=op[i]+1
    Lnum=op[i+1]
    Rnum=op[i+2]

    if adr==1:
        print("%s: "%hex(i)+f"nop")
    elif adr==2:
        print("%s: "%hex(i)+f"mov r[{Lnum}],{hex(Rnum)}")
    elif adr==3:
        print("%s: "%hex(i)+f"mov r[{Lnum}],r[{Rnum}]")
    elif adr==6:
        print("%s: "%hex(i)+f"push r[{Lnum}]")
    elif adr==7:
        print("%s: "%hex(i)+f"pop r[{Lnum}]")
    elif adr==8:
        print("%s: "%hex(i)+f"add r[{Lnum}],r[{Rnum}]")
    elif adr==9:
        print("%s: "%hex(i)+f"sub r[{Lnum}],r[{Rnum}]")
    elif adr==10:
        print("%s: "%hex(i)+f"div r[{Lnum}],r[{Rnum}]")
    elif adr==11:
        print("%s: "%hex(i)+f"mul r[{Lnum}],r[{Rnum}]")
    elif adr==12:
        print("%s: "%hex(i)+f"xor r[{Lnum}],r[{Rnum}]")
    elif adr==13:
        print("%s: "%hex(i)+f"jmp r[{Lnum}]")
    elif adr==15:
        print("%s: "%hex(i)+f"cmp r[{Lnum}],r[{Rnum}] -- jnz r[19]")
    elif adr==0x62:
        print("%s: "%hex(i)+f"getchar(r[{Lnum}])")
    elif adr==0x63:
        print("%s: "%hex(i)+f'putchar(r[{Lnum})]')
    elif adr==0x64:
        print("%s: "%hex(i)+f"exit()")

伪码

截取片段,前面的putchar 输出 VNCTF等提示符

0xcc: mov r[19],0x49
0xcf: mov r[3],0x0
0xd2: mov r[1],0x2b     #长度0x2b
0xd5: mov r[2],0x1
0xd8: getchar(r[0])
0xdb: push r[0]         #输入进栈
0xde: sub r[1],r[2]
0xe1: cmp r[1],r[3] -- jnz r[19]

arry2int

4个Byte转为 int

0xe4: mov r[0],0x0
0xe7: push r[0]
0xea: nop
0xed: nop
0xf0: pop r[0]
0xf3: mov r[5],0x100
0xf6: mul r[0],r[5]
0xf9: mov r[6],r[0]
0xfc: pop r[0]
0xff: add r[6],r[0]
0x102: mov r[0],r[6]
0x105: mul r[0],r[5]
0x108: mov r[6],r[0]
0x10b: pop r[0]
0x10e: add r[6],r[0]
0x111: mov r[0],r[6]
0x114: mul r[0],r[5]
0x117: mov r[6],r[0]
0x11a: pop r[0]
0x11d: add r[6],r[0]
0x120: nop

Tea

0x3f9: mov r[3],0x9e3779b9 ;delta
0x3fc: mov r[4],0x95c4c    ;key
0x3ff: mov r[5],0x871d
0x402: mov r[6],0x1a7b7
0x405: mov r[7],0x12c7c7
0x408: mov r[8],0x0
0x40b: mov r[17],0x10
0x40e: mov r[18],0x20
0x411: mov r[19],0x160
0x414: mov r[10],0x0
0x417: mov r[11],0x20
0x41a: mov r[12],0x1
0x41d: add r[8],r[3]
0x420: mov r[0],r[2]
0x423: mul r[0],r[17]
0x426: add r[0],r[4]
0x429: mov r[14],r[0]
0x42c: mov r[0],r[2]
0x42f: add r[0],r[8]
0x432: mov r[15],r[0]
0x435: mov r[0],r[2]
0x438: div r[0],r[18]
0x43b: add r[0],r[5]
0x43e: mov r[16],r[0]
0x441: mov r[0],r[14]
0x444: xor r[0],r[15]
0x447: xor r[0],r[16]
0x44a: add r[1],r[0]
0x44d: mov r[0],r[1]
0x450: mul r[0],r[17]
0x453: add r[0],r[6]
0x456: mov r[14],r[0]
0x459: mov r[0],r[1]
0x45c: add r[0],r[8]
0x45f: mov r[15],r[0]
0x462: mov r[0],r[1]
0x465: div r[0],r[18]
0x468: add r[0],r[7]
0x46b: mov r[16],r[0]
0x46e: mov r[0],r[14]
0x471: xor r[0],r[15]
0x474: xor r[0],r[16]
0x477: add r[2],r[0]
0x47a: sub r[11],r[12]
0x47d: cmp r[11],r[10] -- jnz r[19]
0x480: jmp r[20]
0x483: nop

Tea没有魔改,用mul和div实现的左右移

0x348: mov r[20],0x11c
0x34b: mov r[0],0x154
0x34e: jmp r[0]
0x351: mov r[0],0xe8d1d5df
0x354: mov r[19],0x183
0x357: mov r[20],0x153
0x35a: cmp r[1],r[0] -- jnz r[19]
0x35d: mov r[0],0xf5e3c114
0x360: cmp r[2],r[0] -- jnz r[19]
0x363: pop r[1]
0x366: pop r[2]
0x369: mov r[20],0x127
0x36c: mov r[0],0x154
0x36f: jmp r[0]
0x372: mov r[0],0x228ec216
0x375: mov r[19],0x183
0x378: mov r[20],0x153
0x37b: cmp r[1],r[0] -- jnz r[19]
0x37e: mov r[0],0x89d45a61
0x381: cmp r[2],r[0] -- jnz r[19]
0x384: pop r[1]
0x387: pop r[2]
0x38a: mov r[20],0x132
0x38d: mov r[0],0x154
0x390: jmp r[0]
0x393: mov r[0],0x655b8f69
0x396: mov r[19],0x183
0x399: mov r[20],0x153
0x39c: cmp r[1],r[0] -- jnz r[19]
0x39f: mov r[0],0x2484a07a
0x3a2: cmp r[2],r[0] -- jnz r[19]
0x3a5: pop r[1]
0x3a8: pop r[2]
0x3ab: mov r[20],0x13d
0x3ae: mov r[0],0x154
0x3b1: jmp r[0]
0x3b4: mov r[0],0xd9e5e7f8
0x3b7: mov r[19],0x183
0x3ba: mov r[20],0x153
0x3bd: cmp r[1],r[0] -- jnz r[19]
0x3c0: mov r[0],0x3a441532
0x3c3: cmp r[2],r[0] -- jnz r[19]
0x3c6: pop r[1]
0x3c9: pop r[2]
0x3cc: mov r[20],0x148
0x3cf: mov r[0],0x154
0x3d2: jmp r[0]
0x3d5: mov r[0],0x91ab7e88
0x3d8: mov r[19],0x183
0x3db: mov r[20],0x153
0x3de: cmp r[1],r[0] -- jnz r[19]
0x3e1: mov r[0],0x69fc64bc
0x3e4: cmp r[2],r[0] -- jnz r[19]
0x3e7: pop r[1]
0x3ea: mov r[0],0x7d3765
0x3ed: cmp r[1],r[0] -- jnz r[19]
0x3f0: mov r[0],0x189
0x3f3: jmp r[0]
0x3f6: exit()

长度44,转为int是11个,前10个两两一组Tea,最后一个不处理,解密即可。

#include<iostream>
#define ut32 unsigned int
#define delta 0x9E3779B9
void Tea_Decrypt(ut32* enc, ut32* k) {
	ut32 sum = delta * 0x20;
	ut32 v0 = enc[0];
	ut32 v1 = enc[1];
	for (int i = 0; i < 0x20; i++) {
		v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
		v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
		sum -= delta;
	}
	enc[0] = v0;
	enc[1] = v1;
}


int main() {
	ut32 m[2] = { 0xe8d1d5df,0xf5e3c114 }; //依次密文
	ut32 k[4] = { 0x95c4c,0x871d,0x1a7b7,0x12c7c7};
	Tea_Decrypt(m, k);
	printf("%x %x", m[0], m[1]);
	return 0;
}
//常规Tea解密
//VNCTF{ecd63ae5-8945-4ac4-b5a5-34fc3ade81e7}

cm1

Android题主要逻辑在隐藏的一个dex文件中

主要是copyfile这个函数

    public static void copyFiles(android.content.Context r6, java.lang.String r7, java.io.File r8) {
    
            java.lang.String r0 = "vn2022"
            byte[] r0 = r0.getBytes()
            r1 = 0
            android.content.Context r6 = r6.getApplicationContext()     // Catch: IOException -> 0x005a, all -> 0x0056
            android.content.res.AssetManager r6 = r6.getAssets()     // Catch: IOException -> 0x005a, all -> 0x0056
            java.io.InputStream r6 = r6.open(r7)     // Catch: IOException -> 0x005a, all -> 0x0056
            java.io.FileOutputStream r7 = new java.io.FileOutputStream     // Catch: IOException -> 0x0052, all -> 0x004f
            java.lang.String r8 = r8.getAbsolutePath()     // Catch: IOException -> 0x0052, all -> 0x004f
            r7.<init>(r8)     // Catch: IOException -> 0x0052, all -> 0x004f
            r8 = 1024(0x400, float:1.435E-42)
            byte[] r8 = new byte[r8]     // Catch: IOException -> 0x004d, all -> 0x004b
        L_0x0020:
            int r1 = r6.read(r8)     // Catch: IOException -> 0x004d, all -> 0x004b
            r2 = -1
            if (r1 == r2) goto L_0x003f
            r2 = 0
            r3 = 0
        L_0x0029:
            if (r3 >= r1) goto L_0x003b
            byte r4 = r8[r3]     // Catch: IOException -> 0x004d, all -> 0x004b
            int r5 = r0.length     // Catch: IOException -> 0x004d, all -> 0x004b
            int r5 = r3 % r5
            byte r5 = r0[r5]     // Catch: IOException -> 0x004d, all -> 0x004b
            r4 = r4 ^ r5
            r4 = r4 & 255(0xff, float:3.57E-43)
            byte r4 = (byte) r4     // Catch: IOException -> 0x004d, all -> 0x004b
            r8[r3] = r4     // Catch: IOException -> 0x004d, all -> 0x004b
            int r3 = r3 + 1
            goto L_0x0029
        L_0x003b:
            r7.write(r8, r2, r1)     // Catch: IOException -> 0x004d, all -> 0x004b
            goto L_0x0020

有点小坑,这里是1024byte读取一次,每次重新开始与vn2022异或

re dex

key=b'vn2022'
f1=open(r'ooo','rb+')
f2=open(r'111','wb+')
while True:
    t=[]
    s=f1.read(1024)
    if len(s)==0:
        break
    for i in range(len(s)):
       t.append(s[i]^key[i%len(key)])
    f2.write(bytes(t))

image-20220212235258147

主体是XXtea,其余就是一些 arry2int 小端序变化 ,XXTea脚解密本即可,delta没魔改(-法转为+法补码是一样的)

获取key和enc,其实就是小端序转int

from Crypto.Util.number import *
a=b'H4pPY_VNCTF!!OvO'
r=[0]*4
for i in range(16):
    i2 = i >> 2
    r[i2] = r[i2] | ((a[i] & 255) << ((i & 3) << 3))
for i in r:
    print(hex(i),end=',')

print()
enc=[0]*11
c=[0x44 ,0x27 ,0xffffffa4 ,0x6c ,0xffffffae ,0xffffffee ,0x48 ,0xffffffc9 ,0x4a ,0xffffffc8 ,0x26 ,0x0b ,0x3c ,0x54 ,0x61 ,0xffffffd8 ,0x57 ,0x47 ,0x63 ,0xffffffae ,0x78 ,0x68 ,0x2f ,0xffffffb9 ,0xffffffc6 ,0xffffffc7 ,0x00 ,0x21 ,0x2a ,0x26 ,0xffffffd4 ,0xffffffd9 ,0xffffffc4 ,0x71 ,0xfffffffe ,0x5c ,0xffffffb5 ,0x76 ,0xffffffb3 ,0x32 ,0xffffff87 ,0x2b ,0x20 ,0xffffff96]
for i in range(len(c)):
    i2 = i >> 2
    enc[i2] = enc[i2] | ((c[i] & 255) << ((i & 3) << 3))
for i in enc:
    print(hex(i),end=',')
print()
key=[0x50703448,0x4e565f59,0x21465443,0x4f764f21]
enc=[0x6ca42744,0xc948eeae,0xb26c84a,0xd861543c,0xae634757,0xb92f6878,0x2100c7c6,0xd9d4262a,0x5cfe71c4,0x32b376b5,0x96202b87]

XXtea

#include <stdint.h>
#include<stdio.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))

void btea(uint32_t* v, int n, uint32_t const key[4]) {
    uint32_t y, z, sum;
    unsigned p, rounds, e;
    if (n > 1) {          /* Coding Part */
        rounds = 6 + 52 / n; //加密轮数
        sum = 0;
        z = v[n - 1];
        do {
            sum += DELTA;
            e = (sum >> 2) & 3;
            for (p = 0; p < n - 1; p++) {
                y = v[p + 1];
                z = v[p] += MX;
            }
            y = v[0];
            z = v[n - 1] += MX;
        } while (--rounds);
    }

    else if (n < -1) {  /* Decoding Part */
        n = -n;
        rounds = 6 + 52 / n;
        sum = rounds * DELTA;
        y = v[0];
        do {
            e = (sum >> 2) & 3;
            for (p = n - 1; p > 0; p--) {
                z = v[p - 1];
                y = v[p] -= MX;
            }
            z = v[n - 1];
            y = v[0] -= MX;
            sum -= DELTA;
        } while (--rounds);
    }
}


int main() {
    unsigned int m[11] = { 0x6ca42744,0xc948eeae,0xb26c84a,0xd861543c,0xae634757,0xb92f6878,0x2100c7c6,0xd9d4262a,0x5cfe71c4,0x32b376b5,0x96202b87 };
    unsigned int k[4] = { 0x50703448,0x4e565f59,0x21465443,0x4f764f21 };
    btea(m, -11, k);
	for (int i = 0; i < 11; i++) {
		printf("0x%x ,",m[i]);
	}
	return 0;
}

//VNCTF{93ee7688-f216-42cb-a5c2-191ff4e412ba} 

时空飞行

首先是求日期,处理函数类似SM4的秘钥扩展,不过L函数魔改了

void __fastcall SM4_keyInit(_DWORD *a1, unsigned int *a2)
{
  int v2; // esi
  int v3; // ebx
  int v4[36]; // [rsp+20h] [rbp-B0h]
  unsigned int v5; // [rsp+B0h] [rbp-20h]
  unsigned int v6; // [rsp+B4h] [rbp-1Ch]
  unsigned int v7; // [rsp+B8h] [rbp-18h]
  unsigned int v8; // [rsp+BCh] [rbp-14h]
  int i; // [rsp+CCh] [rbp-4h]

  v5 = _byteswap_ulong(*a2);
  v6 = _byteswap_ulong(a2[1]);
  v7 = _byteswap_ulong(a2[2]);
  v8 = _byteswap_ulong(a2[3]);
  v4[0] = v5 ^ 0xA3B1BAC6;
  v4[1] = v6 ^ 0x56AA3350;
  v4[2] = v7 ^ 0x677D9197;
  v4[3] = v8 ^ 0xB27022DC;
  for ( i = 0; i <= 31; ++i )
  {
    v2 = i + 4;
    v3 = v4[i];
    v4[v2] = sub_401A3B(v4[i + 3] ^ v4[i + 2] ^ (unsigned int)v4[i + 1] ^ CK[i]) ^ v3;
    a1[i] = v4[i + 4];
  }
}

__int64 __fastcall sub_401A3B(int a1)
{
  return a1 ^ (unsigned int)(__ROL4__(a1, 13) ^ __ROR4__(a1, 9));
}

给出了Rkey的后4位,直接逆序往前推即可,主要加密是异或,具有对称性。

def L(a):
    x=((a<<13)|(a>>(32-13)))&0xffffffff
    y=((a>>9)|(a<<(32-9)))&0xffffffff
    return x^y^a
FK=[0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]
CK=[0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
    0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249, 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
    0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229, 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
    0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209, 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279]

def change(k):
    for i in range(4):
        k[i]^=FK[i]
    for i in range(32):
        tmp=L(k[i+1]^k[i+2]^k[i+3]^CK[i])
        k.append(tmp^k[i])
    for i in range(4,36):
        print(hex(k[i]),end=',')

def reverse():
    k=[0]*36
    k[32] = 0xFD07C452
    k[33] = 0xEC90A488
    k[34] = 0x68D33CD1
    k[35] = 0x96F64587
    for i in range(31,-1,-1):
        tmp=L(k[i+1]^k[i+2]^k[i+3]^CK[i])
        k[i]=tmp^k[i+4]
    for i in range(4):
        k[i] ^= FK[i]
    for i in range(4):
        print(int.to_bytes(k[i],4,'big').decode(),end='')

reverse()
#20211205

之后又进行输入,第一次处理函数类似AES秘钥扩展

  for ( i = 0; i <= 5; ++i )
    a1[i] = sub_401E21((char *)(4 * i + a2));   // 大端序
  v5 = 6;
  v3 = 0;
  while ( v5 <= 65 )
  {
    if ( v5 % 6 )
    {
      a1[v5] = a1[v5 - 6] ^ a1[v5 - 1];
    }
    else
    {
      v2 = a1[v5 - 6];
      a1[v5] = v2 ^ sub_401FFB(a1[v5 - 1], v3++);
    }
    ++v5;
  }
}

__int64 __fastcall sub_401FFB(unsigned int a1, int a2)
{
  char v3[28]; // [rsp+20h] [rbp-20h] BYREF
  unsigned int v4; // [rsp+3Ch] [rbp-4h]

  int_to_array(a1, v3);                         // 大端
  shift_left1(v3, 1i64);						//左移一
  v4 = array_to_int(v3);						// 大端
  return v4 ^ round_key[a2];					//异或轮秘钥
}

之后转为小端序进行一个不可逆的异或处理。

  for ( i = 0; i <= 5; ++i )                    // 扩展为66 v5是24个字节
  {
    v4[4 * i] = (unsigned __int8)ext_key[i + 60];
    v4[4 * i + 1] = (unsigned __int8)BYTE1(ext_key[i + 60]);
    v4[4 * i + 2] = (unsigned __int8)BYTE2(ext_key[i + 60]);
    v4[4 * i + 3] = HIBYTE(ext_key[i + 60]);
  }                                             // v4是最后一轮key
  for ( i = 1; i <= 23; ++i )
    v4[i - 1] ^= (v4[i - 1] % 0x12u + v4[i] + 5) ^ 0x41;

之前遇到过类似不可逆的处理,可以用dfs爆破所有结果。

import struct, copy
#key1='20211205'
def arr2int(k):      #小端
    m=[0]*(len(k)//4)
    for i in range(len(k)):
        m[i//4]|=k[i]<<((i&3)*8)
    return m

def F(a,round):
    s=hex(a)[2:].zfill(8)
    k=[]
    for i in range(0,8,2): #大端序
       k.append(int(s[i:i+2],16))
    m=[0]*4
    m[0]=k[1]
    m[1]=k[2]
    m[2]=k[3]
    m[3]=k[0]

    ans=0
    for i in range(4):
        ans|=m[i]<<((3-i)*8)

    return ans^rk[round]


def dfs_get_cipher2(k):                                 # 递归枚举所可能的密文
    if k == 0:
        cipher_list.append(copy.deepcopy(c))
        return
    for j in range(0x100):
        if final[k-1] ==  j^(j%0x12+c[k] + 5)^0x41 :
            c[k-1] = j
            dfs_get_cipher2(k-1)

final = b'%\x15\xdf\xa2\xc0\x93\xad\x14F\xc5\x0f.\x9a\xeb0\xf8 \xe9\xcb\x88\xc6\xbe\x8d\xe3'
c = [-1] * 24
c[23] = final[23]
cipher_list = []
dfs_get_cipher2(23)
k=cipher_list[0]

rk=[0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000]
for k in cipher_list:    
    m=arr2int(k)
    ff=[0]*60
    ff.extend(m)

    v3=9
    for i in range(59,-1,-1):
        if i%6!=0:
            ff[i]=ff[i+6]^ff[i+5]
        else:
            ff[i]=ff[i+6]^F(ff[i+5],v3)
            v3-=1
    for i in range(6):
       try:
            print(int.to_bytes(ff[i],4,'big').decode(),end='')
       except:
           break
    print()
#VNCTF{TimeFlightMachine}  爆破筛选结果

#VNCTF{TimeFl20211205ightMachine}

加密都是异或,第一步AES秘钥扩展也比较容易

不虚此行,别等叶枯萎。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值