Lỗ hổng Kerberos Bronze Bit (Phần 1 - Giới thiệu lỗ hổng)
Phần I. Tìm
hiểu về giao thức Kerberos
I. Kerberos là
gì?
- Giao thức xác thực,
sử dụng trên đường truyền không an toàn
- Là giao thức mặc
định sử dụng trên HĐH Window, Unix, MacOS
- Được sử dụng
trong mô hình Client – Server để đảm bảo xác thực, chống nghe lén hay gửi các
gói tin cũ, đảm bảo toàn vẹn dữ liệu
- Xây dựng dựa trên
mã khóa đối xứng và cần một bên thứ ba mà cả hai phía tin tưởng
II. Cơ chế hoạt
động
1. Hệ
thống gồm:
- Người dùng dịch vụ
(Client)
- Máy chủ cung cấp
khóa – KDC (Key Distribution Center)
o
Máy chủ xác thực
– AS (Authentication Server)
o
Máy chủ cấp vé –
TGS (Ticket Granting Server)
o
CSDL thông tin của
client – server
- Máy chủ cung cấp
dịch vụ - AP (Applycation Server)
2. Tổng
quan về cách thức hoạt động:
- Client xác thực với
AS -> AS check trong CSDL sau đó cấp quyền cho Client đến TGS -> TGS cấp
cho client vé để sử dụng dịch vụ trên SS -> Client mang vé đến SS để sử dụng
dịch vụ.
- Để dễ hiểu thì có thể hiểu là: Muốn sử dụng dịch vụ
thì phải có vé, mà muốn có vé phải đi mua vé ở quầy bán vé, muốn vào được quầy
bán vé thì phải qua phòng bảo về để xác thực)
3. Cụ
thể cách thức hoạt động:
Pha
1: kết nối với AS để lấy vé TGT (ticket-granting ticket) để truy nhập
TGS
-
Client gửi yêu
cầu xác thực (AS_REQ) đến AS yêu cầu xác thực
o
Client nhập
định danh (ID) và mật khẩu
o
Phần mềm client
thực hiện băm 1 chiều trên mật khẩu nhận được và dùng làm khóa bí
mật của client
o
Client gửi gói
tin (không mã hóa) đến AS để yêu cầu dịch vụ. Trong gói tin chỉ có
Client ID, không chứa khóa bí mật hay mật khẩu
-
AS nhận được
yêu cầu của client thì kiểm tra Client có thuộc DB không. Nếu có thì
gửi tới Client AS_REP gồm 2 gói tin:
o
Gói A: “khóa
phiên Client/TGS” được mã hóa với private key của Client
o
Gói B: “Ticket
Granting Ticket – TGT”, gồm ClientID, IP của Client, thời hạn của vé và
“khóa phiên Client/TGS”. TGT được mã hóa bằng private key của TGS
-
Khi Client nhận
được 2 gói tin trên sẽ giải mã Gói A bằng mật khẩu và thu được
“khóa phiên Client/TGS”. Gói B mã hóa với private key của TGS nên không
giải mã được. Lúc này Client đã có thể xác thực mình với TGS
Pha
2: Client xác thực với TGS
-
Client gửi
TGS_REQ, gồm 2 gói tin đến TGS để yêu cầu dịch vụ:
o
Gói C: TGT từ
gói tin B và định danh của dịch vụ yêu cầu (Service ID)
o
Gói D: Phần
xác thực, chứa Client ID và thời điểm yêu cầu (timestamp) được mã hóa
bằng “khóa phiên Client/TGS”
-
TGS giải mã C
bằng private key của mình và thu được “khóa phiên Client/TGS”. Khóa này
sau đó được dùng để giải mã D và thu được phần xác thực. Tiếp theo
TGS gửi TGS_REP trở lại cho Client gồm 2 gói tin:
o
Gói E: “Vé
Client/AP” (gồm ClientID, IP của Client, thời hạn sử dụng và “khóa
phiên Client/AP”) và được mã hóa bằng private key của AP
o
Gói F: “Khóa
phiên Client/AP” mã hóa bằng “khóa phiên Client/TGS”
-
Sau khi nhận
được E, F; Client giải mã F để lấy “khóa phiên Client/AP”. Lúc này
người dùng đã có đủ thông tin để xác thực với AP
Pha
3: Client truy cập và yêu cầu cấp phép sử dụng dịch vụ
-
Client kết nối
với AP và gửi AP_REQ gồm 2 gói tin:
o
Gói E: Vé thu
được từ pha trên
o
Gói G: Phần
xác thực mới, gồm ClientID và timestamp, được mã hóa bằng “khóa phiên
Client/AP” thu được từ việc giải mã F.
-
AP giải mã E
bằng private key của mình để lấy “khóa phiên Client/AP”. Khóa này sau
đó được dùng để giải mã G. Nhờ đọc được phần xác thực mới, AP gửi
AP_REP chứa gói tin H tới người dùng để xác nhận định danh của mình
cũng như đồng ý cho sử dụng dịch vụ:
o
Gói H: chứ
timestamp trong G cộng thêm 1, mã hóa bằng “khóa phiên Client/AP”
-
Client giải mã
gói H, xác nhận và kiểm tra thời gian có được cập nhận đúng hay
không. Nếu đúng thì người dùng có thể tin tưởng AP và tiến hành gửi
request để sử dụng dịch vụ, AP cung cập dịch vụ mà Client yêu cầu
Phần II. Ủy quyền trong Kerberos
Ví dụ: Khi người dùng xác thực ứng dụng web sau đó ứng
dụng web cần truy cập cơ sở dữ liệu dưới quyền của người dùng. Cơ sở dữ liệu sẽ
kiểm soát việc liệu một người dùng nhất định có được phép truy cập một bản ghi
cụ thể hay không. Khi ứng dụng web cố gắng truy cập bản ghi trong cơ sở dữ liệu
nó phải thực hiện ủy quyền của người dùng trong request để cơ sở dữ liệu xác định
request đó được cho phép hay từ chối. Điều này gọi là “double-hop” (nhảy đôi)
Sự cố được khai thác thông qua “ủy quyền trong
Kerberos” khi cho phép Service1 mạo danh người dùng và tương tác với Service2
như thể các request đến trực tiếp từ người dùng. Một số kiểu ủy quyền Kerberos
trong Active Derectory sẽ đươc nên ở dưới
-
Unconstrained
Delegation (Ủy quyền không giới hạn)
-
Constrained
Delegation (Ủy quyền có ràng buộc)
o
Không chuyển đổi
giao thức
o
Có chuyển đổi
giao thức
-
Resource-Based
Constrained Delegation (Ủy quyền hạn chế dựa trên nguồn)
Cài đặt ủy
quyền trong AD
I. Unconstrained
Delegation (Ủy quyền không giới hạn)
Lỗ hổng không ảnh hưởng đến cấu hình này, tuy nhiên cần
tránh việc ủy quyền không giới hạn. Service1 được ủy quyền không giới hạn với
cài đặt “Trust this computer for delegation to any service (Kerberos only)”.
Khi người dùng nhận được service ticket cho Service1, KDC sẽ nhúng TGT của người
dùng vào service ticket. Khi “Ticket Service” được chuyển đến Service1,
Service1 có thể lấy ra TGT. Với TGT của người dùng, Service1 có thể thực hiện
việc “Ticket-Granting Service Exchange” và nhận “Ticket service” với tư cách
người dùng cho bất kỳ dịch vụ nào. Điều này cho phép hoàn toàn mạo danh người
dùng.
II. Constrained
Delegation (Ủy quyền hạn chế)
Chỉ định trước các mục tiêu ủy quyền của dịch vụ. Ví dụ:
cấu hình Service1 chỉ được phép ủy quyền cho Service2, thay vì mọi dịch vụ
trong domain. Khi người dùng nhận được ticket service cho Service1, KDC sẽ
không nhúng TGT của người dùng vào service ticket nữa.
1. Ủy quyền hạn
chế mà không chuyển đổi giao thức
Người dùng xác thực với Service1 thông qua Kerberos,
Service1 cần truy cập đến Service2 dưới quyền của người dùng. Vì service ticket
của người dùng dành riêng cho Service1, nếu chuyển tiếp đến Service2 sẽ bị từ
chối. Nếu không có TGT của người dùng, Service1 không thể nhận được service
ticket tới Service2 từ KDC. Vậy làm thế nào để Service1 xác thực với Service2 với
tư cách người dùng?
Sử dụng MS-SFU để giải quyết thông qua giao thức
“Service for User to Proxy” (S4U2proxy) (MS-SFU là tiền ích mở rộng của giao thức
Kerberos: dịch vụ này cho phép người dùng ủy quyền ràng buộc).
Giao thức S4U2proxy cho phép Service1 lấy service
ticket cho Service2 với tư cách người dùng bằng cách gửi cho KDC service ticket
mà nhận được từ người dùng, cùng với TGT của riêng Service1. KDC gửi lại bằng
“TGS_REP” bao gồm service ticket sử dụng cho Service2 được ủy quyền với tư cách
người dùng. Sau khi khi có service ticket, Service1 và Service2 tiến hành việc
“Client/Server exchange”. Quá trình trao đổi hoàn tất, Service2 xử lý request từ
Service1 như đến từ người dùng.
Giao thức S4U2proxy cho phép ủy quyền ràng buộc mà
không cần chuyển đôi giao thức vì giao thức Kerberos được dùng trong mọi bước.
Tất cả các bước được xác thực với nhau thông qua Kerberos và trao đổi ticket
2. Ủy quyền hạn
chế có chuyển đổi giao thức
Xảy ra khi người dùng được phép xác thực với Service1
bằng 1 giao thức không phải Kerberos.
Ví dụ: Service1 có thể xác thực người dùng thông qua
xác thực NTLMv2. Nếu Service1 sau đó cần xác thực ủy quyền đó cho Service2 sẽ
không thực hiện được (vì không có vé).
Trong trường hợp này, Service1 cần chuyển đổi giao thức
bằng cách sử dụng giao thức thứ 2 được cung cấp trong MS-SFU là “Service for
User to Self” (S4U2self).
Giao thức S4U2self cho phép dịch vụ nhận được một
service ticket thay mặt cho bất kỳ người dùng nào. Giao thức này là sự thay đổi
khi “Tick-Granting Exchange”. Service1 gửi TGT + timestamp được mã hóa bằng
session key của KDC và chỉ định người dùng mà nó muốn có vé. KDC xử lý request,
thực hiện xác thực và trả về cho Service1 service ticket, tên người dùng được
chỉ định trong trường “cname”.
Bây giờ Service1 đã có service ticket cho chính nó.
Service1 sử dụng vé này trong S4U2proxy Exchange và nhận service ticket tới
Service2 thay mặt người dùng
Điều quan trọng cần lưu ý là một dịch vụ có thể yêu cầu
service ticket cho bất kỳ người dùng nào thông qua giao thức S4U2self. Dịch vụ
không phải đưa ra bằng chứng cho thấy người dùng thực sự xác thực với dịch vụ.
III. Resource-Based
Constrained Delegation (RBCD) (ủy quyền dựa trên nguồn)
Xác định danh sách các dịch vụ mà một dịch vụ cụ thể
có thể ủy quyền.
Ví dụ: ServiceA được phép ủy quyền xác thực Kerberos
cho ServiceB, ServiceC, ServiceD. Danh sách sẽ được cấu hình tại
“AllowedToDelegateTo” của ServiceA trong Active Derectory. RBCD có trong
Windows Server 2012 trở đi.
IV. Bảo vệ trong
ủy quyền hạn chế
Dù phạm vi hẹp hơn ủy quyền không hạn chế nhưng ủy quyền
hạn chế vẫn có thể mạo danh người dùng.
-
Dịch vụ để ủy quyền
có chuyển đổi giao thức thì thuộc tính “TrustedToAuthForDelegation” trong AD sẽ
được bật. Điều này tương ứng với tùy chọn “Trust this computer for delegation
to specified services only – Use any authentication protocol” (Chỉ tin cậy máy
tính này để ủy quyền cho các dịch vụ được chỉ định - Sử dụng bất kỳ giao thức
xác thực nào) trong AD GUI
-
Dịch vụ để ủy quyền
không chuyển đổi giao thức thì thuộc tính “TrustedToAuthForDelegation” trong AD
không sử dụng nhưng vẫn có danh sách “AllowedToDelegateTo” được điền. Điều này
tương ứng với tùy chọn Trust this computer for delegation to specified services
only – Use Kerberos only” (Chỉ tin cậy máy tính này để ủy quyền cho các dịch vụ
được chỉ định - Chỉ sử dụng Kerberos) trong AD GUI. Mặc dù bấy kỳ dịch vụ nào cũng có thể tự mình
thực hiện S4U2self exchange để lấy service ticket với tư cách là bất kỳ người
dùng nào nhưng nếu chuyển đổi giao thức không được phép thì service ticket sẽ
có Forwardable flag là 0. Khi đó service ticket chuyển trong S4U2proxy exchange
tiếp theo sẽ không thành công.
V. Bảo vệ người
dùng và tài khoản nhạy cảm
Người dùng và các tài khoản AD khác có thể cấu hình để
không cho phép ủy quyền xác thực:
-
Enable “Account
is sensitive and cannot be delegated” trong AD cho tài khoản
-
Theo tài khoản
vào nhóm bảo mật trong AD “Protected Users”. Bất kỳ thành viên nào trong nhóm này
đều không được ủy quyền xác thực
ð Giống như “Use kerberos only”, các biện pháp này đảm bảo
rằng khi một vé tạo cho những người dùng này thì gia trị Forwardable flag luôn
bằng 0. Một dịch vụ có thể có vé của người dùng thông qua giao thức S4U2self
nhưng vì vé không chuyển tiếp được nên không sử dụng được trong S4U2proxy để lấy
vé cho dịch vụ khác.
Phần III: Tổng
quan về ủy quyền
Service1 muốn xác thực với Service2 với tư cách là người
dùng nhưng người dùng chưa xác thực với Service1 thông qua Kerberos
-
Bước 1:
Authentication Service Exchange
o
Mã hóa timestamp
bằng “long term key” (màu xanh)
o
KDC xác thực
timestamp sau đó trả về AS_REP (logon session key (khóa phiên đăng nhập) + TGT)
-
Bước 2: S4U2self
Exchange
o
Service1 có khóa
phiên đăng nhập và TGT.
o
Service1 mã hóa
timestamp khác bằng khóa phiên đăng nhập
o
Service1 gửi
timestamp đã mã hóa + TGT + tên người
o
KDC xác nhận TGT
và timestamp. Chuẩn bị một service ticket cho Service1. Ban đầu, Forwardable
flag = 1
o
KDC sẽ kiểm tra
xem Service1 có đặt thuộc tính "TrustedToAuthForDelegation" hay
không; người dùng mục tiêu có được bảo vệ khỏi sự ủy quyền hay không; có là
thành viên của nhóm "Protected Users" hoặc được định cấu hình
“Account is sensitive and cannot be delegated” hay không? Nếu không thì Forwardable
flag = 0.
o
KDC trả lại phiếu
dịch vụ mới cho Service1. Service1 hiện
có một vé hợp lệ với tư cách là người dùng, có thể chuyển tiếp hoặc không thể
chuyển tiếp.
-
Bước 3: S4U2proxy
Exchange
o
Service 1 gửi
service ticket cho KDC để chứng minh người dùng đã xác thực với Service1 và yêu
cầu một service ticket mới cho Service2 với tư cách người dùng
o
KDC xác thực mối
quan hệ ủy quyền giữa Service1 và Service2
§ Service2 có trong danh sách “AllowedToDelegateTo” của
Service1 không => ủy quyền bị ràng buộc
§ Nếu không KDC kiểm tra Service1 có nằm trong danh sách
“PrincipalsAllowedToDelegateToAccount” của Service2 không => ủy quyền dựa
trên tài nguyên (RBCD)
§ Cả 2 lần kiểm tra không thành công => trao đổi
không thành công
o
Sau khi xác nhận
Service1 được phép ủy quyền xác thực cho Service2, KDC giải mã service ticket
và kiểm tra Forwardable flag
§ Nếu Forwardable flag = 0 => KDC kiểm tra bổ sung và
trao đổi không thành công do lỗi
§ Nếu Forwardable flag = 1 => KDC trả về service
ticket hợp lệ cho Service2 với tư cách là người dùng
Phần IV: Lỗ hổng
Để ý kỹ cấu trúc của TGS_REP do KDC trả về sau
S42Uself exchange. Giả sử Service1 không phải “TrustedToAuthForDelegation” hoặc
người dùng chỉ định được bảo vệ khỏi ủy quyền thì Forwardable flag = 0. Điều
này có nghĩ là session ticket sẽ bị từ chối nếu sử dụng trong S42Uproxy
exchange
Để ý kỹ sẽ thấy Forwardable flag được mã hóa bằng “long-term key” của Service1. Và
Forwardabe cũng không có trong PAC.
ð Service1 có thể dùng “long-term key” của mình giải mã
(gói tin màu xanh), đặt lại giá trị của Forwardable flag = 1 rồi mã hóa lại
service ticket. Do không có trong PAC nên KDC không thể phát hiện rằng giá trị
Forwardable flag đã bị giả mạo
Vậy
đã có thể chuyển đổi một service ticket không thể chuyển tiếp thành một service
ticket có thể chuyển tiếp. Service ticket này có thể sử dụng trong S4U2prox
exchange, cho phép Service1 ủy quyền xác thực cho Service2 với tư cách là bất kỳ
người dùng nào
Ở phần tiếp theo mình sẽ tiến hành việc khai thác lỗ hổng Kerberos Bronze Bit này
Nhận xét
Đăng nhận xét