Phát hiện 0-day từ xa trong triển khai SMB của Linux bằng o3
(sean.heelan.io)- Trong quá trình audit ksmbd, triển khai máy chủ SMB3 của nhân Linux, tác giả đã tìm ra lỗ hổng use-after-free từ xa CVE-2025-37899 chỉ bằng o3 API của OpenAI, không dùng framework agent hay công cụ riêng nào khác
- Lỗ hổng nằm ở việc các luồng khác vẫn có thể tiếp tục truy cập
sess->userđã được giải phóng trong khi xử lý lệnh SMBlogoff; nó chỉ lộ ra khi xem xét đồng thời các kết nối song song và trạng thái chia sẻ phiên - Trong benchmark dựa trên CVE-2025-37778 vốn được tìm thủ công, o3 tìm ra lỗ hổng 8 lần trong 100 lần chạy; Claude Sonnet 3.7 tìm được 3 lần, còn Claude Sonnet 3.5 là 0 lần
- Ở điều kiện mở rộng đầu vào tới tất cả handler lệnh SMB và mã xử lý kết nối, với 12k LoC / 100k token đầu vào, tỷ lệ phát hiện lỗ hổng cũ giảm xuống còn 1/100, nhưng cũng từ cùng loạt kết quả đó đã xuất hiện lỗ hổng mới CVE-2025-37899
- Kết quả sai và đầu ra vô nghĩa vẫn còn nhiều, nhưng xác suất có câu trả lời đúng đã tăng đủ cao để đáng cho con người xem xét và xác minh trong nghiên cứu lỗ hổng thực tế
Thử nghiệm tìm lỗ hổng ksmbd bằng o3
- Đối tượng audit là ksmbd, triển khai chia sẻ tệp qua giao thức SMB3 trong không gian nhân Linux
- Mô hình o3 của OpenAI được gọi qua
o3 API; không sử dụng scaffolding, framework agent hay công cụ riêng nào khác - Lỗ hổng được phát hiện là CVE-2025-37899, và bản sửa nằm trong commit của nhân Linux
- Vấn đề cốt lõi là use-after-free trong handler lệnh SMB
logoff: một đối tượng không có bộ đếm tham chiếu bị giải phóng trong khi vẫn có thể được luồng khác truy cập - Chỉ có thể tìm ra lỗ hổng này khi hiểu đồng thời các kết nối song song tới máy chủ và các đối tượng được chia sẻ trong những tình huống cụ thể
- Bài viết có nhận định rằng đây có vẻ là trường hợp đầu tiên được thảo luận công khai trong đó một LLM tìm ra lỗ hổng có tính chất như vậy
Lỗ hổng chuẩn CVE-2025-37778
- Trước hết, CVE-2025-37778 được tìm thủ công được dùng làm benchmark để đánh giá hiệu năng của o3
- Lỗ hổng này là một use-after-free xảy ra khi xử lý yêu cầu
session setuptừ client từ xa trong luồng xác thực Kerberos krb5_authenticategiải phóngsess->usernếusess->state == SMB2_SESSION_VALID- Phần mã sau đó dựa vào giả định rằng
ksmbd_krb5_authenticatesẽ khởi tạo lại bằng một giá trị hợp lệ mới, hoặc sau khi trả về-EINVALthìsess->usersẽ không còn được sử dụng - Trên thực tế, có thể khiến
ksmbd_krb5_authenticatekhông khởi tạo lạisess->user, và ngay cả khikrb5_authenticatetrả về-EINVALthì vẫn có thể truy cậpsess->user
Cấu hình benchmark và prompt
- CVE-2025-37778 được dùng làm benchmark vì nó nằm trên bề mặt tấn công từ xa và cần phải đánh giá đồng thời điều kiện kích hoạt
sess->state == SMB2_SESSION_VALID, đường đi không được khởi tạo lại, và đường truy cập sau khi đã giải phóng - Phần mã tối thiểu cần thiết để mô tả đường đi lỗ hổng được tính vào khoảng 3.3k LoC
- Đầu vào thử nghiệm bao gồm handler lệnh
session setupvà các hàm mà handler này gọi tới độ sâu gọi hàm là 3 - Mã nhận gói tin, phân tích yêu cầu, chọn handler lệnh, và dọn dẹp kết nối sau khi handler hoàn tất cũng được đưa vào để giảm việc phải suy đoán về cách khởi tạo cấu trúc dữ liệu
- Đầu vào cuối cùng vào khoảng 3.3k LoC / 27k token, và tệp được phân tích được công khai tại session_setup_code.prompt
- Prompt có các điều kiện sau
- Yêu cầu tìm lỗ hổng use-after-free
- Cung cấp ở mức cao vai trò, kiến trúc và mô hình đe dọa của ksmbd
- Thúc đẩy mạnh việc ưu tiên không báo cáo hơn là báo cáo sai
- Toàn bộ tệp prompt nằm trong kho o3_finds_cve-2025-37899
- Việc chạy thử nghiệm sử dụng công cụ
llmcủa Simon Willison
Kết quả benchmark CVE-2025-37778
- Harness thử nghiệm chạy cùng một truy vấn 100 lần và lưu kết quả
- o3 tìm ra CVE-2025-37778 8 lần trong 100 lần chạy
- Trong 66 lần trên 100, nó kết luận không có bug, trở thành false negative
- 28 lần còn lại là false positive
- Kết quả so sánh như sau
- Claude Sonnet 3.7: phát hiện 3 lần trong 100 lần
- Claude Sonnet 3.5: phát hiện 0 lần trong 100 lần
- Trong benchmark này, o3 cho kết quả cải thiện 2–3 lần so với Claude Sonnet 3.7
- Báo cáo mẫu được công khai dưới dạng kết quả o3 và kết quả Sonnet 3.7
- Đầu ra của o3, do cấu trúc và trọng tâm của nó, đọc giống một báo cáo bug rút gọn do con người viết, nhưng đôi khi quá ngắn nên kém rõ ràng
- Đầu ra của Sonnet 3.7 xuất hiện gần với dạng luồng suy nghĩ hoặc nhật ký công việc
Thử nghiệm mở rộng sang tất cả handler lệnh
- Trong thử nghiệm tiếp theo, không chỉ handler
session setupmà mã của tất cả handler lệnh SMB đều được cung cấp cho o3 - Các handler lệnh nằm trong
smb2pdu.c, tệp có kích thước khoảng 9k LoC - Khi gộp tất cả handler, mã thiết lập và dọn dẹp kết nối, cùng routine dispatch handler lệnh, tổng cộng vào khoảng 12k LoC / 100k token đầu vào
- Ở điều kiện này, thử nghiệm cũng được chạy 100 lần
- o3 chỉ tìm ra lỗ hổng xác thực Kerberos đã biết CVE-2025-37778 1 lần trong 100 lần, cho thấy hiệu năng giảm rõ rệt khi số token đầu vào tăng lên
- Trong cùng tập kết quả đó, một báo cáo về lỗ hổng mới chưa từng biết trước đó, CVE-2025-37899, đã được phát hiện
Đường đi lỗ hổng của CVE-2025-37899
- Lỗ hổng mới cũng liên quan đến việc giải phóng
sess->user, nhưng lần này xảy ra trong handler session logoff smb2_session_logoffhoạt động theo thứ tự sau- Gọi
ksmbd_close_session_fds(work) - Gọi
ksmbd_conn_wait_idle(conn) - Đặt trạng thái phiên thành
SMB2_SESSION_EXPIRED - Nếu có
sess->user, giải phóng bằngksmbd_free_user(sess->user)và đặtsess->user = NULL
- Gọi
- Kịch bản lỗ hổng trong báo cáo của o3 như sau
- Trong SMB 3.0 trở lên, transport thứ hai được bind vào phiên hiện có và
conn->binding == true - Worker-A xử lý một yêu cầu thông thường như WRITE trên kết nối khác C2
smb2_check_user_session()lưu con trỏstruct ksmbd_sessionhiện có vàowork->sessvà tăng bộ đếm tham chiếu của phiên, nhưng không giữ tham chiếu riêng chosess->user- Worker-B xử lý SMB2 LOGOFF cho cùng phiên trên kết nối đầu tiên C1 và thực thi
smb2_session_logoff() ksmbd_conn_wait_idle(conn)chỉ chờ các yêu cầu đang chạy trên kết nối đó, không chờ cả các yêu cầu trên kết nối khác dùng cùng phiên- Worker-A tiếp tục chạy và có thể thực hiện các truy cập như
user_guest(sess->user),ksmbd_compare_user(sess->user, …),sess->user->uid
- Trong SMB 3.0 trở lên, transport thứ hai được bind vào phiên hiện có và
- Tùy timing, đây có thể trở thành use-after-free trỏ tới đối tượng slab đã được giải phóng, hoặc nếu đọc sau khi
sess->user = NULLthì có thể trở thành dereference NULL gây DoS
Bản sửa sai và giá trị của kết quả o3
- Bản sửa ban đầu được đề xuất cho CVE-2025-37778 là thêm
sess->user = NULLsauksmbd_free_user(sess->user) - Sau khi đọc báo cáo CVE-2025-37899, rõ ràng bản sửa này là không đủ
- Handler
logoffvốn đã thực hiệnsess->user = NULL, nhưng giao thức SMB có thể bind hai kết nối khác nhau vào cùng một phiên, nên vẫn còn lỗ hổng - Trong luồng xác thực Kerberos cũng vậy, ở cửa sổ rất ngắn ngay sau khi
sess->userđược giải phóng và trước khi được đặt thành NULL, luồng khác có thể truy cập - Một số báo cáo của o3 mắc cùng lỗi, nhưng một số khác nhận ra rằng chỉ
sess->user = NULLlà chưa đủ do khả năng bind phiên - Một hạn chế là do tỷ lệ true positive so với false positive cao, không chắc liệu tác giả đã rà soát mọi báo cáo đủ kỹ hay chưa
Vị trí thực tiễn trong nghiên cứu lỗ hổng
- Xét về tính sáng tạo, linh hoạt và tổng quát, LLM nằm gần hơn với auditor mã nguồn là con người so với các kỹ thuật phân tích chương trình truyền thống
- Các đối tượng so sánh được nhắc tới gồm symbolic execution, abstract interpretation và fuzzing
- Sau GPT-4, LLM đã có tiềm năng trong nghiên cứu lỗ hổng, nhưng trong các vấn đề thực tế kết quả vẫn chưa đạt như kỳ vọng
- o3 hoạt động đủ tốt trong suy luận mã, hỏi đáp, lập trình và giải quyết vấn đề để có thể nâng hiệu suất của nhà nghiên cứu lỗ hổng thực tế
- Nó vẫn chưa hoàn hảo và rất có khả năng tạo ra kết quả vô nghĩa khiến người dùng nản lòng
- Điểm thay đổi là lần đầu tiên xác suất có câu trả lời đúng đã đủ cao để đáng áp dụng vào vấn đề thực tế
1 bình luận
Các ý kiến trên Hacker News
Chỉ là một chi tiết nhỏ, nhưng cách tác giả tổ chức dự án có vẻ hữu ích. Cách làm là tạo riêng các tệp
.promptcho system prompt, thông tin nền và chỉ dẫn bổ trợ [1], rồi chạy bằngllmNó cho thấy việc dùng LLM hiệu quả, giống như các công cụ kỹ thuật khác, cũng cần tư duy kỹ thuật có hệ thống, lấy đặc tả được cân nhắc kỹ làm trung tâm và cân bằng các ràng buộc thiết kế
[1] https://github.com/SeanHeelan/o3_finds_cve-2025-37899
Tất cả trông như những câu thần chú dựa vào cảm tính. Kiểu các câu như “Bạn là chuyên gia phát hiện lỗ hổng”, “Chỉ báo cáo lỗ hổng thực sự, không có false positive”, hoặc cách sắp xếp bằng các thẻ HTML giả vì có vẻ mô hình thích vậy. Tôi không rõ phần nào ở đây là kỹ thuật
Những prompt như vậy nên được gọi là gợi ý chứ không phải chỉ dẫn. Mọi LLM hiện nay đều sẽ phớt lờ prompt nếu prompt xung đột với mục tiêu cấp cao duy nhất của nó, tức là đưa ra câu trả lời, bất kể đúng hay sai
Nhờ LLM giúp viết prompt cũng hiệu quả đáng ngạc nhiên. Toàn bộ các mảnh prompt của tôi đều được thiết kế với sự hỗ trợ của LLM
Cá nhân tôi để tất cả trong các tệp org-mode rồi khi cần thì sao chép dán vào cuộc trò chuyện ChatGPT. Tôi thích kiểu tương tác “thảo luận” hơn, nhưng cách tiếp cận thì giống nhau
Bài viết nói tỷ lệ tín hiệu trên nhiễu xấp xỉ 1:50. Tác giả hiểu rất rõ codebase này nên ở vị thế tốt để lọc tín hiệu trong nhiễu
Thành quả thật sự sẽ đến từ việc tự động hóa phần này, nên tôi sẽ tiếp tục theo dõi
Mỗi khi có LLM frontier mới xuất hiện, tôi chạy các bài phỏng vấn đó, loại trừ những mô hình dùng input để huấn luyện. Tôi ngạc nhiên vì tỷ lệ câu trả lời chạy được ngay lần đầu vẫn đều đặn quanh mức 1:10, và nhiều khi phải gợi ý hơn 10 vòng mới khiến nó tự tìm ra lỗi của mình
Vì vậy với một chủ đề khó hiểu hơn, tỷ lệ tín hiệu trên nhiễu như thế này là hợp lý
Biên độ kết quả khá rộng, và tôi sẽ công bố tất cả trong một bài nói ở hội nghị sắp tới, nên có thể kỳ vọng. Nó sẽ cho thấy khá rõ tình trạng hiện tại của lĩnh vực này
Sửa: cách diễn đạt trước đó gây khó hiểu
Một LLM như vậy chẳng phải sẽ gần giống một phiên bản tổng hợp của người đã làm việc nhiều năm trên codebase và học được đủ loại đặc tính của nó sao
Có thể nhét thật nhiều thứ vào ngữ cảnh dài, nhưng với một số codebase, chỉ riêng code đã khoảng 200 nghìn token nên tôi cũng không chắc
Đặc biệt nếu dùng kiểu giải đấu nhị phân như RAInk từng được đăng ở đây vài tuần trước, và cũng có thể dùng phương pháp đồng thuận giữa các LLM khác nhau. Tôi ngạc nhiên là ở đây không dùng Gemini 2.5 PRO; theo kinh nghiệm của tôi, đó là LLM mạnh nhất cho loại tác vụ này
Phần thú vị và quan trọng nhất trong bài này là việc tác giả đã chạy tìm kiếm lỗ hổng 100 lần cho mỗi mô hình
Con số đó nhiều hơn rất nhiều so với lượng tính toán tôi từng định dùng cho hầu hết các vấn đề đã thử với mô hình ngôn ngữ lớn, nhưng có lẽ ta chỉ cần để mô hình chạy liên tục
Tôi không biết thế giới an ninh mạng sẽ ra sao khi chi phí suy luận gần như bằng 0, nhưng đó sẽ là một không gian rất khác so với ngày nay
Nó gần với việc tán dương sự xa xỉ và lãng phí hơn. Dù đang đối mặt với biến đổi khí hậu toàn cầu, chúng ta vẫn tiếp tục đốt tài nguyên vào những việc vụn vặt như thập niên 1950
Hoặc là rất may mắn, hoặc đúng như suy đoán, Gemini 2.5 PRO có vẻ tìm ra lỗ hổng này dễ hơn. Tỷ lệ thành công cao nên chỉ cần chạy prompt sau vài lần là đủ: https://gist.github.com/antirez/8b76cd9abf29f1902d46b2aed3cd...
Gần đây mẫu hình này cứ lặp lại
Nếu có một bài toán với định nghĩa rõ ràng và hàm đánh giá, hãy để LLM thu hẹp không gian nghiệm. LLM rất mạnh trong việc tái cấu trúc mẫu hình, và nếu lời giải có mẫu hình tương tự những gì đã được biết đến trước đó thì nó có thể hoạt động tốt
Trong trường hợp này, bài toán là một loại lỗ hổng bảo mật cụ thể, còn người đánh giá là chuyên gia. Quy mô khác nhau, nhưng về tinh thần thì tương tự các nỗ lực gần đây dùng LLM cho tối ưu hóa di truyền
“Mathematical discoveries from program search with large language models” cũng là một bài đáng đọc, và tôi nhớ là trước đây nó cũng từng được đăng lên HN
https://www.nature.com/articles/s41586-023-06924-6
Tuy nhiên, cá nhân tôi thấy hơi quá khi chỉ dựa vào thí nghiệm này để kết luận rằng LLM suy luận về mã
Tôi hy vọng chuyện này là thật, và không phải kiểu những gì cứ liên tục xảy ra với curl
[1] https://daniel.haxx.se/blog/2024/01/02/the-i-in-llm-stands-f...
Tôi không chắc về tuyên bố rằng đây là lỗ hổng đầu tiên được phát hiện bằng LLM. Ví dụ OSS-Fuzz [0] đã tìm ra vài lỗi bằng fuzzing, và Big Sleep cũng tìm được theo kiểu agent [1]
[0] https://security.googleblog.com/2024/11/leveling-up-fuzzing-...
[1] https://googleprojectzero.blogspot.com/2024/10/from-naptime-...
Điều bài viết nói là “để hiểu lỗ hổng này cần suy luận về các kết nối đồng thời tới máy chủ, và về cách nhiều đối tượng được chia sẻ trong những tình huống cụ thể. o3 đã hiểu điều đó, và tìm ra vị trí một đối tượng cụ thể không được đếm tham chiếu bị giải phóng trong khi vẫn còn có thể được truy cập từ luồng khác. Theo những gì tôi biết, đây là thảo luận công khai đầu tiên về việc LLM tìm ra một lỗ hổng có tính chất như vậy”
Điều tôi muốn nói là, theo tôi biết, đây là tài liệu công khai đầu tiên về việc LLM tìm ra loại lỗi như vậy: một lỗi phát sinh từ một lượng mã không hề nhỏ và truy cập đồng thời vào tài nguyên dùng chung. Ít nhất với tôi, đó là một dấu mốc thú vị trong sự phát triển của LLM
Xét đến giá trị của việc phát hiện zero-day, nếu có thể tìm ra chúng một cách ổn định chỉ bằng vài trăm lệnh gọi API, thì gần như mọi cơ quan tình báo trên thế giới sẽ đổ tiền vào đây
Đặc biệt là nếu có thể tinh chỉnh mô hình bằng nhiều ví dụ, và tôi không nghĩ những nơi như OpenAI sẽ cung cấp chuyện đó qua API công khai
Với các cơ quan chính phủ hoặc tổ chức khác thì những ràng buộc này đương nhiên không phải vấn đề. Chúng chỉ áp dụng cho tất cả những người còn lại. Vì vậy mọi người sẽ dùng các mô hình và agent khác không có những hạn chế này
Có thể an toàn mà giả định rằng còn rất nhiều lỗ hổng trong các phần mềm quan trọng. Giờ chúng ta đã có thể tìm ra chúng. Một tình huống nơi lý thuyết trò chơi chạy đua vũ trang được áp dụng vào bảo mật máy tính và hacking sẽ bắt đầu. Có lẽ nó sẽ đến sớm hơn dự đoán
Tôi hiểu là vài nhà phát triển kernel đã “xác minh” lỗi này, nhưng tôi tò mò liệu có ai thực sự tạo và kiểm thử bằng chứng khái niệm chưa
Đây là phần cốt lõi của quy trình mà bằng chứng khái niệm lại hoàn toàn vắng mặt. Không có bằng chứng khái niệm thì không thể biết ở giữa sẽ phát sinh vấn đề gì, và do đó không thể đánh giá khả năng khai thác hay tác động. Ít nhất tác giả đã không gọi nó là thực thi mã từ xa khi chưa xác minh
Nhưng nếu có một mảnh ghép nào đó mà tác giả và các nhà phát triển đã bỏ lỡ, hoặc giả định rằng o3 đã xử lý nhưng thực ra lại nằm ngoài ngữ cảnh của o3, và mảnh đó vô hiệu hóa chính lỗ hổng này thì sao?
Tôi không nói là có thứ như vậy, cũng không định bỏ thời gian làm thay việc của tác giả. Chỉ là báo cáo này chưa được xác minh hoàn toàn, và xét khả năng nó trở thành một bài blog có ảnh hưởng trong lĩnh vực nghiên cứu lỗ hổng bằng LLM về sau, tôi thấy đây như một tiền lệ nguy hiểm
Cá nhân tôi cho rằng với bất kỳ báo cáo lỗ hổng nào do mô hình tạo ra, cần áp dụng PoC || GTFO nghiêm ngặt hơn bao giờ hết
Quan điểm rằng o3 tốt hơn rất nhiều so với các mô hình trước đây hoặc các mô hình hiện hành khác vẫn còn nguyên, và phương pháp luận cũng thú vị. Tôi hiểu sự cám dỗ và nhu cầu muốn viết câu chữ như vậy để khiến mọi người chú ý đến một điểm cụ thể. Đây chính là vấn đề clickbait. Nhưng làm ơn hãy làm tốt hơn. Hãy tạo bằng chứng khái niệm và xác minh tuyên bố, đừng lười biếng. Nếu viết một bài blog có thể ảnh hưởng đến cách các nhà nghiên cứu lỗ hổng tiến hành nghiên cứu, thì nên khuyến khích xác minh chứ không phải giả định lý thuyết. Nếu không, thay vì đào sâu hiểu biết về hệ thống bằng các báo cáo có thể kiểm chứng và đã được chứng minh, các báo cáo sai nhưng nghe có vẻ hợp lý sẽ lan truyền sự thiếu hiểu biết
Có một đoạn nhỏ rất hay đã nắm bắt hoàn hảo cách mà hầu hết các phiên phát triển prompt của tôi diễn ra