사용자 액세스 로깅 (UAL)¶
UAL이란¶
사용자 액세스 로깅(UAL)은 Windows Server 2012부터 기본적으로 설치되고 활성화되어 있는 Windows Server 기능으로, 클라이언트가 서버의 역할에 보낸 요청을 집계하여 ESE 데이터베이스에 저장합니다. 역할, 클라이언트 주소, 계정의 조합마다 해당 연도에 클라이언트가 처음과 마지막으로 확인된 시각, 총 요청 수, 연중 각 날짜의 요청 수를 보관합니다. 역할에는 File Server(SMB), Active Directory Domain Services, Active Directory Certificate Services, DHCP Server, Print and Document Services, Remote Access, Web Server(IIS), Windows Server Update Services가 있습니다.
UAL은 측면 이동 조사에 유용합니다. 클라이언트 행은 어떤 주소와 계정이 어느 날에 서버를 사용했는지를 보여 주며, 이벤트 로그가 순환되어 사라진 뒤에도 오랫동안 남아 있는 경우가 많습니다.
가장 타당한 결론: 기록된 주소의 클라이언트가 기록된 계정으로 인증하여, 요청 수가 기록된 각 날짜에 해당 역할을 사용했습니다.
위치와 수집¶
C:\Windows\System32\LogFiles\Sum\Current.mdb
C:\Windows\System32\LogFiles\Sum\{GUID}.mdb (one per year)
C:\Windows\System32\LogFiles\Sum\SystemIdentity.mdb
C:\Windows\System32\LogFiles\Sum\Svc*.log, Svc.chk (transaction logs)
Current.mdb에는 가장 최근의 활동이 들어 있습니다. SystemIdentity.mdb는 서버를 설명하고, 역할의 이름을
정의하며, 각 연도의 데이터를 담은 {GUID}.mdb 파일을 나열합니다(CHAINED_DATABASES). UAL 서비스는
데이터베이스를 계속 열어 두므로, 포렌식 수집 도구를 사용하거나 볼륨 스냅샷에서 Sum 디렉터리 전체를
수집하십시오.
더티 데이터베이스
실행 중인 서버에서 수집한 Current.mdb는 더티 상태인 경우가 많습니다. Juntei는 이를 수집된 그대로
읽고 그 상태를 보고하지만, Svc*.log를 재생하지는 않습니다. 트랜잭션 로그에만 존재하는 활동은
누락됩니다.
분석 시 주의 사항¶
- UAL은 요청을 날짜별로 집계할 뿐, 각 요청을 개별적으로 기록하지 않습니다. 클라이언트 행에 있는 시각은
InsertDate와LastAccess뿐입니다. DailyAccesses의 날짜는 UTC 기준 날짜입니다.Address는 서버가 본 주소입니다. 서버와 실제 클라이언트 사이에 NAT 게이트웨이, 프록시 또는 VPN이 있을 수 있습니다.::1과127.0.0.1은 서버 자신입니다.Sum디렉터리의 모든 데이터베이스를 파싱하십시오. 같은 클라이언트가Current.mdb와 해당 연도의{GUID}.mdb양쪽에 행을 가질 수 있습니다.- 행이 없다고 해서 아무것도 연결하지 않았다는 증명이 되지는 않습니다. UAL은 비활성화할 수 있으며
(
Disable-Ual또는 User Access Logging Service 중지), 더티 데이터베이스에는 최신 변경 사항이 빠져 있습니다. SystemIdentity.mdb가 없으면RoleName에는 Windows Server가 역할에 부여한 이름이 사용됩니다.LastAccess가 0이거나 유효하지 않으면 연도를 판단하는 데 사용하지 않습니다. Juntei는 유효한InsertDate, 그다음 연간 데이터베이스의 메타데이터를 사용하며, 유효한 연도가 없으면DayOfYear를 유지합니다.- 요약 합계는 모든 원본 행을 합산합니다.
Current.mdb, 연간 데이터베이스 및 스냅샷이 겹칠 수 있으므로 중복을 제거한 연결 또는 로그온 횟수로 해석하면 안 됩니다.
Juntei로 파싱하기¶
Usage: juntei parse-ese ual <INPUT> [OPTIONS]
Input:
-d, --directory <DIR> Recursively find Current.mdb, {GUID}.mdb and SystemIdentity.mdb
-f, --file <FILE> Parse one UAL database
Output:
-o, --output <PATH> Directory of CSV tables, or JSON/JSONL file
-t, --output-type <TYPE> csv, json, or jsonl
juntei parse-ese ual -d Sum -o ual-csv
juntei parse-ese ual -d Sum -t jsonl \
| jq 'select(.Table == "CLIENTS") | {Address, AuthenticatedUserName, RoleName, LastAccess}'
출력 테이블¶
CSV는 테이블마다 하나의 파일을 생성하며, 테이블이 비어 있으면 헤더만 있는 파일이 됩니다. JSON 및 JSONL 행에는
SourceFile(데이터베이스)와 Table(데이터베이스 내 테이블 이름)이 포함됩니다.
| CSV 파일 | 테이블 | 내용 |
|---|---|---|
UAL-Clients.csv |
CLIENTS |
각 역할의 클라이언트: 주소, 계정, 해당 연도의 첫 액세스와 마지막 액세스, 총 요청 수와 일별 요청 수. |
UAL-RoleAccess.csv |
ROLE_ACCESS |
각 역할이 처음과 마지막으로 사용된 시각. |
UAL-DNS.csv |
DNS |
주소와 호스트 이름의 쌍, 그리고 각 쌍이 마지막으로 확인된 시각. |
UAL-VirtualMachines.csv |
VIRTUALMACHINES |
Hyper-V 가상 머신: 식별자, 일련 번호, 생성 시각과 마지막 활성 시각. |
UAL-SystemIdentity.csv |
SYSTEM_IDENTITY |
서버 자체: 이름, 도메인, Windows 버전, 제품 유형, 하드웨어, 표준 시간대, 마지막 부팅. 새 행은 이름 변경, 도메인 가입 또는 도메인 컨트롤러로의 승격을 나타낼 수 있습니다. |
UAL-ChainedDatabases.csv |
CHAINED_DATABASES |
각 연도의 {GUID}.mdb 파일. |
UAL-Roles.csv |
ROLE_IDS |
역할 GUID와 그 이름. |
UAL-<table>.csv |
기타 테이블 | Juntei가 알지 못하는 테이블의 모든 열. |
필드¶
| 필드 | 해석 |
|---|---|
SourceFile |
행을 읽어 온 데이터베이스. |
RoleGUID, RoleName |
역할과, 데이터베이스 옆에 있는 SystemIdentity.mdb에서 가져온 그 이름(해당 파일이 없으면 기본 제공 이름). |
TenantID |
역할이 보고하는 경우, 클라이언트가 속한 테넌트의 GUID. |
TotalAccesses |
데이터베이스 연도 동안 클라이언트가 보낸 요청 수. DailyAccesses의 합계입니다. |
InsertDate |
행이 생성된 시각. 즉, 이 데이터베이스에서 해당 연도에 클라이언트가 보낸 첫 요청입니다(UTC). |
LastAccess |
클라이언트의 가장 최근 요청(UTC). |
Address |
클라이언트의 IPv4 또는 IPv6 주소. |
AuthenticatedUserName |
클라이언트가 인증에 사용한 계정(DOMAIN\user. 컴퓨터 계정은 $로 끝남). |
ClientName |
역할이 보고하는 경우, 클라이언트의 이름. |
DailyAccesses |
요청이 있었던 날짜와 그 요청 수. Day1 … Day366 열에서 가져와 LastAccess의 연도로 날짜를 지정합니다. CSV에서는 2023-01-12: 5, 2023-01-13: 2, JSON에서는 Date와 Accesses를 가진 객체입니다. 연도를 알 수 없는 날짜에는 Date 대신 DayOfYear가 있습니다. |
FirstSeen, LastSeen |
역할의 첫 사용과 마지막 사용(ROLE_ACCESS), DNS 쌍이 마지막으로 확인된 시각(DNS). 모두 UTC입니다. |
CreationTime, LastSeenActive |
가상 머신 또는 SYSTEM_IDENTITY 행이 생성된 시각과, 가상 머신이 마지막으로 활성 상태였던 시각(UTC). |
OS-ProductType, OS-ProductTypeName |
1 Workstation, 2 Domain Controller, 3 Server. |
OS-CurrentTimeZone |
UTC를 기준으로 한 서버의 오프셋(분 단위, -420은 UTC-07:00). |
OS-LastBootUpTime |
서버의 마지막 부팅 시각(UTC). 읽을 수 없으면 저장된 WMI 텍스트 그대로입니다. |
| 기타 열 | 테이블의 그 밖의 모든 열을 Juntei의 PascalCase 필드 레이블로 출력합니다. 예: SystemDNS-HostName, SystemDomainName, OS-BuildNumber, SystemSerialNumber. |
자동 분석¶
auto-parse는 테이블을 LateralMovement에 UAL-Clients.csv, UAL-RoleAccess.csv 등으로 기록하며(-t json
또는 -t jsonl을 사용하면 하나의 UAL.json 또는 UAL.jsonl 파일), LateralMovement/UAL-logs.txt도 함께
생성합니다. 결합된 -j 타임라인에는 모든 행이 Comp와 Artifact 식별자 ual과 함께 포함됩니다. -Z는
InsertDate, LastAccess, FirstSeen, LastSeen, CreationTime, LastSeenActive, OS-LastBootUpTime을
변환합니다.