Wargame/CodeEngn Basic RCE

CodeEngn Basic RCE L17 Write-Up

0xe82de_ 2019. 8. 26. 20:07
728x90
728x90
728x90

파일 링크: https://codeengn.com/challenges/

 

CodeEngn.com [코드엔진] - Challenges

코드엔진은 국내 리버스엔지니어링 정보공유를 위해 2007년 부터 리버스엔지니어링 컨퍼런스 및 비공개 워크숍을 현업 실무자들과 함께 운영하고 있습니다. 리버스엔지니어링이라는 하나의 큰 주제로 소프트웨어 보안에 대한 다양한 시각과 연구주제에 대한 정보공유를 추구하고 있으며, 상업적 이익 없이 작은 예산으로 운영하고 있어 큰 예산으로 운영하는 다른 컨퍼런스에 비해 여러 가지로 부족 할 수 있습니다.

codeengn.com

[사진 17]

풀어보자.

 

 

[사진 2]
[사진 3]

파일을 실행하고 Name, Key 값을 입력하면 위와 같다. 코드엔진 문제에서 Name이 한 자리라고 하는데, 한 자리만 입력하면 문자를 더 입력하라고 한다. 이 부분부터 패치해야 한다.

 

 

[사진 4]

code 섹션에서 우클릭 - Search for - All referenced strings 기능을 클릭하면 위와 같이 사용되는 문자열들을 확인할 수 있다. "Please Enter More Chars..." 문자열이 사용되는 곳을 살펴보자.

 

 

[사진 5]

위와 같이 Name 값의 길이가 3 이상인지 검사한다.

 

 

[사진 6]

JGE 명령어를 JMP 명령어로 패치하면 Name 값의 길이에 상관 없이 점프한다.

 

 

[사진 7]

패치된 파일을 실행하고 Name 값에 'a' 문자를 입력하고 실행하면 Name 값이 틀렸기 때문에 아무 창도 뜨지 않는다.

 

 

[사진 8]

루틴 아랫 부분을 살펴보면 "Well done!" 문자열이 사용되고 있다. 0x0045BB9B 주소의 CALL 명령어로 0x0045B850 함수가 호출된 후 "66EE-3EEC-2A139188-8B4F-79E2" 문자열을 EDX 레지스터에 복사한다. 즉, 이 문자열이 내가 입력한 'a' Name 값으로 만들어진 Key일 것이다. 따라서 0x0045B850 함수를 살펴봐야 한다.

 

 

[사진 9]

0x0045B850 함수 내부를 보며면 반복 루틴이 여러 개 존재한다. 이 중 첫 번째 루틴이 종료되면 EDX 레지스터에 0x66EE46F0 값이 저장되는데 상위 4bytes의 0x66EE 값은 [사진 8]에서 확인했던 문자열의 앞 부분이다. 이 루틴에서 Key의 네 자리가 만들어지는 것이다. 따라서 이 루틴이 끝나고 EDX 레지스터의 상위 4bytes 값이 0xBEDA 값이 되면 된다.

 

 

import hashlib

list = [\
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', \
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', \
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', \
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', \
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

for key in list:
    esi = int(ord(key))
    edx = 0
    esi += edx
    esi *= 0x772
    edx = esi
    edx *= esi
    esi += edx
    esi *= 0x474
    esi += esi
    edx = esi
    
    password = hex(edx).upper()[2:][4:-4]
    if password == "BEDA":
        print("Name => %c" %(key))
        print("Key  => %s" %(hex(edx).upper()[2:][4:-4]))
        print("md5  => %s" %(hashlib.md5(key.encode()).hexdigest()))

위와 같이 Python으로 대/소문자 알파벳과 숫자의 연산 결과 값이 "BEDA" 문자열과 같으면 key와 md5 값을 출력한다.

 

 

[사진 10]

실행 결과는 위와 같다. Name 값은 'F' 문자이고 md5 값은 0x800618943025315f869e4e1f09471012이다.

 

 

[사진 11]

'F' 문자를 Name에 입력하고 Key를 입력하면 성공한다.

 

Auth Key 값은 md5 값이다.

728x90
728x90