ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CodeEngn Basic RCE 20
    $ 리버싱 $/CodeEngn Basic RCE 2019. 5. 7. 16:14

     

    파일을 실행 해보니 이렇게만 뜨네요.

     

    올리디버거로 실행을 해보겠습니다.

     

    ↑ main 함수

     

    아래로 내려가 보겠습니다.

     

    CreateFileA함수로 FileName : CRACKME3.KEY로 파일을 만들어 줍니다. 그러면 CMP로 EAX의 값인 

    FFFFFFFF( -1 ) 와 -1을 비교 해서  똑같기 때문에 401043으로 점프를 하지 않고 아래로 내려갑니다.

    그러면 CrackMe v3.0 - Uncracked를 40210E에 PUSH 하고 프로그램이 40210E로 인해서 아무런 창이 뜨지 않고 종료 하게 됩니다. 

     

    그래서 첫번째 분기점은 401032 이기 때문에 저이름으로 파일을 하나 만들어 보겠습니다.

    FFFFFFFF에서 1E8로 바뀐것을 찾았습니다. 그렇게 되면 JNZ에 따라서 다음 문자열을 40210E에 넣지 않게 되는 군요.

     

    그리고 계속 내려가 보겠습니다.

    두번째 분기점에 도달 했습니다. 

    4021A0와 12(18)이랑 비교를 하는 것 같은데 4021A0가 어디서 입력되는 지 보았는데 401054에서 파일의 BYTE 크기를 입력 받는다는 것을 알게 되었습니다. 그렇다면 .KEY의 바이트 크기를 18로 맞춰 보겠습니다. ( 숫자나 영어는 1Byte , 한글은 2Byte 입니다.)

    아까랑 좀 다른것 같습니다. 파일의 내용이 다음과 같이 뜨네요.

    크기가 일치하기 때문에 40106D에서 점프를 하지 않고 그냥 내려갑니다.

     

    40106F에서 우리가 입력한 "111111111111111111" 문자열이 402008로 PUSH 됩니다.

    아래로 내려가는데 4020F9에 들어있는 값과 12345678을 XOR 합니다.

     

    4020F9에는 80 06 00 00  리틀 엔디안 방식으로 입력 되어있습니다.

     

    XOR 한 후 데이터 값은 다음과 같습니다.

    F1 50 34 12 라는 값이 중요한 값이 될것 같아서 기억하고 있어야 할것 같습니다.

     

    세번째 분기점에 도달 했습니다. 

     

    방금 값을 확인 했었던 4020F9 와 EAX의 값을 비교하는 비교문 입니다. 

     

    EAX에는 31313131이 들어있는데 이는 "1111"을 의미합니다. 

     

    18개의 1 중에서 어디부분의 1111인지 확인을 해본 결과 맨마지막 자리 4자리의 1111이였습니다. 

     

    F1 50 34 12는 리틀 엔디안 방식으로 입력되어있기 때문에 Hex 에디터를 이용해서 값을 넣어 보겠습니다.

     

    그리고 저장후에 다시 실행을 해보겠습니다.

     

     

    두값이 일치하기 때문에 ZF의 값이 1이 되고 ZF가 1이여서 AL의 값도 1이 되고 AL AND AL 을 할때 AL의 값이 1이기 때문에 0이 아닌 수인 1이 반환 됩니다.

    그래서 TEST AL, AL 의 반환값이 0이 아닌 다른 수 이기 때문에 ZF가 0이 되고 ZF가 0이므로 JE에서 점프가 되지 않고 그냥 내려가게 됩니다.  

     

    하나씩 조건을 충족해서 내려가고 있는데 아까 계속 피하려고 했었던 문자열이 아래에 있습니다.

     

    물론 CrackMe v3.0이라는 문자열을 만났지만 4010AB에서 ESP의 값을 4만큼 증가 시켜 줌으로써 호출하는 문자열의 주소를 변경해 줘서

    위의 CrackMe v3.0은 호출 되지 않게 됩니다.

     

    우리가 출력해야 하는 문자열이 좀 아래쪽에 위치해 있어서 역으로 거슬러 올라가보겠습니다.

    우리가 출력해야 하는 문자열은 40216A에 위치하고 있습니다.

     

    덤프창으로 확인해 보면 값이 들어있는데 새로 재시작한뒤에 보면 값이 비워져 있습니다.

    ↑ 비워져 있다.

     

    그래서 어디에서 데이터가 채워지는지를 알아보겠습니다.

    위의 사진처럼 401373을 지나가면 값이 들어오게 됩니다.

    저 빈공간에는 우리가 입력한 값이 XOR된 값인 402008에 있는 값이 들어갑니다.

    ↑ 40216A에 있는 데이터

     

    ↑ 402008에 있는 데이터

     

    분명 아까는 XOR 한값은 맨 뒷자리 4자리 였는데 지금 보이는 값은 전부 XOR된듯 하게 1의 문자를 총 18자리에서 볼수가 없습니다.

     

    그렇다는 것은 위에서 미리 변환되서 내려 왔다는 것을 뜻합니다. 그렇다면 다시 재실행 해서 변환 되는 함수를 찾아보겠습니다.

    위와 같이 401061을 지나가면 값이 입력됩니다. 

     

    그리고 나서 어디서 값이 변화 되는지를 확인해 보겠습니다.

    401074를 지나자 마자 값이 아예 다 바뀌였습니다. 

     

    그렇다는 것은 401311주소에 있는 코드가 값을 바뀌게 하는 것이므로 F7을 이용해서 들어가 보겠습니다.

    코드를 좀 보면...

     

    입력되어있는 문자열의 첫번째 문자를 HEX값으로 반환해서 AL에 저장.

    BL은 41이라는 값을 가지고 있기 때문에 XOR연산후 다시 AL에 저장을 시킵니다.

    그리고 BL을 1증가 시키고 AL이 0이 아니라면 CL을 하나 증가 시키고 위의 작업을 반복 시키는 역할을 합니다.

    이렇게 해서 나오는 값이 첫 문제에서 원했던 CodeEngn! 이 나와야 합니다.

     

    이 과정에서 역으로 계산 코드를 직접 하셔도 되고 코드로 작성 하셔도 됩니다.

     

    저는 코드로 작성해 보겠습니다.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    #include <stdio.h>

     

    char strings[] = "CodeEngn";

    int num = 0x41;

    int result = 0;

     

    void main(void) {

        for (int i = 0; i < strlen(strings) + 1; i++)

        {

            printf("%x ", strings[i] ^ num);

            result += strings[i];

            num++;

        }

    }

    ↑ codeengn_20.c

     

    ↑ 실행 결과

     

    이값을 Hex로 넣어 보겠습니다.

    아래로 좀 내려가 보니 4020F9의 값이 바껴있습니다. 이것을 수정해 주도록 합시다.

     

    위 사진과 같이 수정해 줍니다.!

    드디어 끝이 났습니다..!!!

     

    '$ 리버싱 $ > CodeEngn Basic RCE' 카테고리의 다른 글

    CodeEngn Basic RCE 18  (0) 2019.07.16
    CodeEngn Basic RCE 19  (0) 2019.05.07
    CodeEngn Basic RCE 17  (0) 2019.05.07
    CodeEngn Basic RCE 16  (0) 2019.05.07
    CodeEngn Basic RCE 15  (0) 2019.05.07

    댓글

Designed by Tistory.