ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [reversing.kr] Replace 풀이
    Wargame/reversing.kr 2021. 3. 9. 15:04

    1. 프로그램 분석

    우선 PEiD에 집어넣어보자.

     

    PEiD

    위와 같이 단순한 Visual C++로 작성된 프로그램임을 확인할 수 있다. 프로그램을 실행해보자.

     

    실행화면

    위와 같은 윈도우가 나타난다. 아무 값이나 입력해보려고 했지만 숫자가 아닌 값이 input으로 입력으로 들어올 경우 나타나지 않으며, 임의의 숫자를 넣고 Check 버튼을 누르면 프로그램이 비정상적으로 종료된다. 바로 OllyDbg를 통해 분석을 해보자.

     

    2. Debugging(with OllyDbg)

    프로그램을 실행하기 전에 Ctrl+N을 이용해 사용되는 API들을 살펴보자.

    디버깅

    위와 같이 DialogBox 관련 API들이 있는 것으로 보아, 대화 상자 형태의 윈도우 임을 알 수 있다. Check 버튼을 눌렀을 때 GetDlgItemInt를 통해 입력 값을 받아올 것임을 추측할 수 있으므로, 해당 부분에 BP를 설정하고 F9를 눌러 프로그램을 실행시키자.

     

    BP 적중

    대화 상자가 나타난 후 임의의 값(여기서는 0000을 입력하였다.)을 input으로 주고 Check 버튼을 누르면, 위와 같이 BP에 적중한다. 읽어 들인 값을 4080D0 주소에 저장하고 CALL Replace.0040466F를 통해 함수를 호출하는데 해당 부분으로 이동해보자.

     

    Replace.0040466F

    뭔가 딱 봐도 코드들이 수상해보인다. F7을 통해 한 줄씩 실행시키다 보면 다음과 같은 상황을 만나게 된다.

     

    디버깅

    위와 같이 EAX 레지스터가 가리키는 곳에 90을 이동시키는 연산을 수행하는데 EAX는 현재 601605CB를 가리키고 있다. 601605CB는 Replace에게 할당된 메모리 영역이 아니므로 Memory Access violation이 일어나고, 프로그램에서는 예외가 발생해 정상적으로 실행되지 못한다. 코드를 한 줄씩 실행시키다 보면 알겠지만, 이 601605CB라는 값은 

     

    (input 정수) + 2 + 0x601605C7 + 2

     

    라는 값으로 부터 나온 값이다. 일단은 프로그램에서 예외가 발생하면 안 되기 때문에, 적당한 input을 주어 memory access violation이 일어나는 것을 방지하도록 해보자. 우선 접근 가능한 메모리 영역을 고르기 위해 ollydbg에서 memory map을 살펴보자.

     

    memory map

    계산의 결과가 407000이 되도록 input 값을 주자. 계산기를 통해 계산하면 0xA02A6A35를 input으로 주면 된다. 해당 값은 10진수로 2,687,134,261이다. 프로그램을 다시 실행하여 이 값을 input으로 주고, memory access violation이 일어났던 지점까지 디버깅을 해보자.

     

    디버깅

    위와 같이 407000 주소에 90 이라는 값을 write 한다. 계속 디버깅해보자.

     

    디버깅

    이번에는 그다음 주소인 407001 주소에 90 값을 또 write 한다. 계속 디버깅해보자.

     

    함수 종료

    위와 같이 JMP에 의해 401071로 돌아가게 된다.

     

    디버깅

    그런데 401071 주소에서는 SetDlgItemText API를 건너뛰는 점프 명령어가 있다. conditional jump가 아니어서 SetDlgITemText API는 호출될 일이 없다. 다른 루틴에서 401073 주소를 call 한다든가 jump 하는 명령어를 탐색해 보여도 보이지 않으므로 무효화하는 방법을 생각해보아야 한다. 곰곰이 생각해보면 이전에 보았던 특정 메모리 영역에 90 값을 옮기는 명령어를 이용하면 될 듯하다. 0x90 기계어 코드는 어셈블리로 NOP(아무 연산도 안 함)에 해당된다. JMP SHORT는 2byte 명령어 이므로 90을 두 번 mov 하는 명령어를 이용해 해당 부분을 NOP으로 변경해주면 될 것 같다.

     

    memory access violation이 일어났던 주소식을 결과가 401071이 되도록 하는 input을 계산한 후 해당 값을 넣어주고 Check 버튼을 누르면 다음과 같이 Correct! 문자열이 나타난다.

     

    flag 획득

     

    3. Comment

    프로그램 실행부터 버벅거려서 살짝 애먹었던 문제다. 사이사이에 의미 없는 명령어(pushad, popad 등등)들이 껴있어서 분석하는데 시간이 더 들어간 것 같다. 최근에 Dreamhack 강의 System hacking 파트에서 NOP sled 관련 기술을 배우면서 NOP이 0x90이라는 점을 배웠었는데, 이점이 문제 해결하는데 도움이 되었다.

     

     

    반응형

    'Wargame > reversing.kr' 카테고리의 다른 글

    [reversing.kr] Position 풀이  (0) 2021.05.22
    [reversing.kr] ImagePrc 풀이  (0) 2021.05.09
    [reversing.kr] Music Player 풀이  (0) 2021.02.09
    [reversing.kr] ransomware 풀이  (0) 2021.01.08
    [reversing.kr] Easy ELF 풀이  (0) 2021.01.05

    댓글

Designed by Tistory.