CodeEngn Write Up/Basic

CodeEngn Basic RCE L17 Write Up

서원근양학계정 2022. 4. 22. 11:12

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

https://ch.codeengn.com/

 

CodeEngn.com [코드엔진]

코드엔진은 국내 리버스엔지니어링 정보공유를 위해 2007년 부터 리버스엔지니어링 컨퍼런스 및 세미나, 워크숍을 현업 실무자들과 함께 운영하고 있는 비영리 커뮤니티입니다.

ch.codeengn.com

 

이 문제는 키 값을 주고 이름을 구하는 문제입니다.

일단 문제 파일을 실행시켜보겠습니다.

이름이 한 글자라고 하니 한 글자를 입력해보겠습니다.

 

Check it! 버튼을 눌렀더니 더 많은 글자를 입력하라고 합니다.

OllyDBG를 이용해서 본격적으로 분석해보겠습니다.

문자열 검색 기능을 이용해서 "Please Enter More Chars..."를 찾고 BP를 걸어주었습니다.

그리고 실행시키면 이 부분에서 멈추게 됩니다.

 

EAX에는 문자열의 길이가 있고 이 값을 3과 비교하고 있습니다.

따라서 이 부분을 CMP EAX, 1로 바꿔주겠습니다.

스페이스바나 더블 클릭을 이용해서 어셈블리어 코드를 수정할 수 있습니다.

 

그다음 코드 부분을 우클릭하고 "Copy to executable"을 눌러준 다음 "Selection"을 눌러줍니다.

 

그러면 이런 창이 뜹니다.

 

여기서 우클릭을 하고 "Save file"을 눌러주면 수정한 부분을 저장한 파일을 만들 수 있습니다.

이제부터는 수정한 파일로 진행하도록 하겠습니다.

 

문자열 검색 기능을 이용해서 중요한 부분을 찾아보았습니다.

 

몇 개의 함수들을 호출하는 것과 성공했을 때 출력되는 것으로 추정되는 문자열들이 보입니다.

먼저 0045BB9B에서 호출되는 함수를 먼저 분석해보겠습니다.

 

몇 개의 반복문이 보입니다.

이 부분에서 키값을 만드는 것 같습니다.

먼저 첫 번째 반복문을 분석해보겠습니다.

 

이 반복문은 입력한 이름의 길이만큼 반복을 하면서 여러 가지 연산을 수행합니다.

그 값은 최종적으로 ESI에 저장됩니다.

 

ESI의 값이 0x4E399840인 것을 확인할 수 있습니다.

이다음에도 반복문이 더 있지만 일단은 Ctrl+F9를 이용해서 RETN까지 실행시키고 이 함수를 빠져나오겠습니다. 

다음으로 0045BBA4에서 호출되는 함수를 분석해보겠습니다.

함수의 안으로 들어간 다음 레지스터의 값을 확인해보니 입력한 값이 들어있습니다.

 

0045BB9B에서 호출되는 함수가 키값을 만드는 함수라는 것을 확실하게 확인할 수 있습니다.

따라서 그 함수를 자세하게 분석해보겠습니다.

이 부분에서 Key 값이 만들어지게 됩니다.

 

이 부분을 분석해서 C언어로 코드를 짜 보겠습니다.

#define _CRT_SECURE_NO_WARNINGS

#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	int ESI, EDX = 0;
	char aa[101] = { "0" };
	int i;

	scanf("%s", &aa);
	for (i = 0; i < strlen(aa); i++)
	{
		ESI = aa[i];

		ESI = ESI + EDX;
		ESI = ESI * 0x772;
		EDX = ESI;
		EDX = EDX * ESI;
		ESI = ESI + EDX;
		ESI = ESI * 0x474;
		ESI = ESI + ESI;
		EDX = ESI;
	}
	
	printf("%X", ESI / 0x10000);

	return 0;
}

 

코드를 실행시키면 출력되는 값이 OllyDBG에서 확인한 값과 같다는 것을 확인할 수 있습니다.

 

하지만 키 값이 BEDA-2F56-BC4F4368-8A71-870B가 되게 하는 이름을 구하는 것이 목표이므로 입력할 수 있는 모든 이름을 대입하는 코드를 짜서 답을 구해보겠습니다.

#define _CRT_SECURE_NO_WARNINGS

#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	int ESI, EDX = 0;
	int i, j;

	for (i = 0; i < 128; i++)
	{
		ESI = i;
		EDX = 0;

		ESI = ESI + EDX;
		ESI = ESI * 0x772;
		EDX = ESI;
		EDX = EDX * ESI;
		ESI = ESI + EDX;
		ESI = ESI * 0x474;
		ESI = ESI + ESI;
		EDX = ESI;

		if (ESI >= 0xBEDA0000 && ESI <= 0xBEDAFFFF)
		{
			printf("%c->%X", i, ESI);
		}
	}

	return 0;
}

 

이 코드를 실행시키면 

 

이런 결과가 출력됩니다.

F를 이 프로그램에 넣어보겠습니다.

 

성공메시지가 출력됩니다.

 

Flag: F

'CodeEngn Write Up > Basic' 카테고리의 다른 글

CodeEngn Basic RCE L19 Write Up  (1) 2022.05.13
CodeEngn Basic RCE L18 Write Up  (2) 2022.05.12
CodeEngn Basic RCE L16 Write Up  (0) 2022.03.31
CodeEngn Basic RCE L15 Write Up  (3) 2022.03.11
CodeEngn Basic RCE L14 Write Up  (0) 2022.03.11