서론
드림핵 워게임 중 rev-basic-0 문제를 푸는 코스이다.
실행
먼저 다운로드 받은 파일을 실행하여 프로그램이 어떤 식으로 동작하는지 확인해보았다.
워게임 문제와 같이 신뢰할 수 없는 프로그램을 실행할 때는 가상환경(VM)에서 실행하는 것이 바람직하다.
만약 문제 정보를 통해 프로그램의 동작방식이 예상이 간다면 굳이 실행하지 않고 정적분석을 먼저 시도해보는 것도 좋은 방법이다.
윈도우 운영체제에서 기본적으로 제공되는 Windows PowerShell에서 문제 파일을 실행해보았다.
문제 파일의 압축을 해제한 후, 실행해보면 Input : 이라는 문자열이 출력된다. 출력된 문자열 뒤에 AAAA를 입력한 후, 엔터를 치면 Wrong이 출력된다. 문제가 사용자에게 문자를 입력받고 프로그램 내부의 어떤 검증과정을 거쳐 입력한 문자열이 검증을 통과했다면 Correct, 통과하지 못했다면 Wrong을 출력하는 방식으로 동작하는 것 같다.
문제의 정답(flag)은 검증과정을 통과하여 Correct가 출력되도록하는 입력값이 될 것이다.
정적 분석
IDA로 파일 열기
문제 파일을 정적분석하기 위해 앞서 배운 IDA를 사용했다.
IDA를 실행하고, chall0.exe를 끌어넣는다.
파일이 정상적으로 열리면 다음과 같은 창이 나타난다.
위의 창에서는 문제 파일의 간략한 정보를 띄워준다.
바이너리의 아키텍처는 AMD64 (x86-64), 파일 포맷은 PE (Portable Executable) 구조라는 것을 알 수 있다.
이 정보들을 통해 본격적으로 분석하기 전, 분석에 도움이 되는 정보를 획득할 수 있다.
지금까지 과정을 성공적으로 마치면 위와 같은 창이 나타난다.
이는 바이너리에 디버깅 정보를 담고있는 심볼 경로가 존재하는데, 이를 찾아서 로드하겠냐는 질문창이다.
문제 출제자는 별도의 심볼(.pdb)을 제공하지 않았기 때문에 No를 클릭한다.
문자열 검색
파일 실행과정을 통해 입력한 문자열을 검증한 후, Wrong이나 Correct문자열을 출력하는 것을 알 수 있었다.
따라서 검증하는 위치를 찾기 위해서 파일이 실행될 때 출력되던 문자열을 먼저 검색해 보았다.
앞서 파일을 실행해보면서 Input : 과 Wrong이라는 문자열이 출력되는 것을 확인했다.
해당 문자열을 사용하는 곳이 입력한 문자열을 검증하는 곳과 가까이 있을 가능성이 높다.
View - Open subviews -> Strings를 클릭하여 바이너리에 포함된 문자열을 확인했다.
문자열에서 Input : , Wrong 뿐만아니라 예상대로 Correct라는 문자열을 확인할 수 있다.
파일을 실행하고 임의 문자열을 입력했을 때 Wrong이 출력되던 것으로 미루어보아 Correct는 입력한 문자열이 검증과정을 통과했을 때 출력될 것으로 유추해 볼 수 있다.
그렇다면 어떤 입력값을 입력해야 Correct문자열을 출력하는지 알아낸다면 flag를 찾을 수 있을 것이다.
함수 분석
상호 참조 (Cross Reference, xref)를 통해 해당 문자열이 어떤 함수에서 참조되는지 확인할 수 있다.
View - Open subviews - Cross References 혹은 단축키 ('x')를 통해 Correct 문자열이 참조되는 함수를 확인해보면, main에서 해당 문자열을 참조하는 것을 볼 수 있다.
이후 단축키 F5를 사용해 Correct 문자열을 사용하는 곳을 디컴파일했다.
디컴파일 결과를 통해 어떤 조건이 만족해야 Correct 문자열이 출력될 지 분석했다.
파일을 실행하면 Input : 이 출력 되었고, 그 이후에 값을 입력할 수 있었다.
따라서 입력값에 대한 검증 과정은 Input : 문자열 이후에 있을 것이다.
함수 분석
처음 분석을 할 때는 함수 분석 시에 모르는 함수가 많아 완벽한 분석이 어려울 수 있다.
이 때는 익숙한 함수를 중점적으로 찾아보면서 어떤 기능을 하는 함수일지 알아내는 방식으로 추론한다.
sub_140001190 함수 분석
sub_140001190의 경우 익숙한 형태의 함수가 보인다.
va_start 함수와 _acrt_iob_func(1); 함수가 사용되는 것으로 보아 앞서 Helloworld 실습에서 분석했던 것처럼 printf 함수임을 알 수 있다.
즉, printf 함수를 사용해 Input : 문자열을 출력하는 것이다.