> For the complete documentation index, see [llms.txt](https://www.pentestwiki.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.pentestwiki.com/active-directory/ad-trust/cross-forest/inter-realm-kerberoasting.md).

# Inter realm Kerberoasting

도메인 신뢰 패스워드는 어떤 방식으로 신뢰를 구성하는지에 따라 값의 형태가 달라지는데, 일반적인 경우 신뢰 관계가 등록된지 30일 미만의 경우 이 값은 사람이 사용하는 패스워드일 가능성이 높기 때문에 해시 크랙 가능성이 있습니다.

신뢰 패스워드는 레퍼럴 티켓 교환에 사용되는 비밀키로 일반적인 도메인 TGT에서의 krbtgt 비밀키와 동일한 역할을 합니다.

교차 도메인에서 레퍼럴 티켓에 사용되는 이 값이 탈취된다면 신뢰 계정으로 인증하여 보안 경계를 넘어 정보 수집 및 커버로스팅 등의 공격이 가능합니다.

## Abuse

<pre class="language-bash"><code class="lang-bash"><strong># Trust Kerberoasting 도구 설치
</strong>git clone https://github.com/KR-mick3y/TrustKerberoasting.git

<strong># contoso 도메인에서 korea 도메인 서비스를 요청하여 커버로스팅
</strong>python3 TrustRoasting.py contoso.com/client:Password123 -target korea.com
</code></pre>

## Root Cause

<figure><img src="/files/bDTNS4VPiuQKayoZKDgT" alt=""><figcaption><p>도메인 신뢰 등록 옵션</p></figcaption></figure>

도메인에서 양방향 신뢰 관계를 구축할 때, 대상 도메인의 관리자 자격 증명을 이용하여 단일 도메인에서 양방향 신뢰 관계를 구축하는 방법과 서로가 서로에게 일방향 신뢰를 맺을 수 있습니다.

`This domain only` 로 신뢰 관계를 등록할 경우 A 도메인에서는 B 도메인에 대한 일방향 신뢰를 등록하고 B 도메인에서도 A 도메인에 대한 일방향 신뢰를 등록해야 합니다. 서로가 신뢰 관계로 등록하면 커버로스 인증을 위한 레퍼럴 티켓을 동일한 krbtgt 비밀키로 암호화 해야 하는데, 신뢰 패스워드가 그 역할을 합니다.

<figure><img src="/files/qie0Kb47ncEJh65HhV8y" alt=""><figcaption><p>Trust Password</p></figcaption></figure>

언급한 것처럼 레퍼럴 티켓의 krbtgt 비밀키가 신뢰 패스워드기 때문에 양 도메인은 서로 신뢰를 구성할 때 동일한 값을 사용해야 합니다.&#x20;

{% hint style="info" %}
This domain only에 따라 신뢰 패스워드를 직접 구성하더라도, 30일 이후부턴 무작위 값으로 관리됩니다.
{% endhint %}

`Both this domain and the specified domain` 으로 신뢰 관계를 등록할 경우 단일 도메인에서 양방향 신뢰 관계가 구축되며, 신뢰를 구성하려는 도메인은 상대 도메인의 관리자 평문 자격 증명이 필요합니다.

<figure><img src="/files/qGASxZDE1NuDJvkXX3q5" alt=""><figcaption><p>대상 도메인 관리자 자격 증명 입력칸</p></figcaption></figure>

신뢰 관계가 성립되면 사용자가 직접 입력하지 않은 신뢰 패스워드는 랜덤한 128비트 값으로 설정되며 30일마다 자동으로 변경됩니다.&#x20;

어떤 방식으로 신뢰를 구성하더라도 신뢰 패스워드는 양 도메인의 TDO(Trusted Domain Object) 컨테이너 하위 Inter-realm Key 항목으로 저장됩니다.

<figure><img src="/files/ahwRtjtBKxTKCe8ULAAX" alt=""><figcaption></figcaption></figure>

글로벌 카탈로그는 자체 포레스트로 제한되기 때문에 Blue 도메인과 Green 도메인이 서로 같은 포레스트 내에 존재하는 신뢰 관계가 아닐 경우, Blue 도메인은 클라이언트가 요청한 Green 도메인 SPN이 실재하는지 확인할 수 없습니다. 이 경우 포레스트 TDO에 나열된 이름 접미사를 비교하여 일치하게 된다면 레퍼럴 티켓을 반환합니다.

<div><figure><img src="/files/mcVHoGj7o3JfZRgd92LV" alt=""><figcaption><p>같은 포레스트 내 위조 SPN 요청(TGS-REQ)</p></figcaption></figure> <figure><img src="/files/olYbZyj2KOJnkZOL3olN" alt=""><figcaption><p>같은 포레스트 내 위조 SPN 응답(TGS-REP)</p></figcaption></figure></div>

하지만 외부 포레스트 관계에서는 글로벌 카탈로그가 SPN의 진위 여부를 파악할 수 없기 때문에 위조 서비스 티켓을 요청하더라도 레퍼럴 티켓은 반환됩니다.

<figure><img src="/files/zOWaRvHX273YaHVLAFN6" alt=""><figcaption><p>위조 SPN 요청</p></figcaption></figure>

PENTEST 도메인 사용자 계정으로 CONTOSO에 없는 SPN을 요청했을 때 getST.py는 없는 SPN이라는 결과를 반환합니다. 하지만 여기서 반환된 에러 메시지는 레퍼럴 티켓에 대한 요청 결과가 아닌, 레퍼럴 티켓을 통해 CONTOSO KDC에 요청한 TGS-REQ의 결과입니다.&#x20;

<figure><img src="/files/h1TxDA6pQaP2Jhe8pUp7" alt=""><figcaption><p>전체 패킷</p></figcaption></figure>

전체 패킷 흐름을 확인하더라도 TGS-REQ가 두번 나오는 것이 확인되고, 두번째 TGS-REP에서 위에서 확인한 에러와 동일한 코드가 나온 것이 확인됩니다. 우리가 탈취하기 위한 Inter-realm Key로 암호화된 레퍼럴 티켓은 첫번째 요청이기 때문에 전혀 문제가 없다는 것을 알 수 있습니다.

<div><figure><img src="/files/BweKN58vV8aezsiGWjro" alt=""><figcaption><p>TGS-REQ</p></figcaption></figure> <figure><img src="/files/6gfRcq9sSQaJd7Z0826i" alt=""><figcaption><p>TGS-REP</p></figcaption></figure></div>

레퍼럴 티켓 요청 패킷을 조금 더 자세히 확인하면 응답 값에서 TGT 정보가 암호화되어 있음이 확인됩니다.

`$krb5tgs$23$*<trustAccount>$$<domain>$krbtgt*$<checksum>$<enc>` 형식으로 맞게 넣어주면 해시 크랙을 할 수 있게 됩니다.

<figure><img src="/files/vsbum4820tv2YnwCu3vB" alt=""><figcaption><p>해시 크랙 결과</p></figcaption></figure>

## References

{% embed url="<https://blog.xpnsec.com/inter-realm-key-roasting/>" %}

{% embed url="<https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/forest-recovery-guide/ad-forest-recovery-reset-trust>" %}

{% embed url="<https://learn.microsoft.com/ko-kr/entra/identity/domain-services/concepts-forest-trust>" %}
