리버싱

[드림핵] simple crack me

초코맛동산 2024. 11. 19. 17:01

# 문제

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

이 문제는 사용자에게 숫자를 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 10진수 양수 값을 찾으세요!

 

1. main 함수 찾기

먼저, 주어진 파일은 PE 파일의 형식이 아니어서 xdbg64를 통한 디버깅이 불가능 하였습니다. 그럼 어떤 파일인가? 해서 HXD를 통해 시그니처 헤더만 살펴봤습니다. 

 

 

elf 파일임을 확인할 수 있었고, 가능하면 우분투로 디버깅을 하고자 했으나, 가상 머신이 말을 안 듣는 관계로.. (요즘은 다들 가상머신 안쓰고 클라우드로 한다던데..) 윈도우에서 IDA로 정적 분석만 해보겠습니다. 

 

일단 해당 프로그램을 실행해보지는 못 했지만, 워게임의 설명으로는 어떤 값을 입력 시 correct 와 wrong 값 중 하나가 출력된다고 합니다. rev-basic 문제와 같은 형식일 것 같은데.. 그럼 먼저, correc 혹은 wrong 문자열로 해당 main 함수를 찾을 수 있을 것 같습니다. 

 

 

 

 

그래프 뷰로 correc와 wrong 문자열이 분기되는 함수를 쉽게 찾을 수 있었습니다. 

 

2. 실행 흐름 파악하기 & 디버깅 

 

 

먼저 스택이 생성되는 것이 보이고, 그 뒤로는 사실 이러저러 값을 저장하고, 함수를 호출하는 것이 보입니다. 그러나 우리가 crack 해야하는 것은 correct로 무조건 분기하는 값을 찾는 것 입니다. 

 

 

cmp 어셈블리어로 13371337h(십진수 변환시 322376503)와 eax 값을 비교해서 jnz 어셈블리어로 0이 아니면 Wrong으로 이동 합니다. 그렇다면 correct를 만족하는 eax는 322376503 이여야 합니다. 

 

디컴파일로 쉽게 함수를 살펴보자면..

 

 

if로 322376503 값과 v5를 비교하기 전 sub_40BB20 함수가 있는데요. (__int64)&unk_4B6004와 &v5를 인자로 하고 있습니다.  (__int64)&unk_4B6004 값은 아래와 같이 %d를 가리키고 있고, &v5는 v5의 주소를 가리키고 있는 거겠죠. 상당히 scanf 함수와 비슷한 것을 확인할 수 있습니다. 

 

 

 

sub_40BB20 함수를 더 자세히 살펴보았을 때 가변 인수 사용시 포인터를 초기화 해주는 함수가 발견되었고, result 값에 들어있는 sub_40BC60 함수에서도 %로 case를 나눠 작업을 하는 것을 보아 scanf 함수라고 생각해보아도 좋을 것 같습니다. 

 

어찌되었든, scanf로 입력된 값인 v5와 322376503를 비교해서 correct와 wrong으로 분기되는 것을 확인했으니, 값은 322376503가 됩니다.