woonadz :)

[CodeEngn Basic] RCE L07 문제 풀이_nabi 본문

IT/codeengn 문제 풀이

[CodeEngn Basic] RCE L07 문제 풀이_nabi

C_scorch 2022. 3. 29. 01:46
반응형

CodeEngn Basic RCE L07 문제

컴퓨터 C 드라이브의 이름이 CodeEngn 일경우 시리얼이 생성될때 CodeEngn은 'ß어떤것'으로 변경되는가


문제풀이를 위해 C 드라이브 이름을 사진과 같이 바꿔줌
7번 문제 압축 해제 후 exe 파일을 실행하였을 때
잘못된 시리얼을 입력했을 때 나오는 오류 메세지 찾아가기

오른쪽 마우스 -> Search for -> All referenced text strings

오류 메세지를 출력해내는 곳을 찾아 이동하기

 

오류메세지를 출력하는, 메세지 함수를 호출하는 서브루틴 함수의 시작 주소에 BP를 걸고 실행시킨다.

 

GetVolumeInformationA 함수

GetVolumeInformationA 함수는 지정된 루트 디렉터리와 연결된 파일 시스템 및 볼륨에 대한 정보를 검색하는 역할을 한다. 따라서 이 함수가 필자의 컴퓨터 C 드라이브 이름을 가져온다고 추측할 수 있다.

(필자의 풀이 방식은 마이크로소프트 독스에서 함수를 찾아보며 풀이한다. 함수에 대한 더 자세한 정보를 알고 싶다면 아래 문서 참조)

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa

 

GetVolumeInformationA function (fileapi.h) - Win32 apps

Retrieves information about the file system and volume associated with the specified root directory.

docs.microsoft.com

 

GetVolumeInformationA 함수를 실행시키자 빨간색 부분에 필자의 C 드라이브 이름(CodeEngn)이 나타난 것을 확인할 수 있다.

lstrcatA 함수는 매개변수인 두 문자열을 하나의 문자열로 합치는 역할을 한다.

이제 해당 함수를 실행시켜보자.

해당 함수의 반환값(매개변수인 두 문자열을 합친 값)이 EAX 레지스터 들어갔음을 확인할 수 있다.

 

분기문을 만나면서 lstrcatA 함수의 반환값(CodeEngn 4562-ABEX)이 저장된 주소에 1씩 더하고 있다. 1씩 더해지면서lstrcatA 함수의 반환값이 한글자씩 변하고 있는 것을 확인할 수 있다. 

해당 분기문을 모두 실행하면 아래와 같이 변하게 된다.

 

분기문을 탈출했을 때 아스키값은 위와 같이 변한다.

이제 lstrcatA 함수 두 개와 lstrcmpiA 함수 한 개로 정답 시리얼값과 사용자가 입력한 시리얼 값의 일치여부를 가려내는 것 같다.

 

첫번째 lstrcatA 함수를 실행시키자 다른 함수들의 인자값이 생겼다. 첫번째 lstrcatA의 반환값은 'L2C-5781'이다. 이로써 다른 함수들의 두 번째 매개변수(ConcatString, string1)은 첫번째 lstrcatA 함수의 반환값이라고 추측할 수 있다.

두번째 lstrcatA 함수를 실행시켜보겠다. 아마 'L2C-5781' 과 'EqfgEngn4562-ABEX' 의 분자열을 합친 값이 반환값일 것이다.

 

예상과 같이 'L2C-5781EqfgEngn4562-ABEX' 라는 문자열이 반환되었다.

하지만 위에서의 추측 중 틀린 것이 있는데 lstrcmpiA 함수의 string1 매개변수 값이 달라졌다는 점이다. 이로써 lstrcmpiA 함수의 string1 매개변수는 두번째 lstrcatA 함수의 반환값이었다는 것을 알 수 있다.

마저 실행시켜보겠다.

 

EAX 레지스터의 반환값이 1이 되었다. lstrcmpiA 함수는 어떤 역할을 하기에 반환값을 1로 준것일까?

lstrcmpiA 함수는 문자열 비교 함수로 String1 이 가리키는 문자열이 String2 가 가리키는 문자열보다 작으면 음수를 반환하고 String1 이 가리키는 문자열이 String2 가 가리키는 문자열보다 크면 양수를 반환한다. 또한 문자열이 같으면 0을 반환한다.

String1 이 가리키는 문자열이 더 길기 때문에 1이 반환되었던것이다.

해당 함수 아래 어셈블러들을 읽어보면 CMP 명령어로 인해 제로플래그 값이 0으로 유지되게 되고 시리얼 값이 맞았다는 메시지 함수로 이동할 수 없게된다.

그럼 여기서 lstrcmpiA 함수의 매개변수(String1, String2) 값이 같아야 반환값이 0이 되고 CMP 명령어로 0과 비교하였을 때 같아 제로플래그 값이 1이 되어 시리얼 값이 맞았다는 메시지 함수로 이동할 수 있게 된다는 것을 추측할 수 있다.

따라서 시리얼값은 'L2C-5781EqfgEngn4562-ABEX' 일 것이다.

 

이 문제의 시리얼 값은 'L2C-5781EqfgEngn4562-ABEX' 문자열이 맞고 CodeEngn은 EqfgEngn으로 변한다.​

반응형