Description

    드림이의 VM이 해킹당했어요! 나쁜 해커가 채굴을 위해 입력한 플래그를 찾아주세요!

    Files

    ubuntu@WSL2:~/CTF/dreamhack.io$ tree Infested\ Terran/
    Infested Terran/
    ├── bzImage
    ├── rootfs.ext2
    └── run.sh
    
    0 directories, 3 files
    
    ubuntu@WSL2:~/CTF/dreamhack.io$ file Infested\ Terran/bzImage
    Infested Terran/bzImage: Linux kernel x86 boot executable bzImage, version 5.15.18 (bincat@bincat-16) #1 SMP Fri Jun 17 05:31:19 UTC 2022, RO-rootFS, swap_dev 0X4, Normal VGA
    
    ubuntu@WSL2:~/CTF/dreamhack.io$ file Infested\ Terran/rootfs.ext2
    Infested Terran/rootfs.ext2: Linux rev 1.0 ext2 filesystem data (mounted or unclean), UUID=2c70f850-c8ab-4128-83c3-dedd3b97231f, volume name "rootfs" (large files)
    
    ubuntu@WSL2:~/CTF/dreamhack.io$ cat Infested\ Terran/run.sh
    #!/bin/sh
    
    qemu-system-x86_64 \
        -M pc \
        -kernel ./bzImage \
        -drive file=./rootfs.ext2,if=virtio,format=raw \
        -append "root=/dev/vda console=ttyS0" \
        -net nic,model=virtio -net user \
        -nographic

    qemu를 통해 vm 이미지를 실행시키는 듯 하다.

    분석

    root 계정으로 비밀번호 없이 로그인할 수 있었다.

    그리고 실행 파일을 둘러보던 중, /usr/bin 경로에 수상한 sl 바이너리 파일을 구할 수 있다.

    void __fastcall __noreturn main(int a1, char **a2, char **a3)
    {
      int i; // [rsp+1Ch] [rbp-14h]
      int j; // [rsp+20h] [rbp-10h]
      int k; // [rsp+24h] [rbp-Ch]
      __int64 v6; // [rsp+28h] [rbp-8h]
    
      for ( i = 0; i <= 35; ++i )
      {
        off_55EDC37673A0[i] = (__int64)calloc(1uLL, 32uLL);
        *(_BYTE *)off_55EDC37673A0[i] = a2[1][i];
      }
      for ( j = 0; j <= 35; ++j )
      {
        v6 = 0LL;
        for ( k = 0; k <= j; ++k )
          v6 += *(_QWORD *)off_55EDC37673A0[k] * qword_55EDC3767020[k];
        qword_55EDC3767280[j] = v6;
        if ( qword_55EDC3767280[j] != qword_55EDC3767140[j] )
        {
          puts("who are u?");
          exit(-1);
        }
      }
      puts("ok I know you!");
      sub_55EDC37641C9();
    }

    Solution

    위 바이너리의 디컴파일한 main 소스를 Python3 코드로 구현시키고,

    역산은 머리써야되서 귀찮아서
    그냥 한 문자의 아스키코드값에 계속 1씩 늘려가면서 때려 맞추는 것으로 끝냈다.

    qword_563C10D7F020 = [0x03, 0x01, 0x03, 0x03, 0x07, 0x01, 0x05, 0x57,\
                          0x65, 0x27, 0x72, 0x65, 0x20, 0x67, 0x6F, 0x6E,\
                          0x6E, 0x61, 0x20, 0x62, 0x65, 0x20, 0x72, 0x69,\
                          0x63, 0x68, 0x3F, 0x20, 0x6E, 0x65, 0x76, 0x65,\
                          0x72, 0x2E, 0x2E, 0x2E]
    
    qword_55EDC3767140 = [0x000CC, 0x00114, 0x00285, 0x0032A, 0x005D1, 0x00632, 0x00736, 0x028DB,\
                          0x05119, 0x0607C, 0x08BAE, 0x09FCD, 0x0A5CD, 0x0B91D, 0x0CECB, 0x0E36B,\
                          0x0FB7B, 0x10F2F, 0x1154F, 0x12811, 0x13DC4, 0x144E4, 0x15D62, 0x1745A,\
                          0x1899F, 0x1B2A7, 0x1BFF1, 0x1C6B1, 0x1F0CD, 0x2074A, 0x21DE0, 0x244EF,\
                          0x271E9, 0x27B9D, 0x284C7, 0x29B3D]
    
    
    flag = [0] * 36
    qword_55EDC3767280 = [0] * 36
    
    for i in range(36):
        v6 = 0
    
        while True:
            for j in range(i+1):
                v6 = v6 + flag[j] * qword_563C10D7F020[j]
    
            if(v6 == qword_55EDC3767140[i]):
                qword_55EDC3767280[i] = v6
                break
    
            flag[i] = flag[i] + 1
            v6 = 0
    
    for i in range(len(flag)):
        print(chr(flag[i]), end='')

    FLAG

    DH{7aa4cfea30020841179787e66b91ce63}

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다