[dreamhack] Recover

IMKYU·2024년 11월 24일

문제

문제 설명

  • chall를 아이다로 분석하자
  • 디스 어셈블하면
    __int64 __fastcall main(int a1, char **a2, char **a3)
    {
      char ptr; // [rsp+Bh] [rbp-25h] BYREF
      int v5; // [rsp+Ch] [rbp-24h]
      _BYTE *v6; // [rsp+10h] [rbp-20h]
      FILE *stream; // [rsp+18h] [rbp-18h]
      FILE *s; // [rsp+20h] [rbp-10h]
      unsigned __int64 v9; // [rsp+28h] [rbp-8h]
    
      v9 = __readfsqword(0x28u);
      v6 = &unk_2004;
      stream = fopen("flag.png", "rb");
      if ( !stream )
      {
        puts("fopen() error");
        exit(1);
      }
      s = fopen("encrypted", "wb");
      if ( !s )
      {
        puts("fopen() error");
        fclose(stream);
        exit(1);
      }
      v5 = 0;
      while ( fread(&ptr, 1uLL, 1uLL, stream) == 1 )
      {
        ptr ^= v6[v5 % 4];
        ptr += 19;
        fwrite(&ptr, 1uLL, 1uLL, s);
        ++v5;
      }
      fclose(stream);
      fclose(s);
      return 0LL;
    }
  • flag.png를 암호화 하고 있다.
  • 반복문을 보면
    • 바이트 하나씩 v6값을 사용하여 xor, 19를 더하면서 암호화를 하고 있다.
    • 복호화하려면 unk_2004가 무엇인지 알아내고 -19하고 xor연산을 한번 더하면 된다.
    • unk_2004
      .rodata:0000000000002004 unk_2004        db 0DEh                 ; DATA XREF: main+1B↑o
      .rodata:0000000000002005                 db 0ADh
      .rodata:0000000000002006                 db 0BEh
      .rodata:0000000000002007                 db 0EFh
    • 복호화 파일
      #include <stdio.h>
      #include <stdlib.h>
      
      int main() {
          char ptr;
          int v5 = 0;
          unsigned char v6[4] = {0xDE, 0xAD, 0xBE, 0xEF}; // XOR 키 값
          FILE *encrypted_file = fopen("encrypted", "rb");
          FILE *decrypted_file = fopen("decrypted.png", "wb");
          
          if (!encrypted_file) {
              puts("fopen() error for encrypted file");
              exit(1);
          }
          
          if (!decrypted_file) {
              puts("fopen() error for decrypted file");
              fclose(encrypted_file);
              exit(1);
          }
          
          while (fread(&ptr, 1, 1, encrypted_file) == 1) {
              // 복호화 과정: 암호화의 역순으로 연산을 수행
              ptr -= 0x13;              
              ptr ^= v6[v5 % 4];          
              fwrite(&ptr, 1, 1, decrypted_file);
              ++v5;
          }
          
          fclose(encrypted_file);
          fclose(decrypted_file);
          return 0;
      }
  • 성공
profile
아무것도 안 한 거랑 다를께 없잖아??

0개의 댓글