DDCTF2019 confused WP

31733 ワード

前言

  • しばらくブログを更新していませんが、主に用事が多すぎます.これは上半期の試合が残した問題で、よく考えてみることにした.その後hackgame 2019の一部の問題解と他のプラットフォーム上の問題解が更新される.

  • ぶんせき

  • これはELF 64ビットの仮想マシンの逆方向です.まず、仮想マシン関数を初期化します:
  • void *__fastcall init_vm(VM *vm, const void *input)
    {
      vm->reg_0 = 0;
      vm->reg_1 = 0;
      vm->reg_2 = 0;
      vm->reg_3 = 0;
      LODWORD(vm->field_10) = 0;
      *&vm->flag = 0;
      LOBYTE(vm->v0) = 0xF0u;
      vm->func_0 = mov_reg0_mem;
      vm->gap30[0] = 0xF1u;
      *&vm->func_1 = xor_reg0_reg1;
      LOBYTE(vm->v2) = 0xF2u;
      vm->func_2 = cmp_reg0_mem;
      LOBYTE(vm->v3) = 0xF4u;
      vm->func_3 = func_add_reg0_reg1;
      LOBYTE(vm->v4) = 0xF5u;
      vm->func_4 = func_sub_reg0_reg1;
      LOBYTE(vm->v5) = 0xF3u;
      vm->func_5 = nullptr;
      LOBYTE(vm->v6) = 0xF6u;
      vm->func_6 = jz_opcode;
      LOBYTE(vm->v7) = 0xF7u;
      vm->func_7 = move_flag_mem;
      LOBYTE(vm->v8) = 0xF8u;
      vm->func_8 = Encode_reg_0;
      ::input = malloc(0x400uLL);
      return memccpy(::input + 48, input, 1, 18uLL);
    }
    
  • は、VM構造体
  • を構築することができる
    struct VM{
        int reg_0;
        int reg_1;
        int reg_2;
        int reg_3;
        int field_10;
        char* opcode;
        int v0;
        ...
        void* func_0;
        ...
        void* func_1;
        ...
        int v2 ;
        ...
        void* func_2;
        int v3;
        ...
        void* func_3;
        int v4;
        ...
        void* func_4;
        int v5;
        ...
        void* func_5;
        int v6;
        ...
        void* func_6;
        int v7;
        ...
        void* func_7;
        int v8;
        ...
        void* func_8;
        int flag;
    };
    
    
  • ダイナミックデバッグ、プログラムに従って、その流れを発見するのは難しくありません:
  • は、まず19文字を入力し、仮想マシンを初期化します.
  • 仮想マシンの実行プロセスは、
  • です.
    1) vm->reg_0=*(vm->opcode+2),opcode+=6
    2) vm->reg_0=Encode(vm->reg_0,2),vm->opcode++// ,key=2 
    3) vm->field_10=vm->reg_0==input[0],vm->opcode+=2// (5), (6)
    5) vm->field_0=0,vm->opcode+=2// (8)
    6) vm->opcode+=*(vm->opcode+1),vm->opcode+=2// (7)
    7) vm->flag=*(vm->opcode+1),vm->opcode+=5// (9)
    8)   (1)~(5) 19  (7)
    9)  
      vm->flag==1  , 
    
  • は実際には19回Encode(opcode[2+11*i])=input[i]?に表示されます.

  • スクリプト#スクリプト#

    code=[\
        240,16,102,0,0,0,248,242,48,246,193,240,16,99,0,0,0,248,242,49,246,182,240,16,106,0,0,0,248,242,50,246,171,240,16,106,0,0,0,248,242,51,246,160,240,16,109,0,0,0,248,242,52,246,149,240,16,87,0,0,0,248,242,53,246,138,240,16,109,0,0,0,248,242,54,246,127,240,16,115,0,0,0,248,242,55,246,116,240,16,69,0,0,0,248,242,56,246,105,240,16,109,0,0,0,248,242,57,246,94,240,16,114,0,0,0,248,242,58,246,83,240,16,82,0,0,0,248,242,59,246,72,240,16,102,0,0,0,248,242,60,246,61,240,16,99,0,0,0,248,242,61,246,50,240,16,68,0,0,0,248,242,62,246,39,240,16,106,0,0,0,248,242,63,246,28,240,16,121,0,0,0,248,242,64,246,17,240,16,101,0,0,0,248,242,65,246,6,247,1,0,0,0,243,247,0,0,0,0,243,93,195,15,31,132,0,0,0,0,0\
    ]
    flag=''
    
    def Encode(v,k):
        v5=False
        if v>64:
            v5=v<=90
        if v5:
            v3=(v+k-65)%26+65
        else:
            v4=False
            if v>96:
                v4=v<=122
            if v4:
                v3=(v+k-97)%26+97
            else:
                v3=v
        return v3
    
    for i in range(19):
        flag+=chr(Encode(code[2+i*11],2))
    print flag
    
  • flag: helloYouGotTheFlag

  • まとめ

  • これはVM逆方向のタイプであり、opcodeが与えられ、入力されたデータがopcodeの実行結果に合致することが要求される.DDCTF 2018には、仮想マシンの実行結果がプログラムに与えられたものと一致するように、opcodeを自分で構築する必要がある.現在のところ、仮想マシンに関する考察では、この2つに遭遇しています.
  • も良い方法はありません.まず仮想マシンの構造をよく把握し、プログラムを追跡し、意図を把握することです.これ以上だめならサイドチャネルにしましょう~