[Dreamhack] Collect Me

chrmqgozj·2025년 2월 6일

DreamHack

목록 보기
17/39
  1. main
int __fastcall main(int argc, const char **argv, const char **envp)
{
  puts(&s);
  puts("# Program Description");
  puts(" - I have so many functions. (func_0, func_1, ..., func_927)");
  puts(" - Each function has 1 characater as local variable.");
  puts(&s);
  puts("# To Do");
  puts("1. Collect those characters and convert them as a string.");
  puts("2. Find DH{[a-z0-9][32]} from the string!");
  puts(&s);
  return 0;
}

문제 설명처럼 func_0부터 func_927까지 순차적으로 실행시켜서 플래그를 얻으면 된다.
근데 어떻게...?

  1. gdb_script
    이전에 배운 gdb_script에 대해서 기억이 났다. (감사합니다, 선배님...)
    받은 자료들 다시 보면서 공부하는데 머리 터지는 줄...

수많은 시행착오 끝에 기틀을 마련했다.

import gdb

ge = gdb.execute

ge("file ./collect_me")

addr = str(gdb.parse_and_eval('func_900').address).split()[0]

print(int(addr,16))

gdb.parse_and_eval을 활용하면 gdb.Value로 값을 받는다. 그래서 address로 앞의 설명을 한 번 걸러주고 split을 통해 함수명과 주소를 분리한 뒤, str로 타입 변경을 한다. 마지막으로 주소가 0번째 인덱스이기 때문에 [0]로 주소를 따로 빼낸다. (수정이 가능한 값이 아니기 때문에 list로 바로 변환은 힘들다.)

  1. 주소

addr + 0xc에 breakpoint를 걸고 rbp-1에 저장된 값을 찾으면 된다.
아니지, 애초에 저 func에 갈 일도 없으니까 그냥 저 주소값을 가져오면 된다.

11만큼 차이나는 위치에 저장되어 있다.

  1. exploit.py
import gdb

ge = gdb.execute
inferior = gdb.selected_inferior()

ge("file ./collect_me")

f = 'func_'
flag = b''

for i in range(928):
    addr = int(str(gdb.parse_and_eval(f+str(i)).address).split()[0], 16)
    val = bytes(inferior.read_memory(addr+0xb, 1))
    flag += val

print(flag)

0개의 댓글