728x90
  • Easy_Keygen

 

 

Reversing.Kr 사이트에서 Easy Keygen 예제를 풀어보려 한다. 문제 파일을 다운 받으면, exe 실행파일과 메모장을 얻을 수 있다.

 

 

메모장을 먼저 열게 되면 시리얼 번호 5B134977135E7D13 일 때의 name을 찾는 예제로 실행파일을 실행했을 때 맞는 name이 아닌 경우에 wrong 을 출력하고 종료하는 것을 확인 할 수 있다.

 

 

 

올바른 name을 찾기 위해서는 어떻게 해야할까?? 먼저 ollydbg에 들어가 실행파일을 열어 보았다.

 

 

 

name 값을 알아내려면 먼저 correct 와 wrong 이 출력되는 부분을 보면 단서가 나오지 않을까 하는 생각에 코드를 찾아 봤다. correct가 출력되는 줄 전에 jmz 명령어는 것을 보고 어딘가 name을 비교하고 점프해서 값을 출력하는 구조일 것이라 추측할 수 있었다.

 

 

 

그렇다면 name을 받는 부분을 살펴보자. name을 받는 부분에 브레이크포인트를 걸고 임의 name으로 abcd 를 입력해 주었더니 EDI에 abcd가 들어가는 것을 확인 할 수 있다. 하지만 확연하게 name을 어떻게 얻는지는 아직까지는 잘 모르겠다.

 

 

그 후 계속 진행하며 아래에 가니 loop 문을 발견했고 그 아래에 movsx 명령어로 ECX, EDX 에 값이 들어가게 되는데 이 값들은 name을 받고 나서 나왔던 mov 0x10, 0x20, 0x30 이 반복해서 들어가게 된다. 그 후 xor 연산으로 ECX 값이 EDX로 들어가게 된다. 

 

지금까지의 이해로 풀이를 하였을 때, 문제 해결을 위해서는 입력 Name 문자열에 0x10, 0x20, 0x30을 각각 XOR연산한 결과가 "5B134977135E7D13"인 Name을 찾을 수 있다는 것이다. xor 연산을 하게 되면 name을 알수 있다.

 

 

 K3yg3nm3 

 


  • reversing_me

 

이 예제에서 주어진 코드를 분석하면, 입력받은 값의 길이와 serial 값의 길이가 53바이트로 같으면 if문을 i<strlen(serial) && (enter[i]^(0,1,0,1, ...))==serial[i]일 때까지 반복한다. 코드에서 ^가 나오는 걸 보고 구글링해봤더니 xor 연산자라고 한다. 

 

그렇다면, serial 값을 xor 연산을 통해서 키 값을 얻으면 되지 않을까? flag 값을 구하는 코드를 작성했다.

#include <stdio.h>
#include <string.h>
 
int main() {
    char* serial = "H`cjCUFzhdy^stcbers^D1_x0t_jn1w^r2vdrre^3o9hndes1o9>}";
    
    for (int i = 0; i < strlen(serial); i++)
        printf("%c", serial[i] ^ (i % 2));
}

 

결과는 flag 값을 얻을 수 있었다!

 

728x90
  • rev-basic #02

 

이전 예제들과 비슷한 유형으로 파일을 실행해 아무값을 입력해줬더니 wrong이 떴다.

 

 

 

IDA에 들어가면 main 화면에 이와 같이 나오고 문자열을 비교해 출력하게끔 하는 함수로 추정할 수 있는 sub_140001000 에 더블 클릭하게 되면 아래와 같은 화면이 나오게 된다.

 

 

 

분석하자면, 뭔가 rax와 12h를 비교해서 rax가 12보다 작지 않을때 jnb명령어를 통해 short loc_140001048 로 점프하는 것 같다. 

 

short loc_140001048에 더블 클릭을 하면 eax에 1을 넣는 다는 내용이 있다.

 

 

 

rax 값이 12를 넘지 않는 경우에는 어떻게 될 지 아래를 보니 위와 같은 화면을 보게 되었고, aC 배열 옆에 주석으로 "C" 있는 것을 보고 flag 값이 여기 있겠구나 싶었다. 

 

aC배열을 더블 클릭하니 위 같은 화면이 나와서 flag 값을 얻을 수 있었다.

 

입력값을 넣으니 correct 가 출력되었고, 문제를 풀었다.

 

https://dreamhack.io/wargame/challenges/16/

 

rev-basic-2

Reversing Basic Challenge #2 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출

dreamhack.io

 

 


  • easy unpack

 

 

처음에는 윈도우10에서 예제를 풀려고 했었는데, 보안 상의 이유로 가상머신에서 윈도우 7 환경에서 풀게 되었다.

 

다운받은 exe 파일을 실행해보니까 아무 내용도 없는 빈 창이 떴다. 

다운받은 파일에는 exe 파일과 메모장이 있는데, 메모장을 열어보니 이 예제는 OEP를 찾는 문제라는 것을 알았다. 

 

+ OEP란?

: OEP는 Orignal Entry Point로 EP는 엔트리 포인트이다. 엔트리 포인트는 운영체제가 사용자 프로그램으로 최초로 제어를 넘기는 지점으로 실행 코드가 최초로 실행되는 지점이라고 생각하면 된다.  

OEP는 실제 시작 지점으로  jmp문을 통해서 찾을 수 있다. 

 

 

 

OllyDbg를 통해 exe 파일을 열어 주었다. 

 

구글링을 하였을 때 일반적으로 OEP로 점프하는 코드 다음에는 옵코드 0으로 채워져 있는 경우가 있다고 하여 그러한 부분을 찾았더니 jmp 명령어가 있었다. 이부분에 브레이크포인트를 걸었다.

실행시켜 보면 OEP를 찾을 수 있다. 

 

http://reversing.kr/challenge.php

 

Reversing.Kr

Copyright © 2012-2022 Gogil All Right Reserved.

reversing.kr

 

728x90
  • rev_basic #00

 

: rev-basic-0 문제는 사용자에게 문자열을 입력 받아 correct! 를 출력하게 하는 입력값을 찾는 문제이다.

 

: 다운 받은 문제 파일을 cmd 창으로 열어 아무런 값을 입력하게 되면 Wrong 이 출력된다. 

 

여기서 문제가 발생하는데 해당 파일은 64비트 exe 프로그램이어서 ollydbg, immunity debugger 에서는 열 때 오류가 발생하여 IDA를 이용하여 열어주었다.

( 처음에는 x62dbg 프로그램을 이용하려 했지만, 설치가 되지 않았다...ㅠ)

 

 

: input은 문자열이 입력받는 곳으로 main 에서 찾게 되면 입력받은 값은 rcx에 들어가는 걸 확인 할 수 있다.

 

이후 문자열을 대조하여 프린트하는 부분인 sub_140001000에 들어 가게 되면, 문자열 대조 함수인 strcmp 함수를 확인 할 수 있다.

 

 

: Compar3_the_str1ng 이 rdx에 들어가 rcx와 rdx가 strcmp를 통해 비교되는 것을 확인할 수 있다.

 

https://dreamhack.io/wargame/challenges/14/

 

rev-basic-0

Reversing Basic Challenge #0 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출

dreamhack.io

 

 

 

 


  • rev_basic #01

 

이 예제는 rev-basic-0 문제와 유사하게 correct를 출력하는 입력값을 찾아내는 문제이다.

 

 

cmd 창에 다운받은 파일을 실행하여 아무값을 입력해봤다. 결과는 wrong이 나왔고, 이제 IDA로 분석해보자!

 

IDA로 main을 열어보니 rev-basic-0와 유사한 형태인 것을 확인 할 수 있다. 입력한 값은 rcx로 들어가고, 문자열을 비교해 출력하는 형태이다.

 

sub_140001000에 들어봤더니 문자열 비교 함수인 strcmp가 없고 데이터 전송 명령어인 movzx 가 있다. 

ptr [rcx+rax]를 eax로 전송한다. 

movzx 명령어 다음줄에 cmp 로 통해 eax와 43h을 비교하는 것을 보고 flag 값을 유추할 수 있었다.

정리하면 Compar3_the_ch4ract3r 문자열이 나온다. 

입력값을 넣어주니 correct 가 출력되었다.

 

https://dreamhack.io/wargame/challenges/15/

 

rev-basic-1

Reversing Basic Challenge #1 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출

dreamhack.io

 

728x90
  • abex crackme - 01


: 이 예제에서 프로그램을 실행하였을 때, 하드디스크를 CD-Rom으로 인식하도록 하라는 화면이 뜨게 된다.

: Ollydbg를 이용해서 위 프로그램을 분석하려고 한다.



01. 엔트리 포인트

디버거를 통해 프로그램을 열면 실행되지 않고 특정 지점에서 멈추는 것을 확인할 수 있는 지점을 엔트리 포인트라고 한다.

프로그램이 로딩되면서 베이스 주소(Base Address) + RVA(상대주소)가 더해진 위치에 데이터가 저장된다.


디버거에서 메모리 상 시작 지점의 위치가 '00401000' 을 확인 할 수 있으며,

맨 마지막의 주소는 '004001061'을 확인 할 수 있다.


02. 명령어

    • F8(=스텝 오버): 프로그램을 한 줄씩 실행
    • F7(=스텝 인투): 'CALL 주소'를 실행하는 명령어에서 해당 주소의 서브루틴 안으로 들어간다.
    • F2(=브레이크포인트): 특정 명령어에 브레이크포인트를 설정 시, 프로그램 실행이 그 위치에서 일시 정지
    • F9 : 브레이크포인트 지점으로 바로 이동
    • Alt + B: 브레이크포인트 확인
    • Ctrl + F12: 프로그램 다시 시작
    • NumLock -: 전단계 혹은 후진 
    • NumLock +: 다음단계 혹은 전진


03. MessageBox() 함수의 구조

: PUSH OFFSET 00402000 / PUSH OFFSET 00402012는 메모리에 있는 데이터를 스택에 넣는 역할을 한다.
메모리에 어떤 데이터가 저장되어 있는 지는 마우스 오른쪽 클릭 후 Follow in Dump → Immediate constant 메뉴를 통해 확인할 수 있다.

+ 00은 null을 의미한다.


04. 서브루틴과 스택 프레임

- 서브루틴
: 스택 프레임 구조로 이루어져 있으며, 어떻게 동작하는지 알아보려면 F7을 통해 한 단계 들어가야 알 수 있다.


05. 프로그램 구조 분석

  • GetDriveTypeA( ) 함수 호출 : 드라이브 종류를 정수 형태로 반환한다. 함수의 반환값은 EAX 레지스터에 저장되며, 함수 실행이 끝나면 EAX 레지스터에 3이 저장된 것을 확인할 수 있는데, MSDN을 참조하면 반환값 3은 하드디스크 드라이브라는 것을 알 수 있다.

 

  • 드라이브 종류 확인 : INC, DEC 명령어는 뒤에 오는 레지스터값을 1씩 감소 또는 증가시키는 동작한다. 따라서 ESI 레지스터 값을 3 증가시키고 EAX 레지스터 값을 2 감소시킨다.

 

  • 비교문과 점프문 : CMP명령어는 뒤에 오는 두 레지스터의 값이 같으면 제로 플래그 레지스터 값을 1로 설정 뒤에 오는 JE 명령어는 앞의 비교구문 결과가 같으면 지정된 주소로 점프, 다르면 다음 행을 실행한다.

 

  • 제로 플래그 레지스터 : EAX레지스터와 ESI 레지스터의 값이 다르므로 제로플래그 레지스터에는 0이 저장된다.

 

  • 목적 달성 실패 : CMP EAX, ESI 구문의 결과가 다를 때 이 부분이 실행된다.

 

  • 목적 달성 성공 : CMP구문의 결과가 같을 때 JE SHORT 명령어를 수행하여 이 부분이 실행된다.


06. 문제해결

: JMP 주소를 00401023으로 바꿔주면 문제가 풀린다.


  • abex crackme - 02


두 번째 예제는 사용자가 입력한 이름과 관련있는 일련번호를 찾아내는 것이 목적으로 이름을 기반으로 만들어진 일련번호가 저장된 메모리 위치를 찾아가는 것이 문제 해결 방법이다.

01. 프로그램 실행

프로그램 실행 시 엔트리 포인트에서 실행을 멈추게 되는데, 이때 F9를 눌러 프로그램을 실행하면 MSVBUM60.ThunRTMain() 함수에서 실행이 멈추게 된다.

프로그램과 상호작용하려면 프로그램 실행 상태를 반드시 'Running' 으로 만들어야 한다.


02. 문자열 검색

프로그램 코드 양이 많을 경우 문자열 검색을 사용하면 유용하다.

공격 실패 또는 성공 시 여러 메시지를 볼 수 있는데, 이 메시지 문자열을 검색해 디버깅 위치를 결정한다.

: 코드 영역에서 마우스 우클릭을 해서 Search for 메뉴 → All refernced text string 메뉴를 클릭하면 프로그램의 전체 문자열을 보여 준다.

Search for text 기능을 활용해서 필요한 문자열의 위치를 구해 준다.


03. 스택 분석하기

스택 분석을 위해 주소 '00403054' 에  브레이크포인트를 설정해 준다.

프로그램을 실행해 2자리 이름과 일련번호 1234를 입력해서 프로그램이 브레이크포인트로 이동하도록 해 준다.

입력 후 check를 누르면 디버거가 브레이크포인트 부분에서 자동으로 멈춘다.
스텝 오버 기능으로 프로그램을 주소 00403066까지 실행해 준다.

아까 찾은 문자열 주소로 스택 데이터를 수정해 준다.
스택 주소에서 binary메뉴의 edit을 선택하고 원하는 데이터가 있는 주소로 주소값 변경을 해주면 된다.



04. 메모리 분석하기

- 메모리:  Adress, Hex dump, ASCII

- 디버거는 ASCII영역에서 헥스 덤프의 데이터를 아스키값으로 변경해 디버깅 시 참고할 수 있도록 해준다.

메모리에 저장된 값을 수정해 메시지 창의 타이틀을 변경한다.

Error 문자열 부분을 선택하여  right로 변경해 준다.

: 수정 후 프로그램을 실행하면 타이틀이 변경된 것을 확인할 수 있다.


05. 프로그램 구조 분석

01) 입력한 이름의 길이를 검사하는 부분으로, 4자리보다 작으면 오류가 발생한다.

02) 이름을 사용해서 반복문으로 일련번호를 생성하는 부분이다.

03) 일련번호를 확인하고 맞으면 첫번째, 틀리면 두 번째 문자열을 보여 준다.

06. 문제해결

메모리 영역에서 우클릭 Integer->Address with ASCII dump 메뉴를 선택하면 4바이트 단위의 아스키 값을 확인할 수 있고, 문자열 'C5C6C7C8' 이 저장된 것을 확인할 수 있다.

name에 abcd, 일련번호에 C5C6C7C8를 입력해 주면 문제가 해결된다.

+ Recent posts