18
시작! 리버싱 김 종범 2016 Kerference

[Kerference] 시작! 리버싱 - 김종범(KERT)

Embed Size (px)

Citation preview

Page 1: [Kerference] 시작! 리버싱 - 김종범(KERT)

시작! 리버싱

김 종범

2016 Kerference

Page 2: [Kerference] 시작! 리버싱 - 김종범(KERT)

차례

소개 쓰임새 어셈블리 시연 끄읕

Page 3: [Kerference] 시작! 리버싱 - 김종범(KERT)

소스코드를 역추적하는 것

개발자가코딩을완료하고빌드를하게되면소스코드를컴파일과정을거쳐오브젝트파일이만들어지며, 여러링크된라이브러리와오브젝트파일을결합해최종적으로 EXE DLL등이생성된다.

빌드된 EXE, DLL등을바이너리분석을거쳐서소스코드가어떤식으로만들어져있는지파악이가능해진다. PE Header 분석을통해어떤라이브러리가링크돼있는지분석하고, 버튼을눌렀을때가동되는코드의흐름을추적해원래의코드가어떤식으로제작돼있는지알수있게된다.

Page 4: [Kerference] 시작! 리버싱 - 김종범(KERT)

• 소스코드의구조를분석해서코드변조를통해허가되지않은액

션이가능한지등취약점발견모의해킹취약점발견

• 해커의침입여부를역분석해서그에상응하는보안모듈개발보안코드개발

• 코드상에선문제가없지만다른모듈이결합했을때등, 예상치못

한상황에서예외가발생했을때등에대해원인파악가능버그수정

• 새로운프로그램이등장했는데, 구글링해도나오지않을때, 리버

싱하면기술에대한궁금증을해결신기술연구와학습

Page 5: [Kerference] 시작! 리버싱 - 김종범(KERT)

어셈블리어(Assembly language)• 기본구조

• 명령포맷

• 레지스터

• 외울필요없는명령어

• 스택

• 함수의호출

• 리턴주소

Page 6: [Kerference] 시작! 리버싱 - 김종범(KERT)

Void 물마심()

{

BOOL bOpen = 냉장고문오픈();

if (bOpen)

{

물을꺼냄();

마심();

}

}

__asm{

냉장고앞으로간다

냉장고문을잡는다

냉장고문을연다

오픈성공:

냉장고안을본다

손을든다

냉장고안에넣는다

물병을잡는다

물병을꺼낸다

뚜껑을연다

물을컵에따른다

컵을손에든다

컵에든것을마신다.

C/C++ 코드와의결정적인차이

: “한번에한가지동작”

[어셈블리는간단명료하다]

기본구조(feat. 물마심)

Page 7: [Kerference] 시작! 리버싱 - 김종범(KERT)

명령포맷• X86 CPU의기본구조인 IA-32를기본플랫폼으로삼아소개함

대부분의 PC가 Intel CPU를사용하며, AMD의경우도대부분의코드가 Intel Processor와호환되기 때문이다.

• “명령어 + 인자”

IA-32의기본형태

명령어 mov, push 같은것들. 옵코드(opcode)

인자: “어떤장소로값을넣을것인지”, “명령어에해당하는값.” 오퍼랜드(operand)

• Push 337

Push는옵코드, 337는오퍼랜드

• Mov eax, 1

Mov는옵코드, eax와 1이오퍼랜드

모든오퍼랜드는앞의것이 destination 뒤의것이 source

Page 8: [Kerference] 시작! 리버싱 - 김종범(KERT)

레지스터

Page 9: [Kerference] 시작! 리버싱 - 김종범(KERT)

EAX

산술계산을하며, 리턴값을전달하는변수.

A = Accumulator

EDX

각종연산에쓰이나,

리턴값에쓰이지않는변수

D = Data

ECXC = Count

For 문에서 int I 라고선언할때의 i의역할

카운팅할필요없을때는그저변수.

EBX

레지스터가하나더

필요할때사용되는것.

Page 10: [Kerference] 시작! 리버싱 - 김종범(KERT)

• ESI (Source Index)

시작지인덱스

데이터를조작하거나, 복사시에데이터의주소가저장되는변수

• EDI (Destination Index)

목적지인덱스

복사시에목적지의주소가저장되는변수

• EBP(Stack Pointer)

스택프레임의끝지점주소가저장됨.

• ESP(Baste Pointer)

스택프레임의시작주소가저장됨.

Page 11: [Kerference] 시작! 리버싱 - 김종범(KERT)

기본적인명령어• ADD, SUB

ADD : Src에서 dest로값을더하는명령어

SUB : Src에서 dest로값을빼는명령어

• INT 인터럽트를일으키는명령어

• CALL 함수를호출하는명령어

CALL뒤에오퍼랜드로번지가붙는다. 해당번지를호출하고끝나면 call다음번지로돌아온다.

• INC, DEC INC = i++; DEC = i--;

• PUSH, POP PUSH : 스택에값을넣는명령어

POP : 스택에있는값을가져오는명령어

• MOV 값을넣는명령어

Mov eax, 1 : eax에 1을넣는코드

Mov ebx, ecx : ebx에 ecx를넣는코드

• LEA 주소를넣는것 Lea eax, dword ptr ds:[esi] : eax에 0x401000

Mov eax, dword ptr ds:[esi] : eax에 5640EC83

Lea eax, dword ptr ss:[esp+8] :eax에 0x13FF40

Mov eax, dword ptr ss:[esp+8] : eax에 33

Page 12: [Kerference] 시작! 리버싱 - 김종범(KERT)

기본적인명령어• AND, OR ,XOR

비트연산자

XOR는동일한오퍼랜드로처리가능

Ex : XOR EAX, EAX : EAX = 0

• NOP

아무것도하지말라는명령어

• CMP, JMP

비교해서점프하라는명령어

• 그외의명령어는구글링

Page 13: [Kerference] 시작! 리버싱 - 김종범(KERT)

스택(stack)• 지역변수사용

• 함수호출시파라미터가들어가는방향

• 리턴주소

Page 14: [Kerference] 시작! 리버싱 - 김종범(KERT)

지역변수사용Push ebp

Mov ebp, esp

Sub esp, 50h

• Ebp 레지스터를스택에넣는다.

• 그리고현재 esp의값을 ebp에넣는다.

• Ebp와 esp가같아지면서이제이함수에서지역변수는 ebp에서부터얼마든지계산할수있다.

• Ebp를기준으로오프셋을더하고빼는작업으로스택을처리할수있게된다.

• Sub esp, 50h LIFO특성으로인해특정값만큼뺀다는것은그만큼스택을사용하겠다는것이고, 즉 50h만큼지역변수를사용하는것이다.

Page 15: [Kerference] 시작! 리버싱 - 김종범(KERT)

함수의호출DWORD HelloFunction(DWORD dwParam1, DWORD dwParam2,DWORD dwParam3)

HelloFunctioni 호출

Main(){

DWORD dwRet = HelloFunction(0x37,0x38,0x39);

If(dwRet)

//….

}

Push 39h

Push38h

Push 37h

Call 401300h

• 스택에값을 LIFO 순으로넣기떄문에실제소스코드에서호출한것과는반대로들어간다.

Page 16: [Kerference] 시작! 리버싱 - 김종범(KERT)

리턴주소• DWORD HelloFunction(DWORD

dwParam1, DWORD dwParam2, DWORD dwParam3){

• DWROD dwRetAddr = 0;

• __asm

• {push eax

mov eax,[ebp+4]

mov dwRetAddr, eax

pop eax

}

Printf(“dwRetAddr: %08x\n”, dwRetAddr);

}

• 결과를보면 HelloFunction()을호출한뒤호출한쪽의다음번지가바로리턴주소다.

Page 17: [Kerference] 시작! 리버싱 - 김종범(KERT)

시연크랙미 1번 • 크랙미 5번

Page 18: [Kerference] 시작! 리버싱 - 김종범(KERT)

끄읕