'SECURITY/리버싱(역공학)'에 해당되는 글 4건

  1. 2015.08.20 리버싱 4장
  2. 2015.08.20 리버싱 3장
  3. 2015.08.19 리버싱 2장
  4. 2015.08.19 리버싱 1장

1. CPU 레지스터란?

- CPU 내부에 존재하는 다목적 저장 공간

- CPU와 한 몸이기 때문에 고속으로 데이터를 처리


1-1. 레지스터에 대해서 알아야 하는 이유

- 디버거가 해석(디스어셈)해주는 어셈블리 명령어를 공부해야 함

- 어셈블리 명령어의 대부분은 레지스터를 조작하고 그 내용을 검사하는 것이기 때문에 레지스터에 대해서 알아야함


2. IA-32의 레지스터

# IA-32 레지스터의 종류

+ Basic program execution registers

+ x87 FPU registers

+ MMX registers

+ XMM registers

+ Control registers

+ Memory management registers

+ Debug registers

+ Memory type range registers

+ Machine specific registers

+ Machine check register

* 초급 단계에서는 Basic program execution register에 대해 알아두고 중/고급 단계로 올라가면 추가적으로 Control registers Memory management registers, Debug registers 등에 대해서 공부하기 바람


2-1. Basic program execution registers

# 그룹

+ General Purpose Registers (32비트 - 8개)

+ Segment Registers (16비트 - 6개)

+ Program Status and Control Register (32비트 - 1개)

+ Instruction Pointer (32비트 - 1개)


1) 범용 레지스터

- 범용적으로 사용되는 레지스터

- 크기 : 32비트(4바이트)

- 상수/주소 등을 저장할 때 사용

- 특정 어셈블리 명령어에서는 특정 레지스터를 조작하기도 함


# 각 레지스터 이름 - 1

+ EAX : Accumulator for operands and results data

+ EBX : Pointer to data in the DS segment

+ ECX : Counter for string and loop operations

+ EDX : I/O pointer


- 주로 산술연산(ADD, SUB, XOR, OR 등) 명령에서 상수/변수 값을 저장하기 위해 사용

- MUL, DIV, LODS 등은 특정 레지스터를 직접 조작하기도 함

- ECX는 반복문 명령어(LOOP)에서 반복 카운트(loop count)로 사용

- EAX는 일반적으로 함수 리턴 값에 사용되며 모든 Win32 API 함수들은 리턴 값을 EAX에 저장한 후 리턴


# 각 레지스터의 이름 - 2

+ EBP : Pointer to data on the stack (in the SS segment)

+ ESI : source pointer for string operations

+ EDI : destination pointer for string operations

+ ESP : Stack pointer (in the SS segment)


- 주로 메모리 주소를 저장하는 포인터로 사용

- ESP는 스택 메모리 주소를 가리킴

- PUSH, POP, CALL, RET은 ESP를 직접 조작하기도 함

*Stack Frame 기법 : ESP는 함수가 호출되었을 때 그 순간의 ESP를 저장하고 있다가, 함수가 리턴 하기 직전에 다시 ESP에 값을 되돌려줘서 스택이 깨지지 않도록 함

- ESI와 EDI는 LODS, STOS, REP, MOVS 등과 함께 주로 메모리 복사에 사용


2) 세그먼트 레지스터

- 세그먼트 : IA-32의 메모리 관리 모델에서 나오는 용어

- IA-32 보호모드에서의 세그먼트 : 메모리를 조각내어 각 조각마다 시작 주소, 범위, 접근 권한 등을 부여해서 메모리를 보호하는 기법

- 세그먼트는 페이징(Paging) 기법과 함께 가상 메모리를 실제 물리 메모리로 변경할 때 사용

- 세그먼트 메모리는 Segment Descripor Table(SDT)이라고 하는 곳에 기술

- 세그먼트 레지스터는 SDT의 index를 가지고 있음

- 세그먼트 레지스터는 총 6개(CS, SS, DS, ES, FS, GS)이며, 각각의 크기는 16비트(2바이트)이다.


- 세그먼트 디스크립터(Segment Descriptor)와 가상 메모리가 조합되어 선형주소(Linear Address)가 되며, 페이징 기법에 의해서 선형주소가 최종적으로 물리주소(Physical Address)로 변환

* OS에서 페이징을 사용하지 않는다면 선형주소는 그대로 물리주소가 됨


# 세그먼트 레지스터의 이름

+ CS : Code Segment

+ SS : Stack Segment

+ DS : Eata Segment

+ ES : Extra(Data) Segment

+ FS : Data Segment

+ GS : Data Segment


- CS는 프로그램의 코드 세그먼트를 나타냄

- SS는 스택 세그먼트

- DS는 데이터 세그먼트

- ES, FS, GS 세그먼트는 추가적인 데이터 세그먼트

- FS 레지스터는 애플리케이션 디버깅에도 자주 등장하는데 SEH(Structured Exception Handling), TEB(Thread Environment Block), PEH(Process Environment Block)등의 주소를 계산할 때 사용


3) 프로그램 상태와 컨트롤 레지스터

- 플래그(Flag) 레지스터의 이름은 EFLAGS이며 32비트(4바이트) 크기

- 각 비트는 1 또는 0의 값을 가지는데, 이는 On/Off 혹은 True/False를 의미


#주요 flag

+ Zero Flag(ZF) : 연산 명령 후에 결과 값이 0이 되면 ZF가 1(True)로 세팅

+ Overflow Flas(OF) : 부호가 있는 수(signed integer)의 오버플로가 발생했을 때 1로 세팅, MSB(Most Significant Bit)가 변경되었을 때 1로 세팅

+ Carry Flag(CF) : 부호 없는 수(unsigned integer)의 오버플로가 발생했을 때 1로 세팅


4) Instruction Pointer

- EIP : Instruction pointer

- CPU가 처리할 명령어의 주소를 나타내는 레지스터

- 32비트(4바이트) 크기

- CPU는 EIP에 저장된 메모리 주소의 명령어(instruction)를 하나 처리하고 난 후 자동으로 그 명령어 길이만큼 EIP를 증가

- EIP는 그 값을 직접 변경할 수 없도록 되어 있어서 다른 명령어를 통하여 간접적으로 변경

- JMP, Jcc, CALL, RET을 사용하거나 인터럽트(interrupt), 예외(exception)를 발생 시켜야함

'SECURITY > 리버싱(역공학)' 카테고리의 다른 글

리버싱 3장  (0) 2015.08.20
리버싱 2장  (0) 2015.08.19
리버싱 1장  (0) 2015.08.19
Posted by OnewayK
,

1. 바이트 오더링

- 데이터를 저장하는 방식을 의미

- 빅 엔디언(Big Endian)과 리틀 엔디언(Little Endian)으로 나뉨


1-1. 리틀 엔디언 & 빅 엔디언

 BYTE b = 0x12;

 WORD w = 0x1234;

 DWORD dw = 0x12345678;

 char str[] = "abcde";


TYPE

Name 

SIZE 

빅 엔디언 

리틀 엔디언 

BYTE 

[12] 

[12] 

WORD 

[12][34] 

[34][12] 

DWORD 

dw 

[12][34][56][78] 

[78][56][34][12] 

char [] 

str 

[61][62][63][64][65][00]

[61][62][63][64][65][00] 


구분

빅 엔디언 

리틀 엔디언 

장점

 사람이 보기에 직관적

 산술 연산과 데이터의 타입이 확장/축소 될 때 더욱 효율적 

주로 사용되는 곳

 대형 UNIX 서버에 사용되는 RISC 계열의 CPU 

 네트워크 프로토콜

 Intel x86 CPU 

특징

 사람이 보는 방식과 동일하게 앞에서 부터 순차적으로 저장 

 - 데이터를 저장할 때 역순으로 저장

 - 바이트 자체는 정상적인 순서로 저장

 - 멀티바이트(multi-bytes)인 경우 각 바이트가 역순으로 저장

 - str 문자열은 Endian 형식에 상관 없이 동일 (char 배열이므로 각 바이트를 연속해서 저장)

'SECURITY > 리버싱(역공학)' 카테고리의 다른 글

리버싱 4장  (0) 2015.08.20
리버싱 2장  (0) 2015.08.19
리버싱 1장  (0) 2015.08.19
Posted by OnewayK
,

1. Hello World! 프로그램


- Release 모드로 빌드해서 실행 파일을 만든다.(Release 모드로 빌드하면, 코드가 좀 더 간결해져서 디버깅하기 편하다.)


2. HelloWorld.exe 디버깅

2-1. 목표

- HelloWorld.exe 실행 파일을 디버깅(Debugging)하여 어셈블리 언어로 변환된 main() 함수 찾기

- 기본적인 디버거의 사용법과 어셈블리 명령어 학습


2-2. 디버깅 시작

- OllyDbg: http://www.ollydbg.de

* 64bit 버전 사용


설명 

Code Window 

 disassembly code를 표시하여 각종 comment, label을 보여주며, 코드를 분석하여 loop, jump 위치 등의 정보를 표시 

Register Window 

 CPU register 값을 실시간으로 표시하며 특정 register들은 수정 가능

Dump Window 

 프로세스에서 원하는 memory 주소 위치를 Hex와 ASCII/유니코드 값으로 표시하며 수정도 가능 

Stack Window 

 ESP register가 가리키는 프로세스 stack memory를 실시간으로 표시하며 수정도 가능


2-3. EP(EntryPoint)

- 디버거가 멈춘 곳은 EP(EntryPoint) 코드로, 실행파일의 시작 주소이다.

 Address     Instruction     Disassembled code    comment

 --------------------------------------------------------------------------

 004011A0  E8 67150000  CALL 0040270C      ; 0040270C (40270C 주소의 함수를 호출)

 004011A5  E9 A5FEFFFF  JMP 0040104F       ; 0040104F (40104F 주소로 점프) 


 구분

설명 

Address 

 프로세스의 가상 메모리(Virtual Address:VA)내의 주소 

Instruction 

 IA32(또는 x86) CPU 명령어 

Disassembled code 

 OP code를 보기 쉽게 어셈블리로 변환한 코드 

comment 

 디버거에서 추가한 주석(옵션에 따라 약간씩 다르게 보임) 


3. OllyDbg 사용하기

3-1. OllyDbg 단축키

명령어 

단축키 

설명 

Restart 

Ctrl+F2 

 다시 처음부터 디버깅 시작(디버깅 중인 프로세스를 종료하고 재실행) 

Step Into 

F7 

 하나의 OP code 실행(CALL 명령을 만나면 그 함수 코드 내부로 따라 들어감) 

Step Over 

F8 

 하나의 OP code 실행(CALL 명령을 만나면 따라 들어가지 않고 그냥 함수 자체를 실행) 

Execute till Return 

Ctrl+F9 

 함수 코드 내에서 RETN 명령어까지 실행(함수 탈출) 

Go to

Ctrl+G 

 원하는 주소로 이동(코드/메모리를 확인할 때 사용, 실행되는 것은 아님) 

Execute till Cursor 

F4 

 cursor 위치까지 실행(디버깅하고 싶은 주소까지 바로 갈 수 있음) 

Comment 

 Comment 추가 

User-defined comment

 

 마우스 우측 메뉴 Search for User-defined comment 

Label 

 Label 추가 

User-defined label

 

 마우스 우측 메뉴 Search for User-defined label 

Set/Reset BreakPoint 

F2 

 BP 설정/해제 

Run 

$9

 실행(BP가 걸려있으면 그곳에서 실행이 정지됨) 

Show the current EIP 

 현재 EIP 위치를 보여줌 

Show the previous Cursor 

 직전 커서 위치를 다시 보여줌 

Preview Call/JMP address

Enter 

 커서가 CALL/JMP 등의 명령어에 위치해 있다면, 해당 주소를 따라가서 보여줌
            (실행되는 것이 아님, 간단히 함수 내용을 확인) 

3-2. 베이스캠프 설정하기

1) Goto 명령

- 베이스캠프 주소를 기억해 두었다가 Go to[Ctrl+G] 명령으로 베이스캠프로 이동

* Goto명령[Ctrl+G] 이후 주소 입력


2) BP(Break Point) 설치

- Break Point를 설치[F2]를 하고 실행[F9]

* BP 설정[F2]시 Address부분이 빨간색으로 변함


- BP 설정은 View - Breakpoints에서 확인 가능([Alt+B])

* 해당목록에서 더블클릭시 해당 주소로 이동


3) 주석

[;] 단축키로 주석(Comment)을 달고, 이 주석을 찾아가는 방법도 있다.


* BaseCamp라는 이름으로 주석 설정


* 설정 완료



* 오른쪽 마우스 > Search for > User comments에서 확인 가능


3-3. 원하는 코드 빨리 찾는 방법

1) 코드 실행하기

- 프로그램의 기능이 명확한 경우 명령어를 하나하나 실행(Step Over[F8])을 통해 원하는 위치를 찾아감

- 코드의 크기가 작고, 기능이 명확한 경우에 사용

- 코드의 크기가 크고 복잡한 경우에는 적절하지 못함


2) 문자열 검색 방법

- OllyDbg가 디버깅할 프로그램을 처음 로딩할 때 사전 분석 과정을 통해 참조되는 문자열과 호출되는 API들을 뽑아내서 따로 목록으로 정리

- 오른쪽마우스 > Search for > All referenced text strings


3) API 검색 방법(1) - 호출 코드에 BP

- 오른쪽마우스 > Search for > All intermodular calls


4) API 검색 방법(2) - API 코드에 직접 BP

- 오른쪽마우스 > Search for > Names


- OllyDbg가 모든 실행 파일에 대해서 API 함수 목록을 추출할 수 있는 것은 아니다.

- Packer/Protector를 사용하여 실행 파일을 압축(또는 보호)해버리면, 파일 구조가 변경되어 OllyDbg에서 API 호출 목록이 보이지 않음


 용어

설명 

Packer(Run Time Packer) 

 - 실행 압축 유틸리티, 실행 파일의 코드, 데이터, 리소스 등을 압축

 - 일반 압축 파일과 다르게 실행 압축된 파일 그 자체도 실행 파일임 

Protector

 - 실행 압축 기능 외에 파일과 그 프로세스를 보호하려는 목적으로

 - anti-debugging, anti-emulating, anti-dump 등을 추가

 - Protector를 상세 분석하기 위해서는 높은 수준의 리버싱 지식이 요구


- 해당 파일을 리버깅하기 위해서는 프로세스 메모리에 로딩된 라이브러리(DLL 코드)에 직접 BP를 걸어보아야 한다.

- API는 OS에서 제공한 함수이고, 실제로 API는 C:\Windows\system32 폴더에 *.dll 파일 내부에 구현되어 있다.

- 프로그램이 OS에서 실행되기 위해서는 OS에서 제공하는 API를 사용해서 OS에 요청을 해야 하고, 그 API가 실제로 구현된 시스템 DLL 파일들은

  프로그램의 프로세스 메모리에 로딩되어야 한다.

- OllyDbg에서 확인하는 방법은 View > Memory map[Alt+M]


* KERNEL32에 로딩되는 것을 확인 할 수 있다.


- KERNEL32에서 .text 부분에 들어가서 printf를 확인할 수 있다.


- 해당부분에 breakpoint를 걸고 확인해 보면 잘 되는 것을 확인 할 수 있다.


4. 문자열 패치하기

- 문자열 버퍼를 직접 수정

- 다른 메모리 영역에 새로운 문자열을 생성하여 전달

4-1. 문자열 버퍼를 직접 수정

- Dump window에서 "Hello World!"가 저장된 메모리인 '012A573C'로 이동


- 해당부분을 선택하고 Enter를 누르면 수정 창이 뜬다.

- 유니코드는 알파벳 하나당 2Byte의 크기를 차지한다.

* 원본 문자열에 덮어씌울 경우 그 뒤의 데이터가 훼손 되지 않게 조심하여야 한다. 훼손시 메모리 참조 에러가 발생할 위험이 있다.


* 유니코드 문자열은 2Byte 크기의 NULL로 끝나야 한다.


* 수정된후 실행화면

- 해당 방법은 수정후 프로그램을 다시 저장하지 않으면 프로그램 종료후 원상 복구 된다.


4-2. 다른 메모리 영역에 새로운 문자열을 생성하여 전달

- 적당한 메모리 영역에 패치하고자 하는 긴 문자열을 적어 놓고 printf 함수에게 그 주소를 파라미터로 넘겨 준다.


- Hello World!가 저장된 주소 '012A573C' 에서 조금만 내리다 보면 NULL로 덮여 진 부분이 나타난다.

- 이부분은 프로그램에서 사용하지 않는 NULL padding 영역이라고 한다.

- 프로그램이 메모리에 로딩될 때 최소 기본 단위(보통 1000)가 있다. 이 때문에 100의 크기만큼 메모리를 사용한다고 하면 나머지 900 크기는 NULL로 채워진다.


- 해당 부분에 문자열을 입력한다.


- printf 함수에서 Hello World가 있는 주소를 참조하는 부분에서 코드를 수정[space]를 통해 임의로 작성한 문구가 있는 주소로 바꿔준다.



- 잘 실행되는 것을 확인 할 수 있다.

- 하지만 수정된 코드로 파일을 저장후 실행한다면 제대로 동작하지 않을 수 있다.

- 파일이 그대로 메모리로 로딩되는 것이아니라 특정한 규칙에 의해서 올라가기 때문에 파일에 해당 offset이 존재하지 않을 수 있기 때문이다.

'SECURITY > 리버싱(역공학)' 카테고리의 다른 글

리버싱 4장  (0) 2015.08.20
리버싱 3장  (0) 2015.08.20
리버싱 1장  (0) 2015.08.19
Posted by OnewayK
,

1. 리버스 엔지니어링(Reverse Engineering, RE: 역공학)

- 물건이나 기계장치 혹은 시스템 등의 구조, 기능, 동작 등을 분석하여 원리를 이해하며, 단점을 보완하고 새로운 아이디어를 추가하는 작업


2. 리버스 코드 엔지니어링(Reverse Code Engineering, RCE)

- 소프트웨어 분야의 리버스 엔지니어링

- 아직 정확한 용어의 통일이 되지 않아 RCE, RE, 역공학, 리버싱 등의 용어를 섞어 사용


3. 리버싱(분석) 방법

3-1. 정적분석

- 겉모습을 관찰하는 방법

- 파일을 실행하지 않음

- 파일의 종류, 크기, 헤더(PE)정보, Import/Export API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털 인증서 등의 다양한 내용 확인

- 디스어셈블러(Disassembler)를 이용해서 내부 코드와 그 구조를 확인

- 동적 분석 방법에 좋은 참고 자료로 활용


3-2. 동적분석

- 파일을 직접 실행

- 디버깅을 통하여 코드 흐름과 메모리 상태 등을 자세히 살펴보는 방법

- 파일, 레지스트리(Registry), 네트워크 등을 관찰하면서 프로그램의 행위를 분석

- 디버거(Debugger)를 이용하여 프로그램 내부 구조와 동작 원리를 분석


4. 패치와 크랙

- 패치 : 프로그램의 파일 혹은 실행 중인 프로세스 메모리의 내용을 변경하는 작업

- 크랙 : 패치와 같은 개념이지만 특별히 그 의도가 비 합법적이고, 비도덕적인 경우

'SECURITY > 리버싱(역공학)' 카테고리의 다른 글

리버싱 4장  (0) 2015.08.20
리버싱 3장  (0) 2015.08.20
리버싱 2장  (0) 2015.08.19
Posted by OnewayK
,