Câu chuyện vô tình vấp phải lỗ hổng Debian weak keys
(hezmatt.org)- Năm 2008, trong lúc xử lý nút thắt SSH login của GitHub, một xung đột bất thường đã lộ ra: những người dùng khác nhau lại có cùng dấu vân tay khóa SSH
- Để tránh vấn đề tìm kiếm tuyến tính trong file
authorized_keysngày càng phình to, GitHub đã vá OpenSSH để tra cứu dấu vân tay khóa trong MySQL - Sau khi triển khai bản vá, đã xuất hiện sự cố truy cập kho lưu trữ của người dùng khác qua SSH, nhưng việc dấu vân tay khóa liên tục bị trùng lặp khiến khó có thể xem đây chỉ là lỗi vá thông thường
- Khi DSA-1571-1 được công bố ngày 13/5/2008, người ta xác nhận Debian OpenSSL đã tạo khóa riêng có thể dự đoán được trong khoảng 18 tháng, làm số lượng khóa khả dĩ cho mỗi người dùng giảm xuống chỉ còn hơn 32.000 một chút
- Những sự cố bảo mật lớn thường bắt đầu từ những tín hiệu nhỏ kiểu “có gì đó lạ”, và điều tạo ra khác biệt thực sự là thời gian và năng lực để lần theo manh mối đó đến cùng
Vụ việc bắt đầu từ nút thắt SSH login của GitHub
- Tháng 3/2008, tác giả khi đó làm việc tại Engine Yard đã được nhờ hỗ trợ vấn đề hiệu năng SSH login của GitHub, một khách hàng của công ty hosting tập trung vào Rails
- GitHub cung cấp quyền truy cập kho Git bằng xác thực khóa công khai sau khi kết nối SSH tới
git@github.com - Khi đó, việc quản lý khóa dựa trên cách phổ biến là file
~/.ssh/authorized_keys- Khi nhận yêu cầu xác thực bằng khóa công khai, SSH sẽ mở file
authorized_keysvà tìm kiếm tuyến tính mục khớp với khóa được gửi lên - Với tài khoản thông thường chỉ có vài khóa thì đây không phải vấn đề lớn, nhưng ở GitHub đang tăng trưởng nhanh, mọi khóa SSH đều dồn vào một file lớn, khiến thời gian đăng nhập chậm đi rõ rệt
- Khi nhận yêu cầu xác thực bằng khóa công khai, SSH sẽ mở file
Vá OpenSSH và tra cứu khóa bằng MySQL
- Sau khi xem xét nhiều cách giải quyết, nhóm GitHub và tác giả đã chọn vá OpenSSH để tra cứu khóa trong cơ sở dữ liệu MySQL dựa trên dấu vân tay khóa
- Đây không phải quyết định có thể đưa ra một cách nhẹ nhàng
- Việc chỉnh sửa OpenSSH nếu làm sai có thể gây hậu quả nghiêm trọng về bảo mật
- Nhưng các lựa chọn khác còn tệ hơn, nên đây được xem là phương án “ít tệ nhất”
- Phần lớn công việc thay đổi dành cho việc xác minh rằng bảo mật không bị suy giảm
- Sau khi triển khai vào đầu tháng 4/2008, SSH login đã nhanh hơn và có vẻ trong một thời gian sẽ không phải lo lại vấn đề này
Triệu chứng tưởng như không thể: dấu vân tay khóa bị trùng
- Đầu tháng 5/2008, nhóm GitHub nhận được báo cáo rằng một số người dùng có thể truy cập kho lưu trữ của người khác qua SSH
- Vì vấn đề liên quan trực tiếp tới xác thực khóa SSH và bản vá OpenSSH vừa mới được triển khai trước đó, đoạn mã do tác giả viết trở thành nghi phạm hàng đầu
- Sau khi gỡ lỗi, người ta xác nhận hai người dùng khác nhau lại có cùng dấu vân tay khóa
- Nếu họ không chủ động chia sẻ khóa với nhau thì điều này gần như không thể xảy ra
- Những người dùng bị ảnh hưởng không quen biết nhau và cũng nói rằng họ chưa từng công khai khóa của mình
- Sau đó, ở một cặp người dùng khác lại phát hiện cùng dấu vân tay khóa, và dấu vân tay này khác với trường hợp trước
- Lúc này rất khó quy cho một sự trùng hợp ngẫu nhiên đơn lẻ hay lỗi của ứng dụng web
- Sau khi đã xác nhận đầy đủ rằng nguyên nhân không nằm ở bản vá OpenSSH, mức độ tham gia trực tiếp của tác giả giảm xuống
- Tác giả không phải nhân viên GitHub và còn phải hỗ trợ các khách hàng khác của Engine Yard
- Nhóm GitHub tiếp tục xác minh với người dùng và nhận ra điểm chung là họ đã tạo khóa SSH trên hệ Debian hoặc Ubuntu
Lỗ hổng Debian OpenSSL được công bố và nguyên nhân lộ diện
- Đến ngày 13/5/2008, khi DSA-1571-1 được công bố, tình hình trở nên rõ ràng
- Gói OpenSSL của Debian đã tạo ra khóa riêng có thể dự đoán được trong suốt khoảng 18 tháng
- Nguyên nhân là trong quá trình dọn dẹp mã sinh số ngẫu nhiên của OpenSSL, một maintainer Debian đã vô tình làm thu hẹp mạnh không gian khóa có thể sinh ra
- Số khóa khả dĩ mà một người dùng cụ thể có thể tạo ra bị giảm từ “một con số khổng lồ” xuống chỉ còn hơn 32.000 một chút
- Khi nhiều người dùng đăng ký GitHub, một số có thể đã tạo khóa mới theo thực hành được khuyến nghị, và vì thế xung đột đã có thể xảy ra
- Công bố này mang lại bằng chứng mang tính quyết định rằng bản vá OpenSSH của tác giả không phải nguyên nhân
Những công việc sau đó liên quan đến Debian weak keys
- Về sau, tác giả còn có thêm nhiều điểm giao cắt với Debian weak keys
- Anh vận hành pwnedkeys.com, nơi xử lý kho lưu trữ quy mô lớn các khóa đã biết là bị xâm hại
- Anh cũng dùng những khóa này để tìm các Certificate Authority hoạt động sai
Khác biệt được tạo ra từ thời gian để theo đuổi điều “lạ lùng”
- Tác giả không tìm ra chính xác Luciano Bello đã phát hiện lỗ hổng sau này mang mã CVE-2008-0166 vào lúc nào và bằng cách nào
- Vì bản phát hành stable của Debian có chứa đoạn mã dễ tổn thương đã ra mắt trước khi công bố tới 1 năm, có thể đã tồn tại khoảng thời gian để nhìn thấy việc khóa bị trùng, cảm thấy “có gì đó lạ”, rồi đào sâu hơn
- Gần đây, vụ backdoor XZ cũng là một trường hợp bị phanh phui nhờ những quan sát “có gì đó lạ” và cuộc điều tra tập trung sau đó
- Điều quan trọng là phải thật sự có khả năng và thời gian để tiến hành kiểu điều tra tập trung như vậy
- Khi đó, tác giả đã không thể tự mình điều tra sâu hơn
- Nhóm GitHub cũng bận phát triển tính năng và xử lý sự cố cho một dịch vụ đang tăng trưởng rất nhanh
- Bản thân tác giả cũng đang xử lý các ticket hỗ trợ tại Engine Yard
- Khác biệt lớn được tạo ra khi, đúng vào thời điểm thích hợp, có người sở hữu kỹ năng, thời gian và năng lượng để lần theo manh mối đến cùng
1 bình luận
Ý kiến trên Hacker News
Về đoạn “không tìm được chính xác Luciano Bello đã phát hiện lỗ hổng sau này trở thành CVE-2008-0166 khi nào và như thế nào”, log IRC thời đó có ghi như sau
17:23 < luciano> has really an accident. I was needing many primes numbers... 0:-)17:23 < Sesse> and you got the same numbers every time?17:25 < luciano> Sesse, not every time :PCâu “ngành này đã may mắn khi có đúng người với kỹ năng, thời gian và năng lượng phù hợp ở đúng thời điểm” là chỗ khiến người ta cảm nhận rõ thống kê về nhiều con mắt và “ánh nắng là chất khử trùng tốt nhất”
Dù việc ai đó tình cờ đi ngang qua rồi phát hiện bug có vẻ hiếm đến đâu, vì nó có thể xảy ra nên thực tế nó đã xảy ra
Với mã độc quyền/đóng, xác suất đó gần như bằng 0
Ai đó đã nhận ra điểm bất thường, và nhờ có mã nguồn cùng tình huống thực tế, họ có thể xác nhận rằng đã có điều đáng ngờ
Họ liên hệ với các chuyên gia bảo mật của những bản phân phối lớn để được xem xét thêm, và những người này cũng xác nhận vấn đề bảo mật rồi có thể phản ứng ngay lập tức
Sau khi công khai, những người có chuyên môn trong nhiều mảng phần mềm và bảo mật có thể đào sâu xem chuyện gì đã được thực hiện, thực hiện như thế nào, và rủi ro là gì
Các commit đáng ngờ mà cùng nhà phát triển đó để lại trong phần mềm khác cũng đã được truy vết và xác nhận, và việc phân tích tác động vẫn đang tiếp diễn
Mỗi bản phân phối trở nên nhạy cảm hơn với các chi tiết về cách việc xâm hại xảy ra quanh kho lưu trữ bản build, và bắt đầu tìm cách phát hiện, ngăn chặn những trường hợp tương tự trong tương lai
So với mã nguồn đóng, nhiều khả năng các báo cáo kiểu “phần mềm hơi chậm” gần như sẽ không được chú ý cho đến khi có khai thác thực tế
Ngay cả nếu công ty cuối cùng cũng phát hiện ra, có lẽ chỉ có một lời giải thích rất thận trọng, tiết lộ lượng thông tin tối thiểu; điều này gây tổn hại lớn đến khả năng của toàn ngành trong việc tránh lặp lại
Tuy nhiên, khả năng cao là người ta không thể sửa vấn đề, hoặc không có hành động nào
Hầu hết mọi người khi phát hiện bug cũng không biết phải làm gì. Tôi hồi rất lâu trước cũng vậy, mãi về sau mới nhận ra những thứ mình từng thấy là bug
Chi tiết đã mờ nhạt vì gần 30 năm trước, nhưng tôi nhớ từng nghịch Microsoft NetMeeting trên Windows và có thể làm nó crash bằng lỗi buffer overrun
Khi đó tôi còn là người mới dùng máy tính, và không hiểu rằng buffer overflow trong ứng dụng mạng là chuyện rất tệ. Có vẻ nhiều người đã ở lâu trong ngành lúc ấy cũng vậy
Thời đó việc báo cáo vấn đề bảo mật cũng khó hơn nhiều, thậm chí trong một số trường hợp còn nguy hiểm
Rốt cuộc cần nhiều thứ: gặp phải vấn đề, hiểu đủ sâu về máy tính để nhận ra vấn đề đó là xấu, có phương tiện báo cáo bug ở nơi mọi người sẽ xem xét, và một văn hóa bảo mật biết khi nào và xử lý báo cáo như thế nào
Nhưng khi đọc cùng câu đó, điều tôi thắc mắc là có bao nhiêu bug bảo mật nghiêm trọng như Heartbleed, CVE-2008-0166, vụ xz đang xảy ra mà chưa được phát hiện hoặc công khai
Một sự thật quan trọng mà gần đây tôi mới biết về lỗ hổng này là thay đổi đó không phải là việc làm vội vàng
Người bảo trì đã đăng vấn đề mình thấy lên mailing list của OpenSSL, yêu cầu phản hồi và đề xuất bản sửa, và cũng nhận được một số câu trả lời, bao gồm từ upstream
Kết quả là một lỗ hổng khủng khiếp, nhưng có vẻ gần với vận rủi cực kỳ tệ khi tất cả mọi người đều bỏ sót vấn đề hơn
Hơn nữa, mã OpenSSL upstream đang gọi đến hành vi không xác định. Vì vậy, nếu trình biên dịch thực hiện đúng phép biến đổi giống hệt điều người bảo trì Debian đã làm thì cũng có thể vẫn hợp lệ
Lúc ấy điều này nghe có vẻ như chuyện học thuật. Tôi nghĩ chắc trình biên dịch không thể cư xử ác như vậy được
Về sau, mọi người hiểu rõ hơn rằng nên tránh hoàn toàn hành vi không xác định
Và 8 năm sau, khi Heartbleed được phát hiện, tất cả bỗng nhận ra OpenSSL đã được bảo trì tệ đến mức nào
Để bênh vực thì đó gần như là công việc dựa vào tình nguyện, và may là sau đó nhờ có tài trợ, tình hình đã cải thiện
Với mã bộ sinh số ngẫu nhiên quan trọng về bảo mật, có vẻ thật sự cần một bài test tạo ra lượng số ngẫu nhiên khổng lồ rồi kiểm chứng rằng tất cả đều là duy nhất
Đọc những chuyện thế này làm tôi tự hỏi xác suất chuyện tương tự đã xảy ra, hoặc sẽ xảy ra trong tương lai, ở hàm tạo seed của một trong các ví phần cứng Bitcoin phổ biến là bao nhiêu
Và cũng tò mò hậu quả của nó sẽ như thế nào
Trong 22 tháng qua, Unciphered đã xử lý một lỗ hổng ảnh hưởng đến BitcoinJS, thư viện được dùng rộng rãi để tạo ví tiền mã hóa trên trình duyệt, cũng như các sản phẩm và dự án được tạo bằng phần mềm này
Qua nhiều năm, lỗ hổng này đã khiến một lượng đáng kể ví tiền mã hóa dễ bị tấn công được tạo ra
Vì với lỗ hổng SSH, bạn phải chủ động kiểm tra xem máy chủ mình định truy cập có một trong các fingerprint xấu hay không, còn phía ví thì có thể tự động truy cập tiền của người khác trên mạng
Tuy nhiên trường hợp đó ít có khả năng là được đưa vào một cách cố ý
Với công nghệ hiện nay có thể cần hàng triệu năm tính toán, nhưng với một tác nhân cấp quốc gia có thể bỏ ra gần như vô hạn tiền để chạy lượng tính toán đó trong vài tuần, thì có thể không nằm ngoài khả năng
Rốt cuộc có thể sẽ đến lúc bất kỳ ai biết địa chỉ cũng truy cập được mọi ví
Nếu bạn có thể trở thành mục tiêu của ai đó có trí tuệ và tiền bạc, Bitcoin không thật sự an toàn lắm để lưu trữ giá trị
Câu “Ezra Zygmuntowitz đã kết nối tôi với GitHub, và cho tôi thời gian để đào sâu vào vấn đề cùng đội GitHub” nghe buồn cười
Có lẽ vì tôi không phải người bản ngữ, nên cũng có thể đọc thành ý rằng bản thân đội GitHub có vấn đề lớn, và tôi đã tưởng các câu sau sẽ đào sâu vào chuyện đó
Đoạn “tôi tự hỏi nếu Luciano không phát hiện ra thì phải mất bao lâu nó mới được phát hiện” thì có lẽ chỉ GitHub hoặc một nhà cung cấp cloud lớn nào đó mới tình cờ gặp phải
Vì không có nhiều nơi lưu trữ hàng nghìn, hàng chục nghìn khóa người dùng
Vấn đề là nên đọc câu thành
(đào sâu vào vấn đề) (cùng đội GitHub)hay(đào sâu vào vấn đề liên quan đến đội GitHub)Việc xử lý đúng điều này được biết là khá khó
Theo tôi hiểu thì bộ sinh số ngẫu nhiên của OpenSSL được seed bằng bộ nhớ stack chưa khởi tạo và PID, còn Debian đã khiến nó chỉ seed bằng PID
Nhưng ngay cả khi không có bản vá Debian thì chẳng phải nó vốn đã khá nguy hiểm rồi sao?
Trong mã OpenSSL có hai chỗ sao chép các khối byte, và một trong số đó có thể sao chép giá trị rác chưa được khởi tạo. Đúng là việc đó sai
Ai đó đã viết một bản vá để sửa điều này, và sau đó, không cần sự trợ giúp của LLM mà chỉ bằng sự bất tài thuần túy của con người, có người nói “gần đó còn một đoạn sao chép tương tự nữa, nên cũng phải bỏ nó đi”
Debian đã đưa vào một bản vá áp dụng cả hai thay đổi
Kết quả là OpenSSL giờ không còn sao chép byte nào nữa
Không sao chép dữ liệu chưa khởi tạo thì tốt, nhưng cũng không sao chép cả entropy ngẫu nhiên thật vào pool nữa. Ôi trời
Ở đoạn “sau khi xem xét nhiều giải pháp khả dĩ, chúng tôi kết luận lựa chọn ít tệ nhất là vá OpenSSH để tra cứu khóa trong cơ sở dữ liệu MySQL được lập chỉ mục theo fingerprint của khóa”, tại sao lại là MySQL chứ không phải sqlite?
Bối cảnh là muốn tăng tốc truy cập ~/.ssh/authorized_keys, mà đây đúng là tình huống MySQL được thiết kế để tỏa sáng
Có vẻ vá OpenSSH để kiểm tra ~/.ssh/authorized_keys.db sẽ ít việc hơn so với vá để dùng MySQL
Khả năng cao là MySQL đã đang chạy sẵn. Khi đó cũng không có chi phí ban đầu để lưu dữ liệu vào đó
Dù sao thì cơ sở dữ liệu người dùng hẳn đã tồn tại ở đâu đó rồi
Dù tách biệt với việc phát hiện một số ít khóa yếu, điều thú vị là thời gian đăng nhập SSH chậm lại là một manh mối đáng kéo thử vì nhiều lý do
Một giai thoại thú vị khác là trường hợp dùng ước chung lớn nhất để phát hiện các khóa RSA có chung thừa số
phoặcq: https://factorable.net/weakkeys12.extended.pdfTò mò không biết GitHub hiện vẫn đang chạy openssh đã vá hay không
Chỉ cần mua một bản GitHub Enterprise, gỡ làm rối file rồi xem qua. Việc gỡ làm rối là một thử thách thú vị và cũng không quá khó
Đáng tiếc là nó không phải mã nguồn mở nên không thể chia sẻ, bàn luận về mã, hay liên kết lên GitHub
Nhưng nếu GitHub Enterprise vẫn dùng bản vá như vậy, thì khả năng cao GitHub vận hành thực tế cũng vậy
~/.ssh/authorized_keysThử telnet vào cổng 22 của
github.comthì chuỗi phiên bản sẽ được in ra ngaySửa lại, ban đầu tôi nói là golang nhưng kiểm tra lại thì bên dùng golang là Bitbucket