해보자고

[드림핵] Small counter 본문

리버싱

[드림핵] Small counter

초코맛동산 2025. 4. 10. 20:08

# 문제

문제 링크 | https://dreamhack.io/wargame/challenges/851

 

Small Counter

Description 플래그를 생성하는 함수 flag_gen()을 호출하고 플래그를 출력하세요. 플래그 형식은 DH{...} 입니다. Hint: https://dreamhack.io/lecture/courses/55

dreamhack.io

플래그를 생성하는 함수 flag_gen()을 호출하고 플래그를 출력하세요.

1. 실행 흐름 훑어보기 

flag_gen()



flag_gen() 함수를 분석해서 플래그 값이 어떤 값이 나올지를 확인하려다가, 문제가 원하는 바는 이 함수를 호출하는 조건을 찾아서 호출하는 것이기에 flag_gen() 으로 분기하는 부분을 확인해보고자 했습니다. 

 

 

main 함수에서 flag_gen()을 호출하고 있는 것을 확인했습니다. 어셈블리어로 자세히 확인해보도록 하겠습니다. 

 

 

cmp를 통해 [rbp+var_4]와 5를 비교해서 같으면(ZF=1) jnz를 통해 flag_gen() 함수로 이어지고, 다르면(ZF=0) jnz를 통해 loc_15FE 함수로 이동하는 분기문이 플래그의 힌트임을 IDA를 통해 알 수 있었다. 

 

이렇게 문제를 풀 수 있는 실행 흐름을 확인했으니, 디버깅을 통해 값을 패치하고, flag_gen()을 호출해보자. 

 

2. 디버깅

개인적으로는 xdbg가 gdb보다 편한데, 주어진 파일이 elf 파일이라 gdb로 문제를 풀게 되었다. (gdb 복습이 필요함을 깨닫고 절망과 오열중...) 

 

 

프로그램 자체는 되게 심플하게 실행되는 것을 알 수 있다. main 함수를 disassemble 해보면 아래와 같이 어셈블리 코드들을 확인할 수 있다. 

 

 

네모 박스칸은 IDA에서 확인했던 flag_gen()으로 이어질지 말지를 결정하는 분기 부분이다. 이때, 우리는 gdb를 통해 -0x4(%rbp)( rbp 기준으로 -0x4 바이트 떨어진 메모리)에 0x5의 값을 넣어줘 두 값이 같도록 만들어줘야 flag_gen()함수 실행 호출 조건을 만족시킬 수 있다. 

 

 

break point를 cmp 분기 전에 설정해주고, 디버깅하면서 원하는 메모리에 원하는 값을 넣어줬더니 플래그 형식으로 보이는 값이 나왔다!

 

더보기

Attempt to dereference a generic pointer 경고

 

: 리버싱 초보라 gdb를 많이 사용하지도 않고해서 주소에 막상 5만 대입했었는데 위와 같은 메시지가 계속 떴다. 이 오류는 포인터의 자료형을 몰라 역참조할 수 없을 때 발생한다고 한다. 

-> 그럼 포인터의 자료형을 내가 명시해줘야겠다! 

 

나는 이 포인터의 자료형을 어떻게 알 수 있을까???

-> 한 가지 방법은 어셈블리 코드를 보면 movl, movb, movq 같은 명령어로 저장 크기를 알 수 있다.

  • movl은 4바이트 → 일반적으로 int
  • movb는 1바이트 → char
  • movq는 8바이트 → long 또는 포인터

-> 따라서 movl $0, -0x4(%rbp) 같은 명령이 있다면 -0x4(%rbp)는 int로 추정되므로 int *을 명시해줄 수 있다. 

 

 

헤헤 플래그 꽂았다.

 

 

 

'리버싱' 카테고리의 다른 글

[드림핵] simple crack me  (0) 2024.11.19
[드림핵] Secure Mail  (0) 2024.11.14
[드림핵] rev-basic-8  (1) 2024.08.31
[드림핵] simple-operation  (0) 2024.05.13
[드림핵] rev-basic-6  (0) 2024.05.06