Alternate Service Name
커버로스 위임 중 Constrained Delegation은 S4U2Proxy 확장을 통해 A 서비스 티켓을 B 서비스 티켓으로 교환할 수 있습니다. 그리고 커버로스 패킷의 sname 필드는 암호화 되지 않기 때문에 서비스 센터에서 sname 값에 대한 검증이 불충분하다면 sname 값을 조작하여 다른 서비스를 이용하는게 가능합니다.
Abuse
# 서비스 티켓 교환
.\Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:cifs/ad01.contoso.com /user:user-A /rc4:2b576acbe6bcfda7294d6bd18041b8fe /domain:contoso.com /altservice:ldap /ptt /nowrap
Root Cause
acs.secure/Mick3y는 acs-dc01.acs.secure의 cifs에 대해서 제약된 위임 권한이 있기 때문에 Administrator를 대행하여 자신의 서비스 티켓을 발급받습니다.


두번째 TGS-REQ/REP 과정도 Constrained Delegation 에서 본 것과 동일한 흐름을 확인할 수 있습니다.


Alternate Service Name 공격의 TGS-REQ에서 요청하는 서비스 이름을 위임받은 SPN 소유자의 다른 서비스로 변경하지 않는 이유는 sname 필드 검증 단계가 TGS-REQ에는 있기 때문입니다. 단지 반환받은 특정 서비스에 대한 TGS-REP의 sname 필드를 변조하여 같은 서비스 주체의 다른 서비스에 대해 AP-REQ를 했을 때 서비스 센터에서 검증하지 않아 발생하는 취약점입니다.

따라서 altservice 인자를 넣었을 때 동작 흐름을 분석하려면 코드와 반환된 티켓을 봐야합니다.
getST.py에서 impersonate 인자를 넣었을 때 doS4U2ProxyWithAdditionalTicket 함수를 통해 TGS-REQ를전송하고 받은 TGS-REP를 TGS 변수에 할당합니다. 함수의 마지막은 saveTicket 함수에 반환된 TGS 변수를 전달하여 실행합니다.
saveTicket 함수에서는 사용자가 altservice 인자를 사용했을 경우 반환된 서비스 티켓에서 sname 값을 altservice에서 준 값에서 '/' 기호를 기준으로 동적으로 할당하여 저장하는 것이 확인됩니다.

저장된 티켓을 Rubeus의 describe를 통해 확인하면 altservice 인자로 입력한 서비스 이름이 확인됩니다.
Last updated
Was this helpful?