일단 주어진 파일을 Immunity Debugger로 실행시켜 보았더니 위와 같은 부분으로 코드가 시작되었다.

 

 

단축키를 눌러 0040123D 부분을 실행시켜보았더니 위와 같은 창이 뜨면서 Name과 Serial 값을 입력할 수 있게 되어 있었다.

 

 

일단 위와 같이 Name 값을 입력하고 Check 부분을 눌러본 후에 디버거에서 코드를 진행시켜보았다.

 

실행된 코드에서 약간 밑으로 스크롤 해보니 다음과 같은 두 부분을 발견할 수 있었다.

 

 

Name과 Serial값이 맞았을 경우 위의 주석과 같은 문구를 띄워줄 것을 예상할 수 있었다.

 

 

그리고 Serial 값이 틀렸을 경우 위의 주석과 같은 문구를 띄워줄 것을 예상할 수 있었다.

여기서 왜 Name 값이 맞았는지 틀렸는지를 확인해주는 코드는 없을까? 라는 생각이 들기는 했었다.

 

 

 

위의 코드는 Name에 abcd를 입력하고 Check를 눌렀을 때 코드가 진행된 부분이다.

LEA 명령어는 좌변에 우변의 주소값을 저장해주는 명령어이다.

코드를 보면 EAX 레지스터에 EBP-44 스택값을 저장하고 ECX 레지스터에 EBP-34 스택값을 저장하는 것을 확인할 수 있다.

혹시 방금 위에서 입력한 Name 값을 저장해주는 것이 아닐까? 라는 생각을 해서 스택값을 확인해보기로 했다.

 

 

EBP-44=0019F1F8-44=0019F1B4이고 EBP-34=0019F1F8-34=0019F1C4이다.

 

 

스택창에서 위에서 계산한 주소 부분을 찾아 확인해봤더니 위와 같이 시리얼 값으로 예상되는 주석을 발견할 수 있었다.

 

 

코드를 재시작한 후 아까 입력한 Name(abcd)과 위에서 발견한 Serial(C5C6C7C8)을 입력해봤더니 위와 같이 성공 메세지창이 잘 출력되는 것을 확인할 수 있었다.

이후에 찾아보니 이 문제는 Name값에 따라 Serial값이 달라지도록 만들어진 것이었다.

그래서 Name값의 정답 유무를 체크해주는 부분이 없었던 것이다.

 

다음은 writeup을 참고한 부분이다.

 

처음 파일을 열었을 때 실행되는 위의 코드 부분을 보면 CALL 명령어가 있는 부분에서 MSVBVM60. #100 부분으로 점프하는 것을 볼 수 있는데 이는 VB 파일을 이용한 것이라고 한다.

 

VB 파일은 Visaul Basic 파일로 주로 GUI 프로그래밍에 사용되며 VB 전용엔진인 MSVBVM60.dll을 사용한다.

VB 컴파일러는 MSVBVM60.dll!rtc MsgBox()가 호출되도록 한 후 이 함수 내부에서 Win32 API인 user32.dll!MessageBoxW() 함수를 호출하는 방식이며 컴파일 코드 종류에는 Native Code와 Pseudo Code가 있다. 또한, VB는 대부분 GUI 프로그래밍이라 Windows 운영체제의 Event Driven 방식의 동작으로써 main()이나 Winmain()에 사용자 코드가 존재하는 것이 아니라 각각의 event handler에 사용자 코드가 존재하며 VB에서 사용되는 각종 정보들은 내부적으로 구조체 형식으로 파일에 저장된다는 특징이 있다.

 

 

위와 같이 CALL 명령어로 해당 함수를 불러오는 부분에서 주석 부분을 보면 vbaVarTstEq 함수를 확인할 수 있다.

 

vbaVarTstEq 함수는 암호를 검사하는 함수로 2개의 파라미터를 전달받아 스택에 저장해준다.

이 부분에서 F7키를 눌러 함수 내부로 들어가봤다.

 

 

위와 같은 부분에서 5117C2E4 부분을 보면 또다른 함수를 호출하는 것을 볼 수 있고 이 함수 내부로 들어가봤다.

 

그랬더니 위와 같은 부부으로 연결되었고 계속 함수를 진행시켜보다가 51176320 부분에서 VarCmp 함수를 확인할 수 있었다.

 

VarCmp 함수는 두개의 파라미터를 비교해주는 함수이고, 이 부분에서 내가 입력한 값과 정답을 비교해주는 것이 아닐까? 라고 예측할 수 있었다.

 

 

그래서 위의 VarCmp 함수를 호출해주는 부분으로 들어가 보았다.

 

 

코드를 진행시켜보다가 위와 같이 VarBstrCmp 함수를 호출해주는 부분을 확인할 수 있었고  

 

 

이때 스택창 부분을 확인해봤더니 정답인 시리얼키(C5C6C7C8)와 내가 아무렇게나 입력한 시리얼키(1234)를 저장한 부분을 확인할 수 있었고 이제 이후에 이 두개의 값을 비교하여 정답여부를 판단하겠구나 라고 예측할 수 있었다.

 

 

계속 코드를 진행시켜보았더니 위와 같은 부분으로 이어졌고 두개의 값을 비교하여 정답 여부를 확인해주는 부분으로 넘어가는 것을 확인할 수 있었다.

그래서 아까처럼 파일을 restart하여 Name(abcd)과 확인한 시리얼키(C5C6C7C8)를 입력해준 후 Check를 해주면 성공 메세지 창이 뜨면서 문제를 해결할 수 있다.

 

 

주어진 파일을 Immunity Debugger로 열어보면 제일 처음에 위와 같은 코드를 볼 수 있다.

 

 

일단 뭔가 뜨는지 확인해보기 위해서 단축기를 이용하여 코드들을 분석해보았고, 어느 CALL 함수 지점에서 F8키를 누르면 위와 같은 창이 뜨는 것을 확인할 수 있었다.

 

 

위와 같이 계속 하나하나 breakpoint를 걸어주고 restart하면서 코드를 찾아보았다.

 

 

그러다가 위와 같은 부분을 발견하게 되었고, 주석에 Congratulation!이라는 문구가 쓰여져 있는 것으로 보아 답과 연관이 있을 것이라고 예측할 수 있었다.

 

조금 더 윗부분으로 스크롤해보니 913465라는 아스키코드 값을 발견할 수 있었다.

 

 

그래서 위와 같이 메세지 창에 913465를 입력해주었더니 Congratulation!이라는 메세지 창이 뜨는 것을 확인할 수 있었다.

 

일단 주어진 파일을 Immunity Debugger로 열어보면 위와 같은 코드를 확인할 수 있다.

제일 먼저 메인함수를 찾아서 어떻게 실행되는지 확인해봐야겠다고 생각해서 의심되는 CALL 함수 부분에서 F7키를 눌러 하나씩 찾아보았다.

 

 

이 부분에서 F8키를 누르면 실행창에 ID를 입력하라는 메세지가 뜨길래 메인함수일 것을 예상하고 breakpoint를 걸어주었다.

 

 

다시 단축키를 이용해 위에서 breakpoint를 걸어준 주소값으로 이동했더니 위와 같이 메인함수임을 확인할 수 있었다.

 

이제 F8키를 이용하여 코드를 한줄씩 실행시켜보았다.

 

 

일단 위처럼 ID에 aa를 입력한 후 EBP-34=001AFD04-34=001AFCD0이므로 해당 스택창을 확인해봤더니 aa가 들어간 것을 확인할 수 있었다.

 

 

또한 위처럼 PW에 bb를 입력한 후 EBP-24=001AFD04-24=001AFCE0이므로 해당 스택창을 확인해봤더니 bb가 들어간 것을 확인할 수 있었다.

 

그 후에 아이디와 비밀번호를 입력한 후 레지스터 창을 확인해보라는 힌트를 봤다.

 

 

일단 코드를 더 진행시켜봤더니 위와 같은 부분이 있었다.

먼저 MOV 명령어를 이용하여 DL 레지스터에 EAX값을 넣고 DL과 ECX 값을 CMP 하여 같지 않다면 00CD10F0으로 넘어가도록 하는 것이였다.

 

 

위의 두 주석 부분을 보면 알 수 있듯이 00CD112C로 넘어가면 원하는 메세지가 출력된다고 예상할 수 있었다. 

 

 

위에서 JNZ 명령어를 만나 00CD10F0으로 넘어가게 된다면 00CD1181로 넘어가기 때문에 이렇게 되도록 놔두면 안된다는 것을 예상할 수 있다.

 

 

그렇기 때문에 애초에 EAX와 ECX의 값이 같도록 만들어 주어야하고 이때 레지스터 창을 확인해보면 ECX에 "XCZ"라는 문자열이 있는 것으로 보아 이것이 ID라는 것을 예측할 수 있다.

 

 

다시 파일을 restart 해준 후 위와 같이 ID에 XCZ를 입력하고 PW에 bb를 입력하여 코드를 실행시켜보면

 

 

위와 같이 EAX 레지스터와 ECX 레지스터에 같은 값이 들어가므로 JNZ 명령어를 만나도 점프하지 않고 다음코드로 실행된다.

 

 

다음 코드를 계속 실행시키다 보면 위와 같은 부분이 나온다. 이는 PW를 입력한 부분에 대한 비교이다.

 

 

앞에서 ID를 찾았던 것과 마찬가지의 방법과 이유로 UNL1M1T가 PW라는 것을 예측할 수 있다.

 

 

이렇게 알아낸 ID와 PW를 cmd창에서 파일을 실행시켜 입력해보면 위와 같이 인증키를 얻어낼 수 있다.

'2020 WINTER STUDY > CTF Study' 카테고리의 다른 글

[Reversing] Day 4_abex' crackme #2  (0) 2021.02.18
[Reversing] Day 3_suninatas 9  (0) 2021.02.18
[Reversing] Day 2_abex' crackme #3  (0) 2021.02.16
[Reversing] Day 2_abex' crackme #1  (0) 2021.02.16
[Reversing] Day 1  (0) 2021.02.15

 

Immunity Debugger로 실행파일을 열어보면 위와 같은 코드와 메세지창이 출력되는 것을 볼 수 있다.

F8키를 눌러 실행시켜보다가 00401037 부분에서 00401075 부분으로 점프하는 것을 확인할 수 있었다.

 

 

처음에는 이것도 1번 문제와 비슷한건가? 라고 생각해서 위와 같이 코드를 수정해주었더니 원하는 메세지창이 출력되는 것을 확인할 수 있었다.

 

그리고 이후에 힌트를 보니 CreateFile 함수에 대해 찾아보라고 했다.

 

CreateFile 함수는 파일 혹은 오브젝트를 생성하거나 열 수 있는 함수로 다른 함수들을 이용해서 파일을 읽거나 쓸 수 있다.

 

CreateFile 함수의 원형은 다음과 같다.

 

 

 

위의 부분을 보면 CreateFile 함수를 확인할 수 있고, 주석 부분을 보면 이름이 abex.l2c인 파일을 생성하는 코드를 확인할 수 있다.

 

 

그리고 위의 부분에서 GetFileSize 함수를 확인할 수 있고, 이는 파일의 사이즈를 리턴해준다.

00401046 부분을 보면 EAX레지스터의 값과 12를 CMP 하여 JNZ 해주는 것을 확인할 수 있는데

JNZ 명령어는 Jump If Not Equal이라는 의미 즉, 두 값이 같지 않을 때 해당 주소로 점프해주는 명령어이다.

Yep, keyfile found!라는 메세지를 출력하는 함수를 실행시키기 위해서는 00401049에서 바로 다음 주소인 0040104B로 넘어가게 만들어야 하므로 파일 사이즈가 12인 파일을 생성해주면 된다.

 

 

그래서 위와 같이 메모장으로 이름이 abex.l2c이고 파일사이즈가 12 (10진수로 바꾸면 18을 의미)인 파일을 임의로 생성한 후 실행시켜보면 원하는 메세지가 잘 출력되는 것을 확인할 수 있다.

'2020 WINTER STUDY > CTF Study' 카테고리의 다른 글

[Reversing] Day 3_suninatas 9  (0) 2021.02.18
[Reversing] Day 3_xcz.kr prob 9  (0) 2021.02.18
[Reversing] Day 2_abex' crackme #1  (0) 2021.02.16
[Reversing] Day 1  (0) 2021.02.15
[Forensic] Day 6  (0) 2021.02.07

처음에 Immunity Debugger로 문제 파일을 연 후 F8키를 눌러보면서 한줄씩 실행시켜보았다.

 

 

위와 같은 어셈블리 코드와 메세지창을 볼 수 있었고 CD-ROM이 맞다는 메세지 창이 뜨도록 만드는 것이 이 문제의 목표였기 때문에 아래 그림의 코드 부분을 유심히 보았다.

 

 

일단 00401026 주소에 있는 JE 명령어는 어셈블리의 분기 명령어 중 하나로 Jump if equal 즉, CMP로 비교한 결과 값이 같다면 참이 되고, 이때 해당 주소로 점프하는 기능을 가진 명령어이다.

 

 

수정하기 전의 코드에서 CMP 명령어를 처리해줄때 EAX 레지스터에는 00000001 값이 들어있고 ESI에는 00401003 값이 들어있기 때문에 두 결과값은 같지 않으므로 0040103D라는 주소로 넘어가지 않고 그냥 그 다음주소(00401028)로 넘어간다.

 

 

위와 같이 옆에 주석 부분에서 볼 수 있듯이 Ok, I really think that your HD is a CD-ROM이라는 메세지가 있는 MessageBox가 실행되도록 하려면 CMP를 해준 값이 같도록 하여 JE를 만났을때 해당 주소(0040103D)로 넘어갈 수 있게 만들어주면 될 것이라고 생각했다.

 

 

그래서 위와 같이 MOV EAX, ESI를 해주어 두 값이 같도록 수정했더니 제대로 메세지 창이 뜨는 것을 확인할 수 있었다.

MOV 명령어는 operend1값에 operend2 값을 넣어준다는 의미이다.

 

또 다른 풀이법으로는 JE 명령어를 JMP 명령어로 바꿔주는 방식이 있다.

JE 명령어는 CMP해준 두 값이 같아야만 점프를 하는 반면 JMP 명령어는 무조건 해당 주소값으로 점프를 한다. 

 

 

그렇기 때문에 위와 같이 JE를 JMP로 수정해주면 해당 주소로 잘 넘어가고 원하는 메세지 창이 뜨게 할 수 있다.

 

이외에도 레지스터의 값을 증가시키거나 감소시키는 코드로 수정하여 EAX와 ESI의 값을 같게 만들어주는 방법도 있을 것이다.

'2020 WINTER STUDY > CTF Study' 카테고리의 다른 글

[Reversing] Day 3_xcz.kr prob 9  (0) 2021.02.18
[Reversing] Day 2_abex' crackme #3  (0) 2021.02.16
[Reversing] Day 1  (0) 2021.02.15
[Forensic] Day 6  (0) 2021.02.07
[Forensic] Day 5  (0) 2021.02.05

+ Recent posts