콤푸타/해킹&보안

[windows] 윈도우 로컬 환경 로그온 과정 상세 분석

어둠의다크 2024. 12. 6. 13:14

 예전에 리눅스 데스크탑 환경 관련 글을 포스팅한적이 있다. 해당 포스팅에서 GUI의 각 구성요소별 기능을 소개했다. 당연하지만 윈도우에서도 사용자 인증을 위한 절차가 존재한다. 간단하게 생각해보면, 가장 먼저 로그인 화면이 존재하고 비밀번호를 입력해 인증이 성공하면 explorer가 실제 GUI 사용자 환경을 로드한다. 이 과정에서 사용자 인증정보는 어떻게 처리되고 어디에 기록되는 걸까? 하는 당연한 의문이 생긴다. 그래서 한번 추적하고 정리해보았다.

 

1. 로컬 환경에서 사용자 인증 절차

 위에서 설명한 절차들은 실제로 아래 이미지와 같은 절차를 거친다.

먼저 로그인화면에서 인증 절차를 거친 후 사용자 계정으로 확인되면 권한이 부여된 토큰을 발행하고 사용자별 환경설정을 로드한다.

그럼 이 때 사용자 인증정보는 어디에 저장되어 이런 인증 절차를 확인하는 걸까?

 

2. SAM Registry Hive

 레지스트리는 윈도우 운영체제 구동을 위한 설정 값들이 저장되어있는 일종의 데이터베이스다. regedit 를 열어서 볼수도 있지만 다른 도구를 사용하거나 raw data를 직접 읽어볼 수도 있다. 또한 우리가 읽을 수 있다는 의미는 이 데이터들이 '파일'의 형태로 저장되어 있다는 의미와도 같다.

HKEY_LOCAL_MACHINE 하위 하이브들이 존재하는 경로는 C:/windows/system32/config 경로다. 아래 사진처럼 직접 레지스트리를 찾아볼 수 있다.

레지스트리 편집기
파일 탐색기!

 위에서도 볼 수 있지만 SAM 과 같은 일부 레지스트리 하이브는 일반 사용자나 관리자 권한으로는 내부 데이터들을 읽을 수 없으며 'system' 권한이 필요하다. 이 권한에 대한 이야기는 필자가 다른 글에서 소개한 바 있다. 이는 이러한 중요한 자원에 접근할 수 있는 권한을 제한해 보안을 강화하려는 마이크로 소프트의 의도라고 생각된다.

 아무튼 사용자의 인증정보 계정명, SID, RID, NTLM 해시, 그외 등등 정보들이 모두 이 SAM 에 기록된다. 즉 이 데이터를 까볼 수 있다면 우리는 사용자 인증에 대한 정보들을 알 수 있다는 의미가 된다. 그럼 어떻게 이걸 까볼수있을까?

 

3. 사용자 인증 절차 로직

 로컬사용자 환경과 AD(Active Directory)환경에는 큰 차이점이 존재한다. 이 글에서는 로컬 사용자 환경에 대해서만 다루겠다.

우선 전체 러프한 흐름은 다음과 같다.

NTLM 해시 복호화 흐름도

 예전 버전에서는 NTLM 해시가 한 번 암호화 되어 기록된다 본 적이 있는데, 현재 윈도우 11 23H2 22631.4602 에서는 무려 2번 암호화가 되어 SAM 레지스트리에 기록된다. 그래서 우리는 두 번의 복호화 과정을 거쳐야 하고, 이 복호화 과정을 거치지 위해 system registry hive에서 bootkey 를 추출해야한다.

3-1. BootKey 획득(Syskey)

 위 그림에서 BootKey 획득 단계에 보이는 JD, Skew1, GBG, Data 키는 system registry hive 내부에 존재하는 키로 상위 키의 경로는 HKLM\SYSTEM\CurrentControlSet\Control\Lsa 이다.

해당 네 개 키를 확인할 수 있다. 그리고 네 개 키에 존재하는 값이 아니라 classname 을 확인해야 한다.

레지스트리 구성을 간단하게 설명해보자면 다음과 같다.

  1.  root key에서부터 시작되어 모든 키는 하위 키를 가질 수 있다.
  2. 키에는 이름 : 데이터 쌍을 가진 여러 데이터가 존재할 수 있다.
  3. 키는 class name이라는 별도의 별명(alias)을 가질 수 있다.

그리고 이 class name은 레지스트리 편집기와 같은 도구에서는 확인할 수 없고, 레지스트리 하이프 파일을 수동으로 파싱하거나, 또는 파싱해주는 도구를 사용해야 볼 수 있다.

이 네개 레지스트리 키의 class name을 추출한 후 연접하면 16byte 의 결과를 얻을 수 있다. 다만 이는 scramble 된 결과이다. 즉 우리는 이 값을 scramble 되기 전의 상태로 되돌려야 한다. 즉 아래 리스트에 적힌 순서대로 이 boot key를 재배열 해주면 된다.

BOOTKEY_PBOX = [
    0x8, 0x5, 0x4, 0x2,
    0xB, 0x9, 0xD, 0x3,
    0x0, 0x6, 0x1, 0xC,
    0xE, 0xA, 0xF, 0x7
]

자 이과정을 거치고나면 여러분들은 진짜 bootkey를 얻어냈다. 단, NTLM 해시를 복호화 하기 위해서는 이 bootkey를 복호화해 syskey 를 얻어내는 과정이 필요하다.

 복호화에 필요한 데이터는 SAM 레지스트리의 SAM\SAM\Domains\Account 키의 F 데이터로부터 확인할 수 있다.

SAM/SAM/Domains/Account

16:32 바이트 영역이 IV(salt), 32:64 바이트 영역이 Data 가 된다. 자 이제 복호화를 할 수 있다.

bootkey -> key
IV(salt) -> IV
Data -> Data 로 AES CBC 복호화를 수행하면 우리는 syskey 를 손에넣을 수 있다.

 

3-1. NTLM 복호화

SAM/SAM/Domains/Account/Users/{RID}

SAM/SAM/Domains/Account/Users 키의 하위 경로에는 사용자 계정에 관한 인증정보들을 RID 키로 구분해 저장하고 있다. 이것이 무슨말이냐 한다면 바로 다음 표와 같다.

HEX DEC ETC
000001F4 500 administrator 계정
000003E9 1001 (비밀)
000003EA 1002 troll 계정

Users 키의 하위 키의 16진수는 각 계정의 RID이며 이는 사용자별로 부여되는 고유 식별자다. 그리고 V 데이터 안에는 우리가 그토록 찾아헤매던 사용자 계정 정보와 암호화된 NTLM 해시가 잠들어있다.

 

4.