본문 바로가기
SeSAC/어플리케이션 보안 & 취약점 진단

[SeSAC 성동캠퍼스 1기] 어플리케이션 보안 & 취약점 진단 4일차

by zivvon 2023. 11. 16.
목차 접기

어플리케이션 보안 & 취약점 진단

💡오늘의 실습!

파이썬으로 NTFS, FAT32 파일 시스템 구조를 분석하는 코드를 짜보자!

 

FAT32 파일 속성
파이썬 실행 결과 화면

 

 

✏️ 파이썬으로 FAT32 파일 시스템 구조 분석 코드를 짜려면 우선! 당연하게도 FAT32 파일 시스템 이해가 먼저다

+ HxD에서도 잘 볼 수 있는 연습을 하자! 

- FAT32 파일 시스템 구조

 

✍️ VBR 분석에 필요한 정보만 확인해보기! ⭐

내용 의미
Jump Boot Code(3Byte) 부트 코드로 점프하기 위한 명령어
OEM ID(8Byte) 운영체제 버전별 ID
Byte Per Cluster(2Byte) 섹터 당 바이트 수 (00 02 = 512Byte)
Sector Per Cluster(1Byte) 클러스터 당 섹터 수 (08 = 4096Byte = 4KB = 512*8)
Reserved Sec Count(2Byte) 예약된 영역 섹터의 수
Num of FAT Tables(1Byte) FAT 테이블의 수
Media Type(1Byte) fixed disk
Total Sector32 (4Byte) 4Byte 크기의 파티션 총 섹터 수
FAT 32 Size(4Byte) FAT 하나의 영역이 가지는 4Byte 크기의 섹터 수
File System Version(2Byte)  파일시스템의 주버전과 하위버전
Root Directory Cluster(4Byte) root 디렉토리가 위치한 클러스터 값
(FAT32의 경우 정해져 있지 않지만 보통 클러스터 2번 사용)
File System Information(2Byte) FSINFO 구조체가 저장된 섹터 번호 (보통은 0x01)
Backup Boot Recprd(2Byte) 백업된 부트 섹터의 위치 (보통은 0x06)
File System Type(8Byte) 해당 파일 시스템의 타입을 나타냄

 

 

FAT32 파일시스템

FAT32 파일시스템에 대해 알아보겠습니다.FAT(File Allocation Table)는 MS-DOS시절부터 사용되었으며 간단한 구조로 메모리카드, 디지털카메라, 플래시 메모리 등에 많이 사용합니다. FAT12 ,16, 32에서 뒤에

gsk121.tistory.com

참고 블로그

 

✏️ 이번 실습에서 중요한 것 ⭐

1. MFT 파일 위치 구하기

MFT = VBR + RS + FAT + FAT(미러)

 

2. MFT 파일 분석하는 법 알기!

FAT 파일 시스템의 데이터 영역 구조

 

+ 오늘 얻은 파이썬 코드!

int.from_bytes( bytes, byteorder, *, signed=False )

 

 

Convert bytes to int?

I'm currently working on an encryption/decryption program and I need to be able to convert bytes to an integer. I know that: bytes([3]) = b'\x03' Yet I cannot find out how to do the inverse. What...

stackoverflow.com

바이트 타입의 값을 엄청 쉽게 10진수로 변환할 수 있다! 게다가 엔디안 설정도 가능 :) bb


 

[ API Hooking ]

API(Applicaton Programming Interface)

: 응용 프로그램의 기능을 제어할 수 있도록 제공되는 인터페이스로, 함수가 어떻게 구현되어 있는지 모르더라도 함수의 사용법만 알면 API를 통해서 원하는 결과 얻을 수 있음

 

- 사용자가 제작한 App이 H/W에 바로 접근 불가

- 운영체제를 거쳐 H/W에 접근 가능

= API 함수 없이는 의미 있는 프로그램을 만들 수 없음!

- 운영체제에서 동작하는 프로그램을 쉽게 만들 수 있도록 운영체제가 제공하는 함수의 집합체

 

▶ API 후킹(API Hooking)

: WIn32 API가 호출을 중간에서 가로채서 제어권을 얻어내는 것

ㄴ API에 넘어온 파라미터 혹은 리턴 값 조작

ㄴ API 호출 자체를 취소시키거나 사용자 코드로 실행 흐름 변

 

- 리버싱의 꽃

- 정보 가로채기, 실행 흐름 변경, 원래의 다른 기능 제공

- 보안 솔루션 : APT 대응 솔루션, 쿠쿠 샌드박스, 많은 보안 솔루션

- 악성 코드 : 게임 핵, 은헹 계좌, 탈취

- Fuzzer

- Frida

 

 

CreateProcess() 함수 ⭐

: 윈도우는 프로세스 생성을 돕기 위해 CreateProcess() 함수를 제공, 이 함수를 호출하는 프로세스를 가리켜 부모 프로세스라고 하고 함수 호출에 의해 생성된 프로세스를 가리켜 자식 프로세스라 함

1. lpApplicationName : 생성할 프로세스의 실행파일 이름을 인자로 전달, 경로명을 추가로 지정할 수 있으며, 경로명을 지정하지 않을 경우 프로그램의 현재 디렉터리에서 실행파일을 찾게됨

2. lpCommandLine : 생성하는 프로세스에 인자를 전달할 때 사용됨. 첫 번째 매개변수에 NULL을 전달한 경우, 실행파일의 이름을 같이 전달할 수도 있음. 이런 경우 실행파일의 이름은 표준 검색경로를 기준으로 찾게됨. 내부적으로 문자열에 변경을 가하기 때문에 전달인자의 문자열은 변수 형태여야함.

3. lpProcessAttributes : 프로세스의 보안 속성을 지정할 때 사용함. NULL을 전달할 경우 기본 보안 속성이 적용

4. lpThreadAttributes : 스레드의 보안 속성으로 NULL인 경우 기본 보안 속성

5. bInheritHandles : 전달 인자가 TRUE인 경우 생성되는 자식 프로세스는 부모 프로세스가 소유한 핸들 중 일부(상속가능한 핸들)를 상속

6.dwCreationFlags : 생성하는 프로세스의 특성(우선 순위)를 결정지을 때 사용되는 옵션, 특별히 설정할 필요가 없을 경우 0을 전달

7. lpEnvironment : 프로세스마다 Environment Block(환경블록)이라는 메모리 블록을 관리, 이 블록을 통해서 프로세스가 실행에 필요로 하는 문자열을 저장, 이 전달 인자를 통해서 생성하는 프로세스의 Environment Block을 지정, NULL이 전달되면 자식 프로세스는 부모 프로세스의 환경 블록에 저장되어 있는 문자열을 복사하게됨

8. lpCurrentDirectory : 생성하는 프로세스의 현재 디렉터리를 설정하는 인자, 전달인자는 디렉터리 정보를 포함하는 완전 경로 형태로 구성되어야 하며 NULL이 전달될 경우 부모 프로세스의 현재 디렉터리가 새로 생성하는 자식 프로세스의 현재 디렉터리가 됨. 역시 NULL이 일반적으로 전달됨

9. lpStartupInfo : STARTUPINFO 구조체 변수를 초기화한 다음 이 변수의 포인터를 인자로 전달, STARTUPINFO 구조체 변수는 생성하는 프로세스의 속성을 지정할 때 사용됨

10. lpProcessInformation : 생성하는 프로세스 정보를 얻기 위해 사용되는 인자, PROCESS_INFORMATION 구조체 변수의 주소값을 진자로 전달하면 전달된 주소값이 가리키는 변수에 프로세스 정보가 채워짐
 

CreateProcess 함수란 무엇인가?

BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _

cinrueom.tistory.com

참고 블로그

 

 

CreateProcessA function (processthreadsapi.h) - Win32 apps

Creates a new process and its primary thread. The new process runs in the security context of the calling process. (ANSI)

learn.microsoft.com


 

💡오늘의 실습!

Window API Hooking! feat.CreateProcess() 함수

 

📁 hook_createprocess.js

var hook_createprocess = Module.getExportByName(
  "Kernel32.dll",
  "CreateProcessW"
); // 해당 함수의 주소를 리턴함

Interceptor.attach(hook_createprocess, {
  onEnter(args) {
    var lpApplicationName = args[0];
    console.log(lpApplicationName);
  },
  onLeave(result) {},
});

결과 화면

 

📁 hook_createprocess.js  (풀 경로의 인자값까지 출력하기)

var hook_createprocess = Module.getExportByName(
  "Kernel32.dll",
  "CreateProcessW"
); // 해당 함수의 주소를 리턴함

Interceptor.attach(hook_createprocess, {
  onEnter(args) {
    var lpApplicationName = args[0];
    console.log(Memory.readUtf16String(lpApplicationName));

    var lpCommandLine = args[1];
    console.log(Memory.readUtf16String(lpCommandLine)); // 인자값까지 출력됨
  },
  onLeave(result) {
    console.log(result);
  },
});

결과 화면

 

 

CreateProcessA()와 CreateProcessW()의 차이

A) 아주 세세한 차이지만 결국 둘 다 CreateProcessInternal() 함수를 호출한다! 우선, 유니코드인 CreateProcessW() 함수를 호출하면 간단하게 CreateProcessInternalW()까지 호출되지만, 아스키 혀태인 CreateProcessA()를 호출하면 CreateProcessInternalA() 함수를 거쳐 CreateProcessInternalW()로 가게 됨.

 


 

오늘의 후기!

: 앞에 내용 간신히 이해했더니 API Hooking이 나타났다............................................ 힘내자