Reversing/CodeEngn

[CodeEngn] RCE basic L17 풀이

chan2s 2025. 9. 4. 23:51

Q17. Key 값이 BEDA-2F56-BC4F4368-8A71-870B 일때 Name은 무엇인가. 힌트 : Name은 한자리인데.. 알파벳일수도 있고 숫자일수도 있고.. 정답인증은 Name의 MD5 해쉬값(대문자)

[그림 1] 17.exe 최초 실행

실행한 후 문제에서 주어진 키값(BEDA-2F56-BC4F4368-8A71-870B)을 입력하고 Name에 임의의 값인 CodeEngn을 넣었다. Check it! 을 눌러도 Name값이 틀리면 잠깐 멈추었다가 아무 반응이 없다.

[그림 2] OllyDbg 성공 문구 확인

All referenced text strings 에서 올바른 Name값을 입력했을 때 출력될 것 같은 문구를 확인했다.

[그림 3] 45BAE8 스택 시작주소

전체 알고리즘을 분석해 보기위해 스택의 시작점인 45BAE8에 BP를 걸고 디버깅을 진행했다.

[그림 4] 디버깅 테스트 Name : 12345

디버깅 테스트로 Name에 12345를 입력하고 분석을 시도했다.

[그림 5]45BB12 Name확인

45BB12에서 Name에 입력한 12345 확인할 수 있었다.
이때 EAX값으로 5가 저장되었음을 확인했다. 12345와 5의 연관을 찾아보면 글자수인 것 같았다.

[그림 6] 45BB24 CMP EAX,3 분석

45BB24주소에서 EAX값과 3을 비교하지만 앞서 EAX의 값이 5임을 확인했다.
하지만 문제에서는 Name은 한 자리의 글자를 받는다고 했지만 해당 부분은 3이므로, 패치를 해주어야 했다.

[그림 7] 45BB24 패치

문제에서 Name은 한자리라고 하였으니 해당 명령어를 CMP EAX,3 > CMP EAX,1로 패치 진행했다.

[그림 8] 패치 후 저장 1
[그림 9] 패치 후 저장 2

패치 후 CMP EAX,1에 우클릭 > Copy to executable > Selection 클릭
해당 화면에서 우클릭 > Save file로 패치한 내용을 저장 후 패치된 파일을 저장할 수 있다.
저장할 때에는 기존 17.exe와 혼동이 될 것 같아 17p.exe로 저장했다.

[그림 10] 17p.exe 분석

45BBA9에서 성공으로 분기한다는 것을 확인했다.
하지만 바로 CMP문을 확인할 수 없기에 45BBA4 주소에서 호출하는 404C3C에 대해 분석을 해야한다.
45BBA4에 BP를 걸고 디버깅을 진행했다.

[그림 11] 17p.exe 테스트 Name : 1

Name에 1을 입력하고 동적 분석을 진행했다.

[그림 12] 404C3C 명령어 분석
[그림 13] 404C3C Registers 창

404C3C에 BP가 걸려 F7을 통해 들어오면 404C3C에서 EAX와 EDX를 비교하는 것을 확인해 볼 수 있었다.
Registers 창을 보면 EAX값은 입력한 Serial값이고, EDX에는 생성된 Serial 값을 확인할 수 있었다.

Serial 생성 알고리즘을 분석해야 하는데 404C3C에서는 이미 Serial값이 생성되어 있으므로,
더 이전에 호출되는 주소를 분석해야 했다.

[그림 14] 45BB9B BP

이번에는 더 앞에서 호출되는 45B850을 분석해보기로 해서 45BB9B에 BP를 걸고 분석을 시도했다.

[그림 15] 45B8A0 Name값 확인

45B850에 들어와 내리다 보면 Name에 입력했던 31(1)값을 확인해 볼 수 있었다.
이 45B89D ~ 45B8C2까지가 Serial 생성 알고리즘이다.

45B8A0를 보면 Name에 들어가는 1값을 ESI에 저장한 뒤 여러 연산을 진행하게 된다.

[그림 16] 45B8A0 EAX, EDX 값

45B8A5를 보면 ADD ESI,EDX를 해주는데,
45B8A0에서 확인한 EDX의 초기값은 0임을 확인했다.

45B8A0 이후에 나오는 명령어들에 대해서 python 복호화 코드로 바꾸어 작성하면 다음과 같다.

for i in range(0x30, 0x7A, 1):
	EDX = 0x00
	ESI = i;

	ESI=i*0x772
	EDX=ESI
	EDX*=ESI
	ESI+=EDX
	ESI*=0X474
	ESI+=ESI
	print(chr(i), hex(esi)[-8:])

45B8B4의 OR ESI,ESI 나 45B8A5의 ADD ESI,EDX(0) 같이 값 변화가 없는 것은 제외하고 작성하면 된다.
반복문 범위는 ASCII표 기준 30(0) ~ 7A(z) 까지 범위를 잡고 Name 값을 받는 ESI 한 글자를 추출하면 된다.
마지막 코드의 의미는 i를 ASCII 문자로 변환하고, hex값의 뒤 8자리(32비트)값으로 생성되는 Serial값을 각각 보기 위함이다.
| 코드 참조 출처 : CodeEngn Basic RCE L17

 

CodeEngn Basic RCE L17

문제 Key 값이 BEDA-2F56-BC4F4368-8A71-870B 일때 Name은 무엇인가 힌트 : Name은 한자리인데.. 알파벳일수도 있고 숫자일수도 있고.. 정답인증은 Name의 MD5 해쉬값(대문자) 언제나 그랬듯 . . ~ 성공 구문을 찾

esyeonge.tistory.com

[그림 17] Python 코드 실행 결과

실행해보면 ASCII 값과 이때 생성되는 serial 값에 대해서 볼 수 있다.
문제에서 Serial 값으로 주어진 BEDA-2F56-BC4F4368-8A71-870B와 가장 근접한 값을
가진 문자는 beda로 시작하는 값을 가진 F임을 확인할 수 있다.

[그림 18] 'F' DM5 해시 생성

이제 MD5해시 생성기를 통해 F를 돌려보면 다음과 같은 값을 얻을 수 있었다.

정답 : 800618943025315F869E4E1F09471012

'Reversing > CodeEngn' 카테고리의 다른 글

[CodeEngn] RCE basic L19 풀이  (0) 2025.09.05
[CodeEngn] RCE basic L18 풀이  (0) 2025.09.05
[CodeEngn] RCE basic L16 풀이  (0) 2025.09.03
[CodeEngn] RCE basic L15 풀이  (0) 2025.09.03
[CodeEngn] RCE basic L14 풀이  (0) 2025.09.03