본문 바로가기
Security/Reversing

[CodeEngn] Challenges Basic RCE L20

by jino22 2021. 10. 18.

CodeEngn_Challenges Basic RCE L20

L20. 이 프로그램은 Key파일을 필요로 하는 프로그램이다.
'Cracked by: CodeEngn!' 문구가 출력 되도록 하려면 crackme3.key 파일안의 데이터는 무엇이 되어야 하는가
Ex) 41424344454647 (정답이 여러개 있는 문제로 인증시 맞지 않다고 나올 경우 Contact로 연락주시면 확인 해드리겠습니다)

 

파일 실행 결과 key파일이 없어서 그런지 아무것도 뜨지 않는다. 

파일 실행 / 파일 정보

 

더보기

key파일 없이 풀어보려도 시도했던 흔적..

 

createFileA API return결과 key파일이 없어 eax=FFFFFFFF이므로 401032에서 비교 후 분기되지 않는다. 

이 부분을 수정하여 key파일이 없어도 파일이 존재할 때 실행되는 코드로 가도록 변경했다.

다음 코드로 진행해도 파일이 없으면 ReadFile API에서 파일 읽기를 실패한다.

하지만 코드상으로 보았을 때 읽을 데이터는 12byte임을 알아낼 수 있다.

또한 읽은 데이터는 4020F5주소에 저장된다.

이번에도 파일이 없어서 분기되는 것을 막고 계속 코드 진행을 하기 위해 40106D의 코드를 수정하였다.

 

이후 401311함수로 들어가 보았다.

다음과 같이 문자열을 생성하는 루틴이 존재한다.

 

* sete: ZF=1이면 바이트형 레지스터=1

401037로 분기해 4012F5함수를 지난다.

풀다보니 아무래도 key파일을 생성한 후 진행하는게 나을 것 같아 생성 후 처음부터 다시 분석했다..

key파일 없이 풀어보려도 시도했던 흔적..

EP

createFileA API return결과 key파일이 없어 eax=FFFFFFFF이므로 401032에서 비교 후 분기되지 않는다. 

이 부분을 수정하여 key파일이 없어도 파일이 존재할 때 실행되는 코드로 가도록 변경했다.

코드 변경

다음 코드로 진행해도 파일이 없으면 ReadFile API에서 파일 읽기를 실패한다.

하지만 코드상으로 보았을 때 읽을 데이터는 12byte임을 알아낼 수 있다.

또한 읽은 데이터는 4020F5주소에 저장된다.

이번에도 파일이 없어서 분기되는 것을 막고 계속 코드 진행을 하기 위해 40106D의 코드를 수정하였다.

 

이후 401311함수로 들어가 보았다.

다음과 같이 문자열을 생성하는 루틴이 존재한다.

4020F9 = A-N까지 더한 값

 

* sete: ZF=1이면 바이트형 레지스터=1

401037로 분기해 4012F5함수를 지난다.

4012F5 함수 내

풀다보니 아무래도 key파일을 생성한 후 진행하는게 나을 것 같아 생성 후 처음부터 다시 분석했다..

 

우선 crackme3.key파일을 생성한다. 

이전에 했던 시행착오에서 파일 내의 데이터는 18(0x12)바이트임을 알아냈으니 1을 18개 작성하였다.

main
401311 함수

401311함수에서 연산할 때 문자열 내 18개의 문자를 모두 연산하는 것이 아니라 A-O까지 14개만 연산한다.

40133C 함수

이후 40133C함수에서 그 이후의 주소와 문자열을 읽어온다.

main

연산 이후의 문자열(연산되지 않은 15-18번째 입력 문자열)과 연산 누적합이 같아 sete명령어에 의해 al값이 1로 세팅되고, 그래서 40109F에서 분기가 취해지지 않으면 메시지를 출력하는 함수로 갈 수 있다. 

바이너리를 살짝 바꿔서 출력 함수로 진행되도록 한다.

* SETE: ZF가 1이라면 바이트형 레지스터를 1로 세팅, 여기서는 cmp에서 두 값이 같아 ZF=1이 되면 al=1이 된다.

401346 함수
esi에 입력한 문자열

메시지박스를 생성하는 부분이다.

401362 함수 / 현재 출력 결과

* REP  MOVSB :메모리 복사 명령어 ESI의 메모리를 EDI로 복사한다.

 

드디어 메시지박스에 출력할 문자열을 입력하는 함수를 찾았다.

[ESP+4]=402008의 메모리(문제에서 CodeEngn 문구)를 [ESP+8]=40216A(문구가 들어가야 할 위치)로 복사한다. 

따라서 402008의 메모리가 CodeEngn! 이 되어야 한다는 것을 알아냈다.

현재 psrutwvyz~가 들어있다. 이 문자열은 위에서 "1111~" xor "ABCD~" 한 데이터이다.

 

key파일에 입력되어 있어야 할 문자열에 대한 힌트를 모두 얻었다.

① ABCD EFGH IJKL MN xor 입력 문자열 앞 14자리 =  CodeEngn이 되어야 하며,

② 윗줄에서 연산한 문자(=CodeEngn) 누적 합 xor 12345678 = 입력 문자열 뒤 4자리가 되어야 한다.

복잡하니까 이 과정을 코드로 구현했다.

코드 구현

□ xor A = C >> □ = C xor A 특징을 이용했다.

따라서 key파일에 입력되어야 하는 데이터는 02 2D 27 21 00 28 20 26 49 4A 4B 4C 4D 4E 7B 55 34 12 이다.

 

변경 전
변경 후
1번 결과 / 2번 결과
비교 결과 같으므로 ZF=1 > EAX=123455"01" 로 변경
메시지 복사됨
출력 결과

 

728x90
반응형

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

데이터 보호 기법-Canary  (0) 2021.11.11
UAF 공격  (0) 2021.11.06
디버깅 탐지 방법  (0) 2021.10.15
[CodeEngn] Challenges Basic RCE L17, L18, L19  (0) 2021.10.14
KeyLogger 분석  (0) 2021.09.27

댓글