Phát hiện tấn công trên Windows với Splunk

Các bài viết liên quan

Domain Reconnaissance

Các công cụ thường được sử dụng trong tấn công:

Ngoài ra để thu thập thông tin về domain, kẻ tấn công có thể sử dụng SharpHound/BloodHound. Bản chất của công cụ này là sử dụng LDAP để truy vấn thông tin.

Có 2 cách thu thập dữ liệu liên quan đến truy vấn LDAP đến Splunk bao gồm:

Link xem thêm

Cách phát hiện thông qua sysmon EventID=1:

index=main source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventID=1
| search process_name IN (arp.exe,chcp.com,ipconfig.exe,net.exe,net1.exe,nltest.exe,ping.exe,systeminfo.exe,whoami.exe) OR (process_name IN (cmd.exe,powershell.exe) AND process IN (*arp*,*chcp*,*ipconfig*,*net*,*net1*,*nltest*,*ping*,*systeminfo*,*whoami*))
| stats values(process) as process, min(_time) as _time by parent_process, parent_process_id, dest, user
| where mvcount(process) > 3

Cách phát hiện BloodHound qua LDAP filters:

index=main source="WinEventLog:SilkService-Log"
| spath input=Message 
| rename XmlEventData.* as * 
| table _time, ComputerName, ProcessName, ProcessId, DistinguishedName, SearchFilter
| sort 0 _time
| search SearchFilter="*(samAccountType=805306368)*"
| stats min(_time) as _time, max(_time) as maxTime, count, values(SearchFilter) as SearchFilter by ComputerName, ProcessName, ProcessId
| where count > 10
| convert ctime(maxTime)

LLMNR/NBT-NS/mDNS Poisoning

Các bước tấn công:

  1. Thiết bị nạn nhân gửi truy vấn phân giải tên cho một tên máy chủ bị nhập sai (ví dụ: fileshare).
  2. DNS không phân giải được tên máy chủ bị nhập sai.
  3. Thiết bị nạn nhân gửi truy vấn phân giải tên cho tên máy chủ bị nhập sai bằng LLMNR/NBT-NS.
  4. Máy chủ của kẻ tấn công phản hồi lưu lượng LLMNR (UDP 5355)/NBT-NS (UDP 137), giả vờ biết danh tính của máy chủ được yêu cầu → dẫn nạn nhân giao tiếp với hệ thống do kẻ tấn công kiểm soát.

20260105160611.png

Cách phát hiện:

Link xem thêm

Phát hiện trên Splunk:

Kerberoasting

Kerberoasting là một kỹ thuật tấn công nhắm vào các service account được đặt mật khẩu yếu trong môi trường Active Directory.

Các bước thực hiện tấn công:

  1. Phát hiện các service account được sử dụng cho các service như IIS, SQL Server, Exchange,…
  2. Thực hiện yêu cầu xin TGS từ KDC, sau đó trích xuất password hash từ response trả về và tiến hành crack offline với Hashcat, John the Ripper,…

Các EventID liên quan:

Cách phát hiện dựa vào Splunk:

AS-REProasting

AS-REProasting là một kỹ thuật tấn công nhắm vào các user account không bật pre-authentication.

Khi pre-authentication được bật, yêu cầu AS-REQ từ client đến KDC sẽ chứa giá trị timestamp được mã hoá (pA-ENC-TIMESTAMP) bởi password hash của user. KDC xác nhận timestamp bằng cách giải mã giá trị này.

20260105161214.png

Khi pre-authentication được bật, timestamp không được xác nhận bởi KDC, cho phép user yêu cầu TGT mà không cần password.

20260105161238.png

Các bước tấn công:

  1. Tìm kiếm các user account với pre-authentication bị tắt
  2. Yêu cầu AS-REQ Service Ticket với các account phát hiện được
  3. Thu thập TGT và triển khai offline hash crack

Cách phát hiện với Splunk:

Pass-the-Hash

Pass-the-Hash là kỹ thuật tấn công mà trong đó, kẻ tấn công không sử dụng plaintext password để đăng nhập vào hệ thống mạng mà sử dụng NTLM hash. Để có được NTLM hash trên một máy bị thao túng thì cần có quyền quản trị viên.

Các bước tấn công như sau:

  1. Khi thao túng được một máy với quyền cao nhất, kẻ tấn công sử dụng Mimikatz để trích xuất NTLM hash của user đang trong phiên đăng nhập.
    20260105161423.png
  2. Kẻ tấn công sử dụng NTLM hash này đăng nhập vào các hệ thống khác trên mạng → di chuyển ngang.
    20260105161436.png

Các quan sát thấy được trên hệ thống bị thao túng khi có tấn công:

Cách phát hiện sử dụng mimikatz để pass-the-hash trên Splunk:

index=main earliest=1690450708 latest=1690451116 source="WinEventLog:Security" EventCode=4624 Logon_Type=9 Logon_Process=seclogo
| table _time, ComputerName, EventCode, user, Network_Account_Domain, Network_Account_Name, Logon_Type, Logon_Process
index=main earliest=1690450689 latest=1690451116 (source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=10 TargetImage="C:\\Windows\\system32\\lsass.exe" SourceImage!="C:\\ProgramData\\Microsoft\\Windows Defender\\platform\\*\\MsMpEng.exe") OR (source="WinEventLog:Security" EventCode=4624 Logon_Type=9 Logon_Process=seclogo)
| sort _time, RecordNumber
| transaction host maxspan=1m endswith=(EventCode=4624) startswith=(EventCode=10)
| stats count by _time, Computer, SourceImage, SourceProcessId, Network_Account_Domain, Network_Account_Name, Logon_Type, Logon_Process
| fields - count
Nhận xét:

Cách phát hiện này khó áp dụng trong thực tế, vì để giảm khối lượng dữ liệu vào Splunk, thông thường chỉ có AD được lấy đầy đủ cả Windows Event Logs và Sysmon. Trong khi đó, việc sử dụng mimikatz trực tiếp trên AD gần như vô nghĩa hoặc không thể xảy ra khi tấn công. Phạm vi phát hiện của các rule này là khi chạy mimikatz trên local, và nếu có pass-the-hash nhắm vào tài nguyên mạng thì AD gần như chỉ ghi lại EventID 4624 với LogonType=3 (đăng nhập qua network).
Hiệu quả: 10%
Kiến thức và tạo nguồn cảm hứng cho vấn đề khác: 100%

Pass-the-Ticket

Tương tự Pass-the-Hash, nhưng thay vì khai thác NTLM hash thì tấn công này sử dụng lại TGT/TGS để tiếp cận tài nguyên, hệ thống khác trong mạng.

Các bước tấn công:

  1. Trên máy bị thao túng mà kẻ tấn công có quyền quản trị, Mimikatz hoặc Rubeus được sử dụng để trích xuất TGT/TGS
  2. Sử dụng TGT để request TGS mới hoặc gửi thẳng TGS đến service muốn truy cập.

Các sự kiện liên quan:

Cách tiếp cận để phát hiện tấn công:

Phát hiện với Splunk:

index=main earliest=1690392405 latest=1690451745 source="WinEventLog:Security" user!=*$ EventCode IN (4768,4769,4770) 
| rex field=user "(?<username>[^@]+)"
| rex field=src_ip "(\:\:ffff\:)?(?<src_ip_4>[0-9\.]+)"
| transaction username, src_ip_4 maxspan=10h keepevicted=true startswith=(EventCode=4768)
| where closed_txn=0
| search NOT user="*$@*"
| table _time, ComputerName, username, src_ip_4, service_name, category

maxspan=10h - window time này cần được custom để giảm False Positives.

Overpass-the-Hash

Hay Pass-the-Key là một kỹ thuật sử dụng password hash để tạo yêu cầu TGT đến KDC.

Cả NTLM hash và AES keys đều có thể được dùng để yêu cầu TGT.

Các bước tấn công:

  1. Sử dụng Mimikatz để trích xuất NTLM hash của user hiện tại đang trong phiên đăng nhập trên máy, tối thiểu phải có quyền local administrator để thực hiện việc này.
  2. Sử dụng công cụ như Rubeus để tạo yêu cầu TGT đến KDC.

Cách phát hiện:

Golden Tickets

Khi kẻ tấn công đã có trong tay NTLM hash của tài khoản krgtgt thông qua tấn công DCSync hoặc LSASS Dump thì hắn có thể tạo TGT với user bất kỳ và gắn quyền administrator một cách bất hợp pháp.

Dưới góc độ phân tích dữ liệu log thì tấn công sử dụng Golden Tickets có sự tương quan với Pass-the-Hash. Do đó, có thể dùng phương pháp tương tự để phát hiện.

Silver Ticket

Khi đã có được NTLM hash của một service account hoặc machine account, kẻ tấn công không cần phải giao tiếp với KDC để lấy TGT hay TGS mà hắn tự tạo cho mình một TGS hợp lệ và cho phép hắn truy cập bất hợp pháp vào service/machine đó.

Ví dụ:

Mô tả tấn công trong ví dụ này:

Ví dụ tạo bởi ChatGPT

Cá dấu hiệu phát hiện tấn công:

Unconstrained Delegation

Unconstrained Delegation là một đặc quyền (privilege) được cấp cho User Accounts hoặc Computer Accounts trong môi trường AD, cho phép một service xác thực dưới danh nghĩa của user khác và được truy cấp tài nguyên nằm trong phạm vi quyền được truy cập của user đó.

Tại sao lại có cơ chế Unconstrained Delegation này?

Trong môi trường doanh nghiệp, có rất nhiều tình huống kiểu sau:

Người dùng → Web Server → Database Server

Ví dụ:

→ Tức là, web server cần được phép "impersonate" (giả lập) danh tính của user để truy cập tài nguyên khác trong nội bộ domain.

Khi một service (computer hoặc user account) được gán quyền “Trust this computer for delegation to any service (Kerberos only)”:

=> Service có thể giả mạo user để truy cập bất kỳ tài nguyên nào mà user được phép truy cập.

Các bước tấn công:

  1. Kẻ tấn công thu thập thông tin về các hệ thống có đặc quyền Unconstrained Delegation được bật cho service account
  2. Khi may mắn có được quyền truy cập hệ thống đó, kẻ tấn công có thể sử dụng Mimikatz để trích xuất toàn bộ TGT trong bộ nhớ

Cách phát hiện:

Constrained Delegation

Microsoft đưa ra Constrained Delegation để giới hạn phạm vi delegation:
Một service chỉ được phép impersonate user đến những dịch vụ cụ thể, được liệt kê sẵn trong thuộc tính msDS-AllowedToDelegateTo — danh sách SPNs mà service có thể thay mặt user truy cập.

Ví dụ:

Các bước tấn công:

  1. Kẻ tấn công thu thập thông tin về các hệ thống có đặc quyền Constrained Delegation được bật cho service account
  2. Trích xuất TGT từ bộ nhớ của hệ thống nếu may mắn chiếm được quyền truy cập vào một trong các hệ thống.
  3. Sử dụng kỹ thuật S4U để giả danh (impersonate) user có đặc quyền cao đến dịch vụ khác (nằm trong danh sách SPNs của msDS-AllowedToDelegateTo)

S4U (Service-for-User) là một phần mở rộng của Kerberos (Microsoft implementation) cho phép một service lấy vé Kerberos (ticket) đại diện cho một user mà service đó không có mật khẩu. Có hai biến thể chính:

Tóm lại: S4U2Self lấy “vé cho chính service nhưng mang identity user”; S4U2Proxy đổi vé đó thành vé tới service đích — giải quyết vấn đề “double hop“.

Cách phát hiện với Splunk:

DCSync

DCSync là kỹ thuật cho phép kẻ tấn công trích xuất toàn bộ hash password (bao gồm cả KRBTGTAdministrators) từ Domain Controllers. Điều kiện để có thể thực hiện kỹ thuật này là phải có được user account/computer account có quyền Replication Directory Changes. Các user account nằm trong nhóm Administrators, Domain Admins, và Enterprise Admin hoặc computer account của máy có vai trò domain controllers đều mặc định có quyền này.

Các bước tấn công:

  1. Kẻ tấn công tiến hành mọi cách để leo thang đặc quyền, chiếm được các account có khả năng thực hiện DCSync

  2. Sử dụng các công cụ như Mimikatz, kẻ tấn công sẽ yêu cầu dữ liệu sao chép domain bằng interface DRSGetNCChanges, về cơ bản là giả mạo yêu cầu hợp pháp của domain controller.

  3. Sau khi có được hash password của mọi user, để khai thác hoàn toàn môi trường, một số tấn công có thể được áp dụng như Golden/Silver Tickets, Pass-the-Hash/Overpass-the-Hash.

Cách phát hiện với Splunk:

DCShadow

Kẻ tấn công đăng ký DC giả và đẩy thay đổi vào AD này bằng con đường replication. Dấu hiệu nổi bật: tạo server / nTDSDSA objects trong Configuration partition + các thay đổi AD xuất hiện như replication-originated (không theo thao tác CRUD trên quản trị). DCShadow có thể tránh một số audit vì thay đổi đến AD qua replication channel.

Các bước tấn công:

  1. Kẻ tấn công cần tài khoản có đặc quyền cao (Domain Admin / local admin trên DC / quyền write vào Configuration partition) hoặc có thể gán quyền replication.

  2. Tạo object servernTDSDSA trong Configuration partition, có thể tạo/ghi computer account; thực hiện thay đổi AD (ví dụ: thêm user vào Domain Admins).

  3. Domain controller giả khởi tạo replication với các domain controller hợp pháp, lan truyền các thay đổi đó khắp domain.

Cách phát hiện:

index=main EventCode=4742 
| rex field=Message "(?P<gcspn>XX\/[a-zA-Z0-9\.\-\/]+)" 
| table _time, ComputerName, Security_ID, Account_Name, user, gcspn 
| search gcspn=*

Khi một Domain Controller được bật hoặc tắt chức năng Global Catalog, hoặc SPN GC/<DCName> được cập nhật → sinh event 4742. Vì vậy, filter EventCode=4742 giúp tìm các thay đổi trên tài khoản máy tính Domain Controller — đặc biệt hữu ích khi muốn phát hiện:

Global Catalog là một dịch vụ đặc biệt chạy trên Domain Controller (DC), nó giữ bản sao một phần (partial replica) của mọi object trong forest.

Vì Global Catalog là một dịch vụ LDAP đặc biệt, chạy song song với dịch vụ LDAP thông thường trên DC, nên nó cũng cần SPN riêng để Kerberos có thể cấp vé (TGS ticket) cho client muốn truy cập dịch vụ GC.

index="cobaltstrike_beacon" sourcetype="bro:http:json" 
| sort 0 _time
| streamstats current=f last(_time) as prevtime by src, dest, dest_port
| eval timedelta = _time - prevtime
| eventstats avg(timedelta) as avg, count as total by src, dest, dest_port
| eval upper=avg*1.1
| eval lower=avg*0.9
| where timedelta > lower AND timedelta < upper
| stats count, values(avg) as TimeInterval by src, dest, dest_port, total
| eval prcnt = (count/total)*100
| where prcnt > 90 AND total > 10