Bản phân phối hệ điều hành nguồn mở OpenBSD nổi tiếng trong số các quản trị viên hệ thống, đặc biệt là những người quản lý máy chủ, vì nó tập trung vào bảo mật về tốc độ, tính năng và giao diện người dùng ưa thích.
Có lẽ, phù hợp nhất là logo của nó là một con cá nóc – căng phồng, với những chiếc gai sẵn sàng đẩy lùi bất kỳ tin tặc quỷ quyệt nào có thể xuất hiện.
Nhưng nhóm OpenBSD có lẽ được biết đến nhiều nhất không phải vì toàn bộ bản phân phối của nó, mà vì bộ công cụ truy cập từ xa OpenSSH được viết vào cuối những năm 1990 để đưa vào chính hệ điều hành.
SSH, viết tắt của vỏ an toàn, ban đầu được tạo ra bởi nhà khoa học máy tính Phần Lan Tatu Ylönen vào giữa những năm 1990 với hy vọng cai quản các hệ thống quản trị khỏi thói quen rủi ro khi sử dụng giao thức Telnet.
Rắc rối với Telnet
Telnet cực kỳ đơn giản và hiệu quả: thay vì kết nối dây vật lý (hoặc sử dụng modem qua đường dây điện thoại) để tạo kết nối teletype đến các máy chủ từ xa, thay vào đó, bạn đã sử dụng kết nối TELetype NETwork.
Về cơ bản, dữ liệu thường chảy qua lại qua kết nối nối tiếp chuyên dụng hoặc đường dây điện thoại quay số được gửi và nhận qua internet, sử dụng kết nối mạng TCP chuyển mạch gói thay vì liên kết điểm-điểm chuyển mạch kênh. .
Cùng một hệ thống đăng nhập quen thuộc, kết nối rẻ hơn, không cần đường dữ liệu chuyên dụng!
Tất nhiên, lỗ hổng lớn trong Telnet là nó hoàn toàn thiếu mã hóa, vì vậy việc phát hiện ra phiên cuối cùng chính xác của bạn là chuyện nhỏ, cho phép những kẻ bẻ khóa nhìn thấy mọi lệnh bạn đã nhập (ngay cả những lỗi bạn mắc phải và tất cả những lần bạn nhấn [Backspace]
) và mỗi byte đầu ra được tạo ra…
…và, tất nhiên, tên người dùng và mật khẩu của bạn khi bắt đầu phiên.
Bất kỳ ai trên đường dẫn mạng của bạn không chỉ có thể dễ dàng tái tạo lại các phiên quản trị hệ thống của bạn trong thời gian thực trên màn hình của chính họ mà còn có thể can thiệp vào phiên của bạn bằng cách sửa đổi các lệnh bạn đã gửi đến máy chủ từ xa và giả mạo các câu trả lời quay lại để bạn không nhận thấy sự khuất phục.
Họ thậm chí có thể thiết lập một máy chủ giả mạo, dụ bạn vào đó và khiến bạn khó phát hiện ra sự lừa dối một cách đáng kinh ngạc.
Mã hóa mạnh FTW
SSH của Ylönen nhằm mục đích thêm một lớp mã hóa và xác thực mạnh vào mỗi đầu của phiên giống như Telnet, tạo ra một vỏ an toàn (đó là ý nghĩa của cái tên, nếu bạn đã từng thắc mắc, mặc dù hầu hết mọi người chỉ gọi nó là ess-ess-aitch những ngày này).
Đó là một thành công ngay lập tức và giao thức này nhanh chóng được các quản trị viên hệ thống ở khắp mọi nơi áp dụng.
OpenSSH ngay sau đó, như chúng tôi đã đề cập ở trên, xuất hiện lần đầu tiên vào cuối năm 1999 như một phần của MởBSD 2.6 phát hành.
Nhóm OpenBSD muốn tạo ra một triển khai mã nguồn mở, miễn phí, đáng tin cậy của giao thức mà họ và bất cứ ai khác có thể sử dụng, không có bất kỳ sự phức tạp nào về cấp phép hoặc thương mại đã cản trở quá trình triển khai ban đầu của Ylönen trong những năm ngay sau khi phát hành.
Thật vậy, nếu bạn chạy máy chủ Windows SSH và kết nối với nó từ máy tính Linux ngay bây giờ, thì gần như chắc chắn bạn sẽ dựa vào việc triển khai OpenSSH ở cả hai đầu.
Giao thức SSH cũng được sử dụng trong các dịch vụ máy khách-máy chủ phổ biến khác bao gồm SCP và SFTP, viết tắt của bản sao an toàn và FTP an toàn tương ứng. SSH có nghĩa một cách lỏng lẻo, “kết nối an toàn và chạy lệnh Shell ở đầu bên kia”, thường dành cho các lần đăng nhập tương tác, bởi vì chương trình Unix cho lệnh shell thường là /bin/sh
. SCP cũng tương tự, nhưng đối với các tệp CoPying, vì lệnh sao chép tệp Unix thường được gọi là /bin/cp
và SFTP được đặt tên theo cùng một cách.
OpenSSH không phải là bộ công cụ SSH duy nhất trong thị trấn.
triển khai nổi tiếng khác bao gồm: libssh2, dành cho các nhà phát triển muốn xây dựng hỗ trợ SSH ngay trong các ứng dụng của riêng họ; dropbear, một máy chủ SSH rút gọn từ lập trình viên Úc matt johnston được tìm thấy rộng rãi trên cái gọi là thiết bị IoT (Internet of Things) chẳng hạn như bộ định tuyến gia đình và máy in; Và PuTTY, một bộ sưu tập phổ biến, miễn phí các công cụ liên quan đến SSH dành cho Windows từ nhà phát triển nguồn mở độc lập Simon Tatham ở Anh.
Nhưng nếu bạn là người dùng SSH thông thường, thì gần như chắc chắn bạn đã kết nối với ít nhất một máy chủ OpenSSH hiện nay, đặc biệt là vì hầu hết các bản phân phối Linux hiện đại đều bao gồm nó làm công cụ truy cập từ xa tiêu chuẩn của họ và Microsoft cung cấp cả ứng dụng khách OpenSSH và OpenSSH máy chủ như các thành phần chính thức của Windows ngày nay.
Sửa lỗi miễn phí kép
OpenSSH phiên bản 9.2 vừa ra mắt, và ghi chú phát hành báo cáo như sau:
Bản phát hành này chứa các bản sửa lỗi cho […] sự cố an toàn bộ nhớ. [Lỗi này] được cho là không thể khai thác được, nhưng chúng tôi báo cáo hầu hết các lỗi bộ nhớ có thể truy cập mạng là lỗi bảo mật.
Lỗi ảnh hưởng sshd
, máy chủ OpenSSH (máy chủ -d
hậu tố là viết tắt của daemon, tên Unix cho loại tiến trình nền mà Windows gọi là dịch vụ):
sshd(8): sửa lỗi bộ nhớ trống kép trước khi xác thực được giới thiệu trong OpenSSH 9.1. Điều này được cho là không thể khai thác được và nó xảy ra trong quy trình xác thực trước không có đặc quyền tuân theo chroot(2) và được thêm vào hộp cát trên hầu hết các nền tảng chính.
Một lỗi kép không có nghĩa là một khối bộ nhớ mà bạn đã trả lại cho hệ điều hành sẽ được sử dụng lại trong các phần khác của chương trình của bạn…
…sau đó sẽ được trả lại bởi một phần của chương trình không còn thực sự “sở hữu” bộ nhớ đó nữa, nhưng không biết rằng nó không có.
(Hoặc cố tình trả lại khi nhắc mã đang cố tình kích động lỗi để biến một dễ bị tổn thương vào một khai thác.)
Điều này có thể dẫn đến các lỗi tinh vi và khó giải quyết, đặc biệt nếu hệ thống đánh dấu khối đã giải phóng là khả dụng khi lần đầu tiên free()
xảy ra, sau đó phân bổ nó cho một phần khác của mã của bạn khi nó yêu cầu bộ nhớ thông qua malloc(
), và sau đó đánh dấu khối miễn phí một lần nữa khi lệnh gọi không cần thiết đến free()
xuất hiện.
Điều đó khiến bạn rơi vào tình huống mà bạn gặp phải khi nhận phòng khách sạn và nói: “Ồ, tin tốt đây! Chúng tôi nghĩ rằng chúng tôi đã kín chỗ, nhưng một vị khách khác vừa quyết định trả phòng sớm, vì vậy bạn có thể nhận phòng của họ.”
Ngay cả khi căn phòng được dọn dẹp gọn gàng và chuẩn bị sẵn sàng cho những người mới đến khi bạn bước vào, và do đó có vẻ như nó được phân bổ hợp lý cho mục đích sử dụng riêng của bạn, bạn vẫn phải tin rằng thẻ khóa của khách trước đó thực sự đã được hủy chính xác và rằng “ thanh toán sớm” không phải là một mưu mẹo xảo quyệt để lẻn về sau cùng ngày và đánh cắp máy tính xách tay của bạn.
Sửa lỗi để sửa lỗi
Trớ trêu thay, nếu bạn nhìn vào lịch sử mã OpenSSH gần đây, bạn sẽ thấy rằng OpenSSH có một lỗi nhỏ trong một chức năng gọi là compat_kex_proposal()
, được sử dụng để kiểm tra loại thuật toán trao đổi khóa sẽ sử dụng khi thiết lập kết nối.
Nhưng thay vào đó, việc sửa lỗi khiêm tốn đó lại dẫn đến một lỗ hổng nghiêm trọng hơn.
Nhân tiện, sự hiện diện của lỗi trong một phần của phần mềm được sử dụng trong quá trình thiết lập kết nối chính là nguyên nhân khiến lỗi này được gọi là xác thực trước có thể truy cập mạng lỗ hổng (hoặc lỗi xác thực trước viết tắt).
Lỗi double-free xảy ra trong mã cần chạy sau khi một khách hàng đã bắt đầu một phiên làm việc từ xa, nhưng trước bất kỳ thỏa thuận khóa hoặc xác thực nào đã diễn ra, do đó, về mặt lý thuyết, lỗ hổng bảo mật có thể được kích hoạt trước khi bất kỳ mật khẩu hoặc khóa mật mã nào được đưa ra để xác thực.
Trong OpenSSH 9.0, compat_kex_proposal
trông giống như thế này (được đơn giản hóa rất nhiều ở đây):
char* compat_kex_proposal(char* suggestion) { if (condition1) { return suggestion; } if (condition2) { suggestion = allocatenewstring1(); } if (condition3) { suggestion = allocatenewstring2(); } if (isblank(suggestion)) { error(); } return suggestion; }
Ý tưởng là người gọi chuyển vào khối bộ nhớ của riêng họ có chứa chuỗi văn bản đề xuất cài đặt trao đổi khóa và nhận lại sự chấp thuận để sử dụng chính đề xuất mà họ đã gửi hoặc chuỗi văn bản mới được phân bổ có đề xuất được cập nhật .
Lỗi là nếu điều kiện 1 sai nhưng điều kiện 2 và 3 đều đúng, thì mã sẽ phân bổ hai chuỗi văn bản mới, nhưng chỉ trả về một.
Khối bộ nhớ được cấp phát bởi allocatenewstring1()
không bao giờ được giải phóng và khi hàm trả về, địa chỉ bộ nhớ của nó sẽ bị mất vĩnh viễn, vì vậy không có cách nào để bất kỳ mã nào free()
nó trong tương lai.
Khối đó về cơ bản bị bỏ rơi, gây ra cái gọi là bộ nhớ bị rò rỉ.
Theo thời gian, điều này có thể gây ra sự cố, thậm chí có thể buộc máy chủ phải tắt để phục hồi do quá tải bộ nhớ.
Trong OpenSSH 9.1, mã đã được cập nhật nhằm cố gắng tránh phân bổ hai chuỗi mà bỏ qua một trong số chúng:
/* Always returns pointer to allocated memory, caller must free. */ char* compat_kex_proposal(char* suggestion){ char* previousone = NULL; if (condition1) { return newcopyof(suggestion); } if (condition2) { suggestion = allocatenewstring1(); } if (condition3) { previousone = suggestion; suggestion = allocatenewstring2(); } free(previousone); } if (isblank(suggestion()) { error(); } return suggestion; }
Điều này có lỗi double-free, bởi vì nếu điều kiện 1 và điều kiện 2 đều sai, nhưng điều kiện 3 là đúng, thì mã sẽ phân bổ một chuỗi mới để gửi lại làm câu trả lời của nó…
…nhưng giải phóng không chính xác chuỗi mà người gọi ban đầu đã truyền vào, bởi vì hàm allocatenewstring1()
không bao giờ được gọi để cập nhật biến suggestion
.
Chuỗi đề xuất được truyền vào là bộ nhớ thuộc về người gọivà do đó, người gọi sẽ giải phóng bản thân chủ đề sau này, dẫn đến mối nguy hiểm kép.
Trong OpenSSH 9.2, mã đã trở nên thận trọng hơn, theo dõi cả ba khối bộ nhớ có thể được sử dụng: khối gốc suggestion
(bộ nhớ thuộc sở hữu của người khác) và hai chuỗi mới có thể được phân bổ trên đường:
/* Always returns pointer to allocated memory, caller must free. */ char* compat_kex_proposal(char* suggestion) { char* newone = NULL; char* newtwo = NULL; if (condition1) { return newcopyof(suggestion); } if (condition2) { newone = allocatenewstring1(); } if (condition3) { newtwo = allocatenewstring2(); } free(newone); newone = newtwo; } if (isblank(newone)) { error(); } return newone; }
Nếu điều kiện 1 là đúng, một bản sao mới của chuỗi đã truyền vào sẽ được sử dụng, vì vậy người gọi có thể sau đó free()
bộ nhớ của chuỗi truyền vào của họ bất cứ khi nào họ muốn.
Nếu chúng ta vượt qua điều kiện 1 và điều kiện 2 là đúng nhưng điều kiện 3 là sai, thì gợi ý thay thế được tạo bởi allocatenewstring1()
được trả lại và thông qua suggestion
chuỗi được để lại một mình.
Nếu điều kiện 2 là sai và điều kiện 3 là đúng, thì một chuỗi mới sẽ được tạo và trả về, đồng thời chuyển vào suggestion
chuỗi được để lại một mình.
Nếu cả điều kiện 2 và điều kiện 3 đều đúng, thì hai chuỗi mới sẽ được phân bổ trên đường đi; cái đầu tiên được giải phóng vì nó không cần thiết; cái thứ hai được trả lại; và thông qua suggestion
chuỗi được để lại một mình.
Bạn có thể RTxM để xác nhận rằng nếu bạn gọi free(newone)
khi nào newone
is NULL
, thì "không có thao tác nào được thực hiện", bởi vì nó luôn an toàn để free(NULL)
. Tuy nhiên, nhiều lập trình viên vẫn bảo vệ mạnh mẽ chống lại nó bằng mã như if (ptr != NULL) { free(ptr); }
.
Phải làm gì?
Như nhóm OpenSSH gợi ý, việc khai thác lỗi này sẽ khó khăn, đặc biệt là do các đặc quyền hạn chế mà sshd
chương trình có trong khi thiết lập kết nối để sử dụng.
Tuy nhiên, họ đã báo cáo đó là một lỗ hổng bảo mật vì đó là bản chất của nó, vì vậy hãy đảm bảo rằng bạn đã cập nhật lên OpenSSH 9.2.
Và nếu bạn đang viết mã bằng C, hãy nhớ rằng dù bạn có kinh nghiệm đến đâu, việc quản lý bộ nhớ rất dễ mắc lỗi…
…vì vậy hãy cẩn thận khi ở ngoài đó.
(Vâng, Rust và những người bạn hiện đại của nó sẽ giúp bạn viết mã chính xác, nhưng đôi khi bạn vẫn cần sử dụng C và thậm chí Rust không thể đảm bảo ngăn bạn viết mã sai nếu bạn lập trình một cách thiếu thận trọng!)
- Phân phối nội dung và PR được hỗ trợ bởi SEO. Được khuếch đại ngay hôm nay.
- Platoblockchain. Web3 Metaverse Intelligence. Khuếch đại kiến thức. Truy cập Tại đây.
- nguồn: https://nakedsecurity.sophos.com/2023/02/03/openssh-fixes-double-free-memory-bug-thats-pokable-over-the-network/
- 1
- 1999
- 9
- a
- ở trên
- Tuyệt đối
- truy cập
- thực sự
- địa chỉ
- con nuôi
- Sau
- chống lại
- thuật toán
- Tất cả
- phân bổ
- cấp phát
- Cho phép
- cô đơn
- Đã
- thay thế
- Mặc dù
- luôn luôn
- giữa
- và
- Một
- các ứng dụng
- phê duyệt
- Úc
- Xác thực
- tác giả
- tự động
- có sẵn
- tránh
- trở lại
- lý lịch
- background-image
- bởi vì
- trở nên
- trước
- tin
- BEST
- Chặn
- Khối
- biên giới
- đáy
- Bug
- lỗi
- xây dựng
- cuộc gọi
- gọi là
- Caller
- Cuộc gọi
- mà
- Nguyên nhân
- gây ra
- dè dặt
- Trung tâm
- chắc chắn
- rẻ hơn
- kiểm tra
- khách hàng
- mã
- lập trình viên
- bộ sưu tập
- màu sắc
- COM
- Đến
- đến
- thương gia
- các thành phần
- máy tính
- điều kiện
- điều kiện
- Xác nhận
- Kết nối
- kết nối
- Kết nối
- liên quan
- Kết nối
- chứa
- hiện đại
- sao chép
- có thể
- khóa học mơ ước
- che
- tạo
- tạo ra
- Tạo
- mật mã
- NGUY HIỂM
- dữ liệu
- ngày
- Ngày
- quyết định
- dành riêng
- Nhà phát triển
- phát triển
- Thiết bị (Devices)
- ĐÃ LÀM
- Die
- khó khăn
- Giao diện
- phân phối
- Phân phối
- Không
- không có đôi
- xuống
- suốt trong
- mỗi
- Đầu
- dễ dàng
- Hiệu quả
- hay
- mã hóa
- kết thúc
- Nước Anh
- Toàn bộ
- đặc biệt
- chủ yếu
- Ngay cả
- BAO GIỜ
- Mỗi
- mọi người
- Dành riêng
- kinh nghiệm
- kinh nghiệm
- quen
- Tính năng
- Các tập tin
- Tên
- Cá
- Sửa chữa
- lỗ hổng
- dòng chảy
- Tập trung
- sau
- sau
- mãi mãi
- tìm thấy
- Miễn phí
- bạn bè
- từ
- Full
- chức năng
- xa hơn
- tương lai
- nói chung
- tạo ra
- được
- khổng lồ
- Go
- tốt
- rất nhiều
- Bảo hành
- Lực lượng Cảnh sát
- Khách
- tin tặc
- xảy ra
- Cứng
- cao
- tại đây
- lịch sử
- Đánh
- Lô
- Trang Chủ
- mong
- khách sạn
- di chuột
- Độ đáng tin của
- HTML
- HTTPS
- ý tưởng
- ngay
- thực hiện
- in
- Mặt khác
- bao gồm
- Bao gồm
- đưa vào
- không chính xác
- indie
- ngay lập tức
- thay vì
- tương tác
- Internet
- Internet của sự vật
- giới thiệu
- iốt
- Iot (internet vạn vật)
- IT
- chính nó
- giữ
- phím
- Biết
- nổi tiếng
- Thiếu sót
- máy tính xách tay
- Trễ, muộn
- lớp
- dẫn
- hàng đầu
- Cấp phép
- Hạn chế
- Dòng
- LINK
- linux
- Logo
- còn
- Xem
- nhìn
- NHÌN
- thực hiện
- chính
- làm cho
- LÀM CHO
- quản lý
- quản lý
- Lợi nhuận
- chất
- max-width
- có nghĩa
- Bộ nhớ
- đề cập
- microsoft
- Might
- sai lầm
- hiện đại
- chi tiết
- hầu hết
- tên
- Được đặt theo tên
- Cần
- cần thiết
- nhu cầu
- mạng
- Tuy nhiên
- Mới
- bình thường
- Cung cấp
- chính thức
- ONE
- mở
- mã nguồn mở
- hoạt động
- hệ điều hành
- hoạt động
- gọi món
- nguyên
- ban đầu
- Nền tảng khác
- riêng
- sở hữu
- một phần
- các bộ phận
- thông qua
- vượt qua
- Mật khẩu
- Mật khẩu
- qua
- con đường
- paul
- có lẽ
- điện thoại
- vật lý
- Nơi
- Nền tảng
- plato
- Thông tin dữ liệu Plato
- PlatoDữ liệu
- Phổ biến
- vị trí
- có thể
- bài viết
- chuẩn bị
- sự hiện diện
- trình bày
- trước
- đặc quyền
- có lẽ
- Vấn đề
- quá trình
- chương trình
- Lập trình viên
- đúng
- giao thức
- mục đích
- Mau
- sẵn sàng
- thực
- thời gian thực
- nhận
- gần đây
- Phục hồi
- đều đặn
- phát hành
- đáng tin cậy
- nhớ
- xa
- truy cập từ xa
- báo cáo
- Báo cáo
- trở lại
- Trả về
- Rủi ro
- Phòng
- chạy
- Rust
- an toàn
- Sự An Toàn
- tương tự
- Nhà khoa học
- Màn
- Thứ hai
- an toàn
- an ninh
- nối tiếp
- DỊCH VỤ
- Phiên
- phiên
- định
- thiết lập
- thiết lập
- nghiêm trọng
- Shell
- ngắn
- Đóng cửa
- tương tự
- Đơn giản
- đơn giản hóa
- tình hình
- lẻn
- So
- Phần mềm
- rắn
- Một người nào đó
- một cái gì đó
- Chẳng bao lâu
- nguồn
- tốc độ
- gai
- Spot
- Tiêu chuẩn
- đứng
- Bắt đầu
- Vẫn còn
- mạnh mẽ
- Tiêu đề
- như vậy
- Gợi ý
- hỗ trợ
- SVG
- hệ thống
- Hãy
- nhóm
- Thiết bị đầu cuối
- Sản phẩm
- Khối
- cung cấp their dịch
- Đó
- vì thế
- điều
- nghĩ
- số ba
- thời gian
- thời gian
- Yêu sách
- đến
- bây giờ
- công cụ
- bộ công cụ
- công cụ
- hàng đầu
- Tổng số:
- theo dõi
- quá trình chuyển đổi
- minh bạch
- được kích hoạt
- rắc rối
- đúng
- NIỀM TIN
- XOAY
- thường
- unix
- Cập nhật
- cập nhật
- URL
- sử dụng
- người sử dang
- thường
- xác nhận
- phiên bản
- thông qua
- dễ bị tổn thương
- muốn
- nổi tiếng
- Điều gì
- trong khi
- CHÚNG TÔI LÀ
- rộng rãi
- sẽ
- cửa sổ
- không có
- sẽ
- viết
- viết
- viết
- năm
- trên màn hình
- zephyrnet