Task 2. Windows Registry and Forensics
레지스트리:
windows 레지스트리 = key(폴더) + value(키에 저장된 데이터)
윈도우 시스템 레지스트리는 아래 5개 root key가 존재
- HKEY_CURRENT_USER : HKCU라고 함. 사용자의 폴더, 화면 색상, 제어판 설정 등…
- HKEY_USERS : HKU라고 함. 로드된 모든 사용자 프로필 정보, 위 current_user가 해당 키의 하위 키
- HKEY_LOCAL_MACHINE : HKLM이라 함. 컴퓨터 관련 구성 정보
- HKEY_CLASSES_ROOT : HKCR이라 함. HKEY_LOCAL_MACHINE\Software의 하위 키.
- HEKY_CURRENT_CONFIG : 시스템 시작 시 로컬 컴퓨터에서 사용되는 하드웨어 관련 정보

Task 3. Accessing registry hives offline
regedit.exe 말고 디스크에서 레지스트리에 접근하는 방법 -> C:\Windows\System32\Config
- DEFAULT -> HKEY_USERS\DEFAULT
- SAM -> HKEY_LOCAL_MACHINE\SAM
- SECURITY -> HKEY_LOCAL_MACHINE\Security
- SOFTWARE -> HKEY_LOCAL_MACHINE\Software
- SYSTEM -> HKEY_LOCAL_MACHINE\System
이외에 사용자 정보가 포함된 hive..
C:\Users<username>\ 에서
- AppData\Local\Microsoft\Windows로 가면, USRCLASS.DAT -> HKEY_CURRENT_USER\Software\CLASSES
- NTUSER.DAT -> HKEY_CURRENT_USER
C:\Windows\AppCompat\Programs\Amcache.hve : 최근에 실행된 프로그램 관한 정보

PE파일이란?
리눅스 실행파일이 ELF인 것처럼 윈도우에서 사용하는 실행파일입니다.
PE파일의 종류
EXE, DLL, OBJ 등 윈도우OS에서 돌아가는 실행파일들이 있습니다.
PE파일의 구조
PE 파일은 아래 그림처럼 구조체 형식으로 저장되어 있습니다. 크게는 PE header와 body가 존재합니다.

메모장을 PEview로 열면 구조화되어 있는 걸 알 수 있습니다.
1. DOS Header

IMAGE_DOS_HEADER 구조체
- e_magic: DOS signature이다. PE 파일이라는 걸 나타낸다. MZ로 총 2바이트. 위 메모장에서도 data가 5A4D로 고정됨을 알 수 있습니다.
- e_lfanew: NT header가 시작되는 위치 offset입니다.
2. DOS stub(옵션)

DOS환경에서 실행되는 코드+데이터가 적혀있습니다. 위를 DOS환경에서 실행하면 “This program cannot be run in DOS mode”를 출력하고 종료합니다.
3. NT Header

IMAGE_NT_HEADERS 구조체는 파일 실행에 필요한 정보를 저장합니다(중요).
- signature: data를 읽으면(참고로 리틀엔디안) 00004550인데 이것은 PE를 뜻합니다.
- file header: 파일의 간략 정보를 나타냅니다. IMAGE_FILE_HEADER 구조체를 갖습니다.
| 주요 멤버명 |
의미 |
notepad.exe |
| Machine |
실행되는 아키텍처 |
8664는 AMD64를 나타냅니다. |
| NumberOfSections |
파일에 존재하는 섹션 개수 |
7개입니다. |
| SizeOfOptionalHeader |
Optional Header의 크기 |
0x00F0만큼 차지 |
| Characteristics |
속성 |
bit OR계산을 해보면 0x0002 EXECUTABLE_IMAGE 0x0020 LARGE_ADDRESS_AWARE를 갖는 걸 알 수 있습니다. |
| TimeDateStamp |
파일의 생성 일시 |
value를 보면 2007/06/20에 생성된 걸 알 수 있습니다. |
- optional header: 파일 실행에 필요한 정보들을 저장합니다.

위 파일 헤더에 적혀있던 것처럼 0x00F0만큼 갖습니다.
| 주요 멤버명 |
의미 |
| Magic |
32비트 or 64비트 |
| AddressOfEntryPoint |
로더가 실행을 시작할 주소 처음으로 실행될 코드 주소 |
| ImageBase |
메모리 상의 시작 주소 |
| SectionAlignment, FileAlignment |
섹션의 최소단위 |
| SizeOfImage |
Image 전체 크기 |
| SizeOfHeader |
PE header의 전체 크기 |
| Subsystem |
동작환경 정의 |
| NumberOfRvaAndSize |
datadirectory배열의 개수 |
| DataDirectory |
IMAGE_DATA_DIRECTORY 구조체의 배열
디렉토리별 각각의 정보 작성 |
4. Section Header

아래서 설명할 Section에 대한 header입니다. 메모리에 로드될 때 참조됩니다. 섹션의 자세한 .text, .rdata, .data등은 후술하고 주요 멤버만 짚고 넘어갑니다.
- VirtualSize: 메모리에서 섹션 크기
- VirtualAddress: 메모리에서 섹션의 시작주소(RVA라고 합니다)
- SizeOfRawData: 파일에서 섹션의 크기
- PointerToRawData: 파일에서 섹션의 Offset(길이)
- Characteristics: 섹션의 속성(위에서 본 멤버와 같은 원리)
2. PE body
body는 여러 개의 섹션으로 구성되어 있습니다.
| code 영역 |
.text |
실행 코드를 담고 있는 섹션 |
| data 영역 |
.data |
읽고 쓰기가 가능한 데이터 섹션 초기화된 전역변수와 정적 변수 등 위치 |
| |
.rdata |
읽기만 가능한 데이터 섹션 상수형 변수, 문자열 상수 등 위치 |
| |
.bss |
초기화되지 않은 전역변수 위치 |
| import API |
.idata |
import할 DLL, API 정보 섹션 IAT 존재 |
| |
.didat |
Delay-loading import DLL 정보 섹션 |
| export API |
.edata |
export할 DLL 정보 섹션 |
| Resource |
.rsrc |
리소스 관련 데이터 정보 섹션 |
| relocation |
.reloc |
재배치 정보 섹션 |
| TLS |
.tls |
스레드 지역 저장소 |
| Debugging |
.debug$p |
미리 컴파일된 헤더가 있을 시 |
notepad.exe에는 위와 같은 섹션이 존재합니다. 중요한 code, data 영역 헤더를 살펴보겠습니다.

위는 .text의 섹션 헤더입니다. characteristics를 보면 실행, 읽기 권한이 있습니다.

왼쪽이 .data이고, 오른쪽이 .rdata입니다. 속성 차이를 보면 왼쪽은 읽기, 쓰기 권한이 있지만 오른쪽은 읽기 권한만 존재합니다. rdata에는 문자열 상수 등이 위치합니다.
가상 메모리 구조 분석
위 그림과 같이 메모리에 PE파일이 로드됩니다. 왼쪽 파일에서는 offset의 개념을 쓰지만 오른쪽 메모리에서는 RVA(relative virtual address)의 개념을 차용합니다. RVA는 시작 주소에 대한 상대적 VA를 말합니다. 이 RVA를 이용한 VA 식은 다음과 같습니다.
image_file_header 뒷부분 IMAGE_OPTIONAL_HEADER 구조체에 메모리 로드 관련 멤버들이 존재합니다. 아까 위에서 설명했던 optional header에서는 주요 멤버만 설명하고 넘어갔는데 좀 더 자세히 설명해보겠습니다.

| 주요 멤버명 |
의미 |
| Magic |
실행되는 아키텍처 |
| SizeOfCode |
.text의 크기 |
| AddressOfEntryPoint |
로더가 실행을 시작할 주소 처음으로 실행될 코드 주소 |
| ImageBase |
메모리 상의 시작 주소 |
| SectionAlignment, FileAlignment |
섹션의 최소단위 |
| SizeOfImage |
Image 전체 크기 -> 위 alignment의 배수 |
| SizeOfHeader |
PE header의 전체 크기 -> 위 alignment의 배수 |
| Subsystem |
동작환경 정의 |
| NumberOfRvaAndSize |
datadirectory배열의 개수 |
| stack, heap 사이즈 관련 멤버 |
프로세스마다 가지는 자신만의 스택, 힙 그것들을 생성하기 위한 크기, 속성 지정 |
| DataDirectory |
IMAGE_DATA_DIRECTORY 구조체의 배열
디렉토리별 각각의 정보 작성 |
각 섹션별 RVA와 size가 정의되어 있습니다.


처음에 version 10.0.14393 했는데 안됐다.

그냥 windows server 2016 입력하는 거였다.

레지스트리 탐색기로 가서 Windows\CurrentVersion\Authentication\LogonUI

LastLoggedOn~을 보면 Administrator임을 알 수 있다.

cmd에 위와 같이 입력하면 Last logon을 알 수 있다.

처음에 가상 머신을 켜면 connecting to…가 뜬다. 민첩하게 외워서 작성해준다.

컴퓨터 관리자 > Local Users and Groups > Groups
여기서 Administrators Properties를 누르면 세 명이 나온다.

schtasks를 입력했는데 너무 많아서 얻은 건 없었다.

task scheduler로 가서 예약된 task들을 하나씩 살펴본다. Clean file system은 사실 answer format 글자수 보고 찍었다…

앞문제를 풀었으면 해당 문제는 쉽다. action칸으로 가면 수상한 cmd 명령이 있는데 nc.ps1과 port 번호 입력해주면 된다.

Windows > System32 > drivers > etc에서 hosts를 열면 외부 ip하나가 google.com을 들어가고 있는 기록을 확인할 수 있다.

inbound 방화벽의 최근을 보면 1337 포트 기록이 있다.

inetpub > wwwroot로 가면 jsp파일들이 있는데 해당 파일이 서버 웹사이트서 업로드된 shell이다.
사이트에 있는 파일을 모두 FTK Imager에 담았을 때 SCHARDT.001과 4Dell Latitude Cpi.E01이 제대로 load되었다(?)
1. What is the image hash? does the acquisition and verification hash match?
상단 메뉴에서 file > Verify Drive/Image를 누른다. 왼쪽은 SCHARDT.001은 해쉬 매치가 안되었고 오른쪽 CPi.E01은 match라고 뜬다.
2. What operating system was used on the computer? Windows XP
CPi.E01의 properties를 보면 OS가 뜬다. Windows XP이다.
3. When was the install date? 2004-08-20
Windows\System32\config에서 파일을 export해준다(난 걍 모두 다 export했다). registry explorer에서 Software 파일을 불러와서 Microsoft\Windows NT\CurrentVersion을 들어가면 InstallDate가 뜬다.
4. What is the timezone settings? UTC -5
system 파일을 불러와서 select 안 current가 1이므로, ControlSet001을 들어간다. Control\TimeZoneInformation을 들어가면 다음과 같이 나온다. Bias : 360, DaylightBias : -60, ActiveTimeBias가 300. UTC -5이다.
5. who is the registered owner? Greg Schardt
software을 열어서 Microsoft\Windows NT\CurrentVersion를 보면 RegisteredOwner에 Greg Schardt라고 적혀있다.
6. what is the computer account name? N-1A9ODN6ZXK4LQ
System을 열어서 ControlSet001\Control\ComputerName\ComputerName을 확인한다.
7. what is the primary domain name? N-1A9ODN6ZXK4LQ
DefaultDomainName을 읽어준다.
8. when was the last recorded computer shutdown date/time? 2004-08-27 15:46:33
system을 열고 ControlSet001\Control\Windows를 누르면 shutdown time이 보이는 데 data값 우클릭 -> data interpreter를 누르면 Windows 파일time이 나온다.
9. how many accounts are recorded (total number)? 5
SAM\Domains\Account\Users를 가면 계정 목록이 보인다. 5개의 계정이 있다.
10. what is the account name of the user who mostly uses the computer? mr.evil
위 9번 문제에서 체크 옆옆 칸은 total login count를 뜻한다. mr. evil만 15번이다.
11. who was the last user to logon to her computer? Mr. Evil
software\Microsoft\Windows NT\CurrentVersion\Winlogon에 가서 DefaultUserName을 참조한다. 위 그림에서는 Mr. Evil이다.
ARM은 mobile/embedded 맞춤.. 초기 임베디드 시장은 32bit를 지원하는 ARM이 아닌 16bit가 대세라
ARM을 반쪽으로 만든 Thumb 존재..
| Thumb mode |
ARM mode |
레지스터 R0~r15 기계어 2bytes |
레지스터 R0~R7 기계어 4bytes
해당 모드 간 전환 자유로움 x로 끝나는 분기문 명령으로 전환 |
이걸 리버싱 할 때도 유념해야 하는듯
- 레지스터

범용
- r0~r3 : 인자, 반환값 저장 / return은 r0으로..
이 레지스터를 넘어가면 stack으로..
- r4~r11(r9 제외) : general purpose register
- r11 : base pointer (amd에서 rbp,ebp 역할)
- r13 : sp
- r14 : link register.
- link register: 함수 call 뒤에 return 될 위치 저장, ret 역할
- r15: pc, 실행되는 code 위치 저장
접은 글은 LR에 대하여..
스택에 RET 저장이 아니라 LR에 따로 레지스터에 주소를 남겨줘서 ARM bof는 경우가 좀 다른듯
- lr을 스택에 저장하거나
- 다른 함수 stack frame을 덮을 수 있거나
보통은 1 경우라고 함
상태, mode 전환 시 이용
fps
cpsr
- Passing Arguments via Registers

Procedure Call //arm에서는 subroutine을 procedure이라고 더 많이 부르나..
BL label ; LR = 이 다음 instruction addr
; PC = label
BX LR ; PC = LR
이참에 branch 정리하고 가자
- b: branch, 상대 주소 기반 점프
- bx: branch and exchange, 레지스터 기반 절대주소
- bl: branch with link, 주소 점프(오프셋) + lr에 RET 저장
- blx: branch with link and exchange, 레지스터 점프 + lr에 RET 저장
하위 두 개가 RET 저장되니까 call에 많이 불리지 않을까….
위 접은글 보면 bl을 통해 LR 설정..
컴파일러는 label을 memory address로 translate..
BL은 caller, callee에서 BX
인자는 callee에서 깔아주는듯

R0부터 first argument 넣음
return은 r0으로 넣고 bx..
stack에 넣을 때는.. [sp,#0] 이런 식으로 넣는듯
ARM 명령은 conditional execution..
해당 conditional execution은 CPSR state에 따라 instruction 실행하는 것을 말함
위 예시처럼 add 뒤에 EQ가 붙었다. 이 명령은 CPSR 30번째 비트 Z를 확인하고 이값이 1인 경우만 실행한다고 한다.
//CPSR 레지스터를 더 자세히.. 파야 할듯
CPSR(Current Program Status Register)

여기에는 ALU status flags 있음 -> instruction 결과에 따라 update
맨 앞 N,Z,C,V를 condition code flag라고 함..
- N: 음수
- Z: 0
- C: arry 올림
- V: oVerflowed
이부분의 값을 참조하여 조건부 명령 가능 (if문처럼..)
| Code |
Suffix |
Description |
Flags tested |
| 0000 |
EQ |
Equal |
Z=1 |
| 0001 |
NE |
Not Equal |
Z=0 |
| 0010 |
CS |
Unsigned higher or same |
C=1 |
| 0011 |
CC |
Unsigned lower |
C=0 |
| 0100 |
MI |
Minus (negative) |
N=1 |
| 0101 |
PL |
Positive or Zero |
N=0 |
| 0110 |
VS |
Overflow |
V=1 |
| 0111 |
VC |
No overflow |
V=0 |
| 1000 |
HI |
Unsigned higher |
C=1 & Z=0 |
| 1001 |
LS |
Unsigned lower or same |
C=0 or Z=1 |
| 1010 |
GE |
Greater or Equal |
N=V |
| 1011 |
LT |
Less than |
N!=V |
| 1100 |
GT |
Greater than |
Z=0 & N=V |
| 1101 |
LE |
Less than or equal |
Z=1 or N=!V |
| 1110 |
AL |
Always |
|
LDR/STR
메모리 참조 가능한 명령어
- LDR/STR with offsets
- LDR with labels