'Hacking/System'에 해당되는 글 4건

반응형

Section 02. 쉘코드 실전

* 하드코딩할 경우 

(1) Windows XP : 서비스팩과 언어만 동일하다면 값이 바뀌지 않으므로 가능

(2) Windows 7 : 부팅할 때마다 kernel32.dll의 상위 2바이트 주소값이 바뀌기 때문에 성공할 가능성 매우 희박

 => 프로세스 상에서 함수의 주소값을 동적으로 구해오는 Universal 쉘코드를 작성


1. Universal 쉘코드

 - 프로세스에서 함수의 주소값을 구하기 위해서는 dll의 시작 주소값dll 시작 주소부터 함수까지의 offset을 알아야 한다.

 - Universal 쉘코드의 목적 : 함수의 주소값을 실행 중에 스스로 구해 동적으로 입력


* 배경 지식들 - PEB, TEB, PE Header, Export Table, Export Name Table 등


1) TEB (Thread Environment Block)

 - TEB = 현재 실행되고 있는 쓰레드에 대한 정보를 담고 있는 구조체

 - 특수한 레지스터인 FS 레지스터에 TEB의 주소가 저장되어 있음 -> 프로세스 내부적으로 TEB에 접근하고자 할 때 FS 레지스터를 사용

 - PEB의 주소값을 정확히 알 수 있다. (TEB+0x30)


2) PEB (Process Environment Block)

 - PEB = 현재 실행 중인 프로세스에 대한 정보를 담아두는 구조체

 - 프로세스에 로드된 PE Image(EXE, DLL 등)들에 대한 정보들도 기록되어있음. -> 이를 이용

 - _PEB_LDR_DATA를 가리키는 포인터인 Ldr을 이용 (PEB+0xC)

 - InMemoryOrderModuleList (_PEB_LDR_DATA+0x14) = 프로세스의 PE Image들의 데이터가 저장된 LDR_DATA_TABLE_ENTRY 구조체의 더블링크드리스트 시작 주소가 저장

 - _LDR_DATA_TABLE_ENTRY 구조체 = 로드된 모듈에 대한 다양한 정보들을 저장, 모듈의 주소값인 DllBase가 저장되어 있음, 실행파일 그 자체에 대한 정보 (DllBase = 우리가 처음으로 필요로 한 dll의 시작 주소값)

 - InMomoryOrderLinks의 FLINK를 따라가면 첫 번째 로드된 라이브러리인 ntdll.dll 파일의 정보가 들어있는 LDR_DATA_TABLE_ENTRY 구조체를 만남

 - 한 번 더 FLINK를 따라가면 두 번째 로드된 라이브러리이며 우리가 원하는 kernel32.dll 파일의 정보가 들어있는 LDR_DATA_TABLE_ENTRY 구조체를 만남



* WinDBG = 윈도우 심볼 서버와 연동하여 다양한 심볼 정보를 쉽게 확인할 수 있다.

명령어 

설명 

사용 예시 

db 

byte 단위로 메모리를 표시 

>db [메모리주소]

>db 0x7ffd6000 

dd 

double word 단위로 메모리를 표시 

>dd [메모리주소]

>dd 0x7ffd6000 

dt 

type을 표시 (구조체 등)


type에 해당하는 실제 메모리값 확인 

>dt [구조체]

>dt _PEB


>dt [구조체] [메모리주소]

>dt _PEB 0x7ffd6000 


* <동적으로 모듈 주소 구하기> 실습 명령어 순서

1) !teb
2) dt _TEB [TEB주소]

3) dt _PEB [PEB주소]

4) dt _PEB_LDR_DATA [Ldr주소]

5) dt _LDR_DATA_TABLE_ENTRY [InMomoryOrderModuleList 의 FLINK값 -8]   = 로드된 파일 자기 자신 정보

6) dt _LDR_DATA_TABLE_ENTRY [InMomoryOrderLinks의 FLINK값 -8]            = ntdll.dll 정보

7) dt _LDR_DATA_TABLE_ENTRY [InMomoryOrderLinks의 FLINK값 -8]            = kernel.dll 정보


=> kernel32.dll의 DLLBase 값을 알 수 있다. 함수의 offset은 Windows 운영체제 버전과 서비스팩에 따라 달라질 수 있으므로 동적으로 구해보자!


3) IMAGE_EXPORT_DIRECTORY

 - DLL은 자신이 어떤 함수를 Export하고 있는지에 대한 정보를 PE헤더에 저장

 - 저장위치는 PE 헤더 IMAGE_OPTIONAL_HEADER32의 DataDirectory 배열의 첫 번째 구조체인 Export Directory

 - Export Directory는 IMAGE_EXPORT_DIRECTORY 구조체로 저장되어 있음.


* 가장 중요한 3개의 멤버

(1) AddressOfFunctions = 실제 함수의 시작 주소까지의 오프셋 배열을 가리킴(EAT)

(2) AddressOfNames = 함수 이름의 배열을 가리킴

(3) AddressOfNameOrdinals = 함수의 서수 배열을 가리킴


* 실제 함수의 주소값을 찾는 과정

1) 함수명 배열로 이동해서 원하는 함수의 이름과 해당 인덱스를 찾는다.

2) Ordinals 배열에서 인덱스에 해당하는 서수 인덱스 값을 찾는다.

3) EAT 배열에서 서수 인덱스에 해당하는 함수 offset을 확인한다.

4) DLL Base 주소와 offset을 더해서 함수의 실제 주소를 구한다.


* 주의사항 !

 - EAT, 함수명 배열 모두 직접 값이 들어있는 것이 아니라 RVA값(상대주소)의 배열이라는 것


* <동적으로 함수 주소 구하기> 실습 명령어 순서

1) !dlls     => 로드된 dll 목록 확인, base 주소 확인 가능

2) dt nt!_IMAGE_OPTIONAL_HEADER [dll base주소+0xf4+0x14] 

//Image_Optional_Header = Base + DOS_HEADER + IMAGE_FILE_HEADER

//IMAGE_OPTIONAL_HEADER 내용에서 IMAGE_DATA_DIRECTORY offset 확인

//nt!_의 의미는 NT 헤더에 있는 IMAGE_OPTIONAL_HEADER의 정보라는 의미

3) dd [IMAGE_OPTIONAL_HEADER 주소값 + 0x60]

  (IMAGE_OPTIONAL_HEADER 주소값 = Base + DOS_HEADER + IMAGE_FILE_HEADER + 0x60)

//IMAGE_EXPORT_DIRECTORY offset 확인

 = PEView로 c:\windows\system32\kernel32.dll 파일을 연 뒤 IMAGE_OPTIONAL_HEADER의 EXPORT Table 값과 동일

4) dd [dll base주소 + Export Table Offset]

 // IMAGE_EXPORT_DIRECTORY = BaseAddress + Export Table Offset]

 // 8번째 DWORD 부터 차례대로 함수주소배열, 함수명 배열, 서수배열의 주소값 확인 가능


* ActivateActCtx 함수의 주소를 구해보자!!

1) 함수명 배열에서 원하는 함수명의 인덱스 값을 찾는다.

 - EXPORT Name Table(ENT) = DLL Base + ENT Offset

 - 시작지점부터 4바이트마다 함수명의 offset이 저장 -> Base 주소에 각 offset 주소를 더해 확인 가능 ex) da 0x764f0000 + 0xb8c61



- IMAGE_EXPORT_DIRECTORY = BaseAddress + Export Table Offset

 - 노란색 형광펜은 순서대로 함수주소배열(EAT), 함수이름배열(ENT), 서수테이블(EOT)이다.

 - da 명령어 : 메모리를 ASCII 로 해석.

 - 3번째에 있는 함수명이 우리가 원하는 ActivateActCtx이므로 이에 해당하는 인덱스 값은 2이다. (인덱스는 0부터 시작)


2) 서수 테이블의 인덱스 2일 때의 값을 확인한다.

- 1)에서 찾는 인덱스로 바로 주소값을 확인하지 않고 서수 테이블을 거치는 이유는 함수명 테이블과 함수명 주소 테이블의 인덱스가 같지 않은 경우도 있기 때문


 - Export Ordinal Table(EOT) = DLL Base + EOT Offset

 - 바이트 단위로 저장되어 있으므로 db 명령어로 확인

 - 서수 테이블에서 인덱스 2일 때의 값은 4임을 확인


3) EAT에서 인덱스 4의 값을 확인

 - 인덱스 4의 값 = 5번째 주소 값(인덱스는 0부터 시작하므로) = 0x4556d



4) Base 주소에 함수의 offset을 더해서 최종 주소값을 구한다.

 - u 명령어 : 해당 주소 disassemble


반응형

'Hacking > System' 카테고리의 다른 글

PART3 쉘코드 원리와 작성  (0) 2016.12.21
16.12.19 공부일지  (0) 2016.12.20
16.12.17 공부  (0) 2016.12.18
블로그 이미지

rootable

,
반응형

Section 1. 쉘코드 작성 원리

* 쉘코드 : 공격이 성공한 후 실행을 시킬 실질적인 실행코드

 - Exploit을 총으로 비유한다면 쉘코드는 총알

 - 공격이 성공해서 쉘코드가 실행되는 도중 잘못된 쉘코드 때문에 중단되면 아무 소용이 없으므로 쉘코드는 신뢰성이 있어야 하고 범용적일수록 좋다.


1. 쉘코드 기본

* 명령을 실행하는 함수 : WinExec, ShellExecute, CreateProcess 등 존재

 - 인자값이 많을수록 쉘코드가 길어져서 활용성 측면에서 불리하므로 인자값수가 적은 WinExec가 좀 더 유리


* 인자값 2개를 역순으로 스택에 push한 뒤 함수 주소를 call 명령으로 호출


* 함수의 주소값은 DLL이 로드되는 주소에 따라 달라짐

 - Windows7에서는 재부팅될 때마다 kernel32.dll이 로드되는 주소가 바뀌므로 함수의 주소값도 바뀌게 됌


* 데이터 실행 방지

 - 스택, 힙 등의 메모리상에서 코드가 실행되는 것을 방지하는 것

 - 버퍼오버플로우 등을 통한 공격을 방어하기 위해 운영체제에 적용된 방어 매커니즘

- [프로젝트] > [속성] > [링커] > [고급] > [DEP(데이터 실행 방지)]


* 쉘코드 작성 방법

 1. 취약점을 공격하는 코드를 작성

 2. 디버깅 모드로 진입하여 디스어셈블리로 이동 후 코드 바이트 표시를 선택하여 바이트 코드를 추출

 3. 해당 바이트 코드를 이용하여 쉘 코드 작성


2. 널바이트 제거

 - 쉘 코드 내에 널바이트(\x00)이 들어있으면 문자열 복사 계열 함수에서 발생하는 취약점에는 사용할 수 없다.

 - C언어에서는 널바이트를 문자열의 마지막으로 인식하기 때문

 - 공격의 안전성을 위하여 널바이트를 제거하는 작업이 필수


(1) 레지스터나 메모리를 0으로 만든 후 해당 레지스터를 이용

 - xor를 이용하여 레지스터나 메모리를 0으로 만듦

 - 가장 쉬운 해결방법


ex)

mov     byte ptr [ebp-4], 63h            xor     ebx, ebx

mov     byte ptr [ebp-3], 6Dh    ->    mov    dword ptr [ebp-4], ebx

mov     byte ptr [ebp-2], 64h            mov    byte ptr [ebp-4], 63h

mov     byte ptr [ebp-1], 0                mov    byte ptr [ebp-3], 6Dh

      mov    byte ptr [ebp-2], 64h


(2) 널바이트가 들어가지 않는 명령어로 대체

 ex) mov    eax, 12h -> push 12h, pop eax


(3) 32비트 레지스터가 아닌 16비트, 8비트 레지스터 사용

 - 동일한 0x12라는 값을 표현할 때 32비트 레지스터는 0x00000012라고 표현되지만, 8비트로 표현하면 0x12


(4) add, sub 등의 연산 명령 사용

 ex) mov eax, 12h    ->    add eax, 12h

반응형

'Hacking > System' 카테고리의 다른 글

PART3 쉘코드 원리와 작성(2)  (1) 2016.12.27
16.12.19 공부일지  (0) 2016.12.20
16.12.17 공부  (0) 2016.12.18
블로그 이미지

rootable

,
반응형

1. 취약점이란?

 : 사용자에게 허용된 권한 이상의 동작이나 정보 열람을 가능하게 하는 소프트웨어 설계상의 허점이나 결함


* Exploit : 취약점을 공격하여 원하는 코드를 실행하거나 특정 목적을 달성하는 공격코드

 - 공격코드를 이용한 공격행위 일체를 포함하기도 함.


* 제로데이 공격 : 취약점이 발견되고 패치가 개발되기 전까지의 기간에 이루어지는 공격


* Bug Bounty Program

- 국내 : 인터네침해대응센터(http://www.krcert.or.kr)

- 해외 : Bugcrowd (https://bugcrowd.com/programs)
          Hackerone (https://hackerone.com/programs)


2. 취약점 분류

[1] Memory Corruption 취약점

 : 버그로 인한 메모리 오염, 즉 예상되지 않은 메모리 값 변경, 참조 등에 의해 발생

 : 주로 프로그래밍 실수로 인해 발생

 : 가장 잘 알려진 BufferOverflow 취약점이 해당 취약점에 속함.


1) Stack Buffer Overflow

 : 주로 메모리 경계를 검사하지 않는 함수 사용으로 인해 스택을 덮어쓰게 되어 발생

 : 대표적인 취약함수로 strcpy, gets, scanf, strcat, getwd, sprintf 등이 있다.


2) Heap Buffer Overflow

 : 스택 오버플로우와 비슷하나, 그 대상이 힙 메모리라는 점이 다르다.


3) Integer Overflow

 : 정해진 자료형보다 큰 수를 저장할 때 발생하는 오버플로우 문제

 : 조건문 등에서 정해진 분기문이 아닌 다른 분기문을 실행하도록 하여 취약점을 발생시킴.


4) Format String Bug

 : 포맷스트링을 지정해 주지 않고 사용할 때 발생하는 취약점

 : %n, %hn 등의 일부 포맷스트링을 이용하여 메모리 값을 변조


5) Use-After-Free

 : 최근 브라우저에서 많이 발견되는 취약점

 : Free된 포인터를 사용할 때 발생


6) Double Free

 : Free된 메모리를 다시 Free할 때 발생

 : 대부분 프로그래밍 실수로 발생, Integer Overflow 등의 취약점으로 인해 발생하기도 함


7) Null Pointer Dereperence

 : 메모리 값이 지정되지 않은 초기화되지 않은 포인터(Null Pointer)에 값을 넣으려할 때 발생



3. Exploit 분류

 [1] Local Exploit

 : PC 혹은 서버 내부에서 실행하는 Exploit

 : 일반적으로 권한상승 혹은 코드 실행을 위해서 사용

 : 인자값을 직접 입력해주거나 특정 파일을 통해 입력값을 전달해야하므로 로컬상의 권한을 이미 가지고 있거나, 파일 싱행 등의 조건이 필요하다.

 : 윈도우의 경우 주로 직접 인자값에 입력하는 방식의 공격보다는 악성파일을 이용한 공격이 주를 이룬다.

 : 사용자에게 입력값을 받는 모든 프로그램은 취약점이 존재할 수 있다는 것을 명심


* 쉘 코드 : 공격자가 실행하길 원하는 코드


 [2] Remote Exploit

 : Local Exploit과 반대로 원격에서 이루어지는 공격

 : 원격에서 패킷을 보내 공격하므로 특정 포트를 열고 서비스를 제공하는 서버 프로그램이 타겟


 [3] 침투 절차

 - Remote Exploit은 원격에서 직접 공격이 가능하므로 주로 서버에 접근 권한을 얻기 위한 1차 공격으로 많이 사용

 - Remote Exploit을 통해 서버의 일반 사용자 권한을 획득한 뒤, Local Exploit을 통해 추가 권한 상승을 시도하는 것이 일반적인 침투 절차



* Exploit 검색 사이트

 - http://www.exploit-db.com

 - http://packetstormsecurity.com

 - http://www.securityfocus.com

반응형

'Hacking > System' 카테고리의 다른 글

PART3 쉘코드 원리와 작성(2)  (1) 2016.12.27
PART3 쉘코드 원리와 작성  (0) 2016.12.21
16.12.17 공부  (0) 2016.12.18
블로그 이미지

rootable

,

16.12.17 공부

Hacking/System 2016. 12. 18. 00:44
반응형

1. PE파일

종류 

설명 

EXE 

실행 파일 

SCR 

실행 파일(화면보호기) 

DLL 

라이브러리 

OCX 

라이브러리(ActiveX) 

SYS 

시스템 드라이버 

OBJ 

오브젝트 파일 


- PE 파일은 파일에 존재할 때의 구조와 메모리에 로드된 후의 모습이 달라진다.

- 파일에서는 첫 바이트부터의 거리를 뜻하는 offset을 사용하고, 메모리에서는 VA(Virual Address, 가상주소)와 RVA(Relative Virtual Address, 상대적 가상주소)를 사용

- PE 파일이 메모리에 로드될 때 한 주소에 고정적으로 로딩되는 것이 아니기 때문에 상대주소 사용


* Alignment = 여러 내부 연산 등 처리상의 효율성을 위해 특정 단위로 간격을 맞춰주는 것

 - Section Alignment 값이 File Alignment 값보다 커서 메모리에 로드된 PE 파일의 사이즈가 파일 형태일 때보다 크다.

 - PE에서 남는 공간은 널바이트로 채워줌.



1) Image_DOS_Header와 DOS Stub

 = PE포맷의 시작 부분에 위치한 40바이트의 구조체

 = Windows가 아닌 DOS운영체제를 위한 것(DOS에서 PE파일이 실행되는 경우를 위해 만들어진 것)


* e_magic

 = PE파일임을 나타내주는 첫 2개의 바이트

 = MZ(5A4D)로 고정 (MZ가 아니면 PE파일로 인식 X)


* e_lfanew

 = NT Header가 시작되는 위치의 offset을 나타냄


* DOS Stub

 = DOS용 실행 코드 (DOS가 아니면 실행조차 되지 않음)


2) Image_NT_Headers

 = NT헤더임을 나타내는 시그니처인 "P E 0 0" 4바이트로 시작

 = FileHeader와 OptionalHeader를 멤버로 가지는 구조체


* FileHeader

 - Machine : 이 파일의 실행 대상 플랫폼(상수값으로 나타냄)

  ex) Intel386 = 0x014c // Intel64 = 0x0200 // ARM = 0x01c0

 - NumberOfSetions : 파일에 존재하는 섹션의 수(파일에 따라 섹션의 갯수는 달라질 수 있음)

 - SizeOfOptionalHeader : 바로 이어지는 Optional Header의 크기를 알려줌

 - Characteristics : PE 파일의 특성을 알려줌 -> 이를 통해 DLL인지, 실행파일인지 알 수 있음 (마지막 멤버, 최종 값은 해당되는 속성들의 OR 값으로 표시)

  ex) IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002 // IMAGE_FILE_32BIT_MACHINE = 0x0100 // IMAGE_FILE_DLL = 0x2000


* Image_Optional_Header

 - Magic : Image_Optional_Header32인지 64인지 구분 (32 = 0x10B / 64=0x20B)

 - Address of EntryPoint : 파일이 메모리에 매핑된 후 코드 시작 주소를 나타냄 (PE 로더는 ImageBase 값에 이 값을 더해 코드 시작 지점으로 설정)

 - SectionAlignment, FileAlignment : 각각 메모리와 파일 상태에서의 정렬값 (각 섹션은 반드시 Alignment의 배수여야 한다)

 - Subsystem : 동작환경 정의

  ex) 시스템 드라이버 파일인 sys = 0x1

       GUI프로그램 = 0x2

       CLI 프로그램 = 0x3

 - DataDirectory : NumberOfRvaAndSizes를 통해 디렉토리 수를 정해줄 수 있으나 일반적으로 정형화된 16개의 디렉토리를 가짐.


  • Export Directory : DLL 등의 파일에서 외부에 함수를 공개하기 위한 정보들을 가짐
  • Import Directory : 프로그램 실행을 위해 Import하는 DLL 이름과 사용할 함수정보가 담긴 INT(Import Name Table), IAT(Import Address Table)주소 등의 정보가 들어있음.
3) Section Header
 = 실제 파일의 내용들이 존재하는 부분
 = 각 섹션별로 섹션의 정보를 담고 있는 헤더를 가지고 있다.

* VirtualSize, VirtualAddress = 메모리상에서의 크기와 주소
* SizeOfRawData, PointerToRawData = 파일 상에서의 크기와 offset

* Characteristics = 각 섹션의 특징을 알려줌

 ex) IMAGE_SCN_CNT_CODE       = 0x00000020 // 섹션이 코드를 포함

      IMAGE_SCN_MEM_EXECUTE = 0x20000000 // 섹션 실행 권한 존재

      IMAGE_SCN_MEM_READ     = 0x40000000 // 섹션 읽기 권한 존재

      IMAGE_SCN_MEM_WRITE    = 0x80000000 // 섹션 쓰기 권한 존재

반응형

'Hacking > System' 카테고리의 다른 글

PART3 쉘코드 원리와 작성(2)  (1) 2016.12.27
PART3 쉘코드 원리와 작성  (0) 2016.12.21
16.12.19 공부일지  (0) 2016.12.20
블로그 이미지

rootable

,