콘텐츠로 건너뛰기

Infested Terran

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}

태그:

답글 남기기