Logo
Lỗ hổng OpenSSH sshole CVE-2026-123158: gõ mật khẩu dài 300 ký tự là vào được tài khoản đã khóa

Lỗ hổng OpenSSH sshole CVE-2026-123158: gõ mật khẩu dài 300 ký tự là vào được tài khoản đã khóa

tobi
tobi•• … views

Ngày 05/11/2026, dự án OpenSSH phát hành khẩn cấp bản 10.6p2 — chỉ một ngày sau khi nhận báo cáo, không qua thời gian chờ phối hợp như thường lệ — để chặn lỗ hổng OpenSSH sshole (CVE-2026-123158, CVSS 8.1), một lỗ hổng vượt qua xác thực mật khẩu trong sshd. Trên các hệ Linux dùng thư viện musl và không dùng PAM — điển hình là Alpine Linux — kẻ tấn công chỉ cần gửi một mật khẩu dài hơn 256 ký tự là đăng nhập được vào các tài khoản vốn không hề có mật khẩu. Damien Miller, người duy trì OpenSSH, kêu gọi quản trị viên các hệ bị ảnh hưởng tắt đăng nhập bằng mật khẩu hoặc vô hiệu hóa SSH ngay lập tức trong lúc chờ vá. Nếu bạn đang chạy Alpine — trên VPS, trong Docker, trên thiết bị nhúng — hãy đọc hết bài này và kiểm tra máy của mình ngay sau đó.

1. Chuyện gì đã xảy ra?

Lỗ hổng do nhà nghiên cứu Özgün Kültekin (Wakefield) phát hiện khi dùng các agent AI chạy khoảng 17.600 lần thử đăng nhập trên nhiều tổ hợp bản dựng sshd khác nhau (glibc/musl, có/không PAM) — chỉ tổ hợp musl + không PAM chấp nhận những lần đăng nhập lẽ ra phải bị từ chối. Anh báo cáo riêng cho OpenSSH, và dự án xử lý với tốc độ hiếm thấy: nhận báo cáo ngày 04/11, phát hành bản vá 10.6p2 ngay ngày 05/11, cùng ngày Alpine Linux ra cảnh báo bảo mật cho mọi nhánh từ 3.16 tới edge.

Về tình trạng khai thác, thông tin hiện có hai chiều và mình trình bày đúng như vậy: mã chứng minh khái niệm (PoC) đã công khai, hồ sơ CVE ghi nhận các phòng lab tái hiện được đăng trên GitHub; hai hãng tình báo mối đe dọa là Previdian và watchTowr cho biết đã ghi nhận các nỗ lực khai thác — Previdian nói honeypot Alpine của họ bị chiếm quyền root chưa đầy 9 giờ sau khi CVE công bố, còn watchTowr nhận định đợt tấn công chủ yếu đến từ botnet và mã độc đào coin. Ngược lại, OpenSSH và Alpine cho biết tới 06/11 họ chưa có báo cáo khai thác được xác nhận, và CISA chưa đưa CVE này vào danh sách KEV. Dù hiểu theo chiều nào, kết luận thực hành vẫn giống nhau: đây là lỗi đăng nhập từ xa không cần biết mật khẩu, đã có PoC công khai — hãy vá ngay, đừng chờ.

2. Cơ chế lỗi: khi dấu * “khóa tài khoản” lại thành chìa khóa

Đây là một lỗi logic tinh quái nằm ở điểm giao nhau giữa hai dự án, tồn tại trong mã nguồn OpenSSH bản portable từ năm 2016 (bản 7.3 tới 10.6p1). Chuỗi sự kiện như sau:

  1. Khi sshd được biên dịch không dùng PAM, nó tự kiểm tra mật khẩu: băm mật khẩu người dùng vừa nhập bằng hàm crypt() rồi so sánh với trường mật khẩu lưu trong /etc/shadow.
  2. Tài khoản không đặt mật khẩu (ví dụ tài khoản chỉ đăng nhập bằng khóa SSH) có trường mật khẩu là một ký tự duy nhất: *. Vì * quá ngắn, không chứa “muối” (salt) để băm, sshd mượn tạm salt của một tài khoản khác có mật khẩu thật để thực hiện phép băm so sánh — hành vi có từ bản vá của một CVE cũ năm 2016.
  3. Điểm chết người: hàm crypt() của musl libc trả về đúng chuỗi * như một mã lỗi khi mật khẩu nhập vào dài hơn 256 byte.
  4. Kết quả băm là *, trường lưu trong shadow cũng là * — khớp nhau. Đăng nhập thành công.

Nói cách khác: với bất kỳ tài khoản * nào, cứ gửi một mật khẩu dài từ 257 tới 1024 byte là vào được, một lần là trúng, không cần dò. Bản vá 10.6p2 chặn ở phía sshd: từ chối khớp nếu trường mật khẩu lưu trữ ngắn hơn 4 ký tự, nên * không bao giờ khớp được nữa.

Có một chi tiết đáng chú ý: hai dự án không thống nhất lỗi thuộc về ai. OpenSSH viết trong ghi chú phát hành rằng “nguyên nhân gốc nằm ngoài sshd, nhưng lỗi khai thác được qua sshd và tránh được tại sshd”. Người duy trì musl, Rich Felker, thì cho rằng đây là lỗi của phía gọi hàm, không phải lỗi của musl. Với người vận hành, cuộc tranh luận này không quan trọng bằng việc bản vá đã có sẵn ở cả hai phía hệ sinh thái.

Minh họa máy chủ bị mở khóa bằng mật khẩu dài trong lỗ hổng OpenSSH sshole

3. Hệ nào bị ảnh hưởng, hệ nào không?

Lỗi chỉ kích hoạt khi đồng thời đủ các điều kiện sau:

  • sshd chạy trên Linux liên kết với musl libc;
  • sshd không dùng PAM (gói openssh-server của Alpine biên dịch sẵn không PAM, hoặc bản PAM nhưng đặt UsePAM no);
  • PasswordAuthentication đang bật (đây là mặc định của OpenSSH);
  • máy có ít nhất một tài khoản có trường mật khẩu là * — rất phổ biến: root trong image gốc Alpine là root:*, mọi user tạo bằng adduser mà không đặt mật khẩu (kiểu chỉ dùng khóa), user từ dịch vụ thư mục qua musl-nscd;
  • máy có ít nhất một tài khoản khác có hash mật khẩu dạng $5$ hoặc $6$ (để sshd “mượn” salt).
Hệ thống / cấu hình Trạng thái
Alpine Linux 3.16 – 3.24 và edge (gói openssh-server mặc định) Bị ảnh hưởng
Nền tảng dùng musl: OpenWrt, Buildroot, Yocto Bị ảnh hưởng (chưa có thông báo vá tính tới 06/11)
Image cloud chính thức của Alpine (tiny-cloud) trên AWS/Azure Bị ảnh hưởng có điều kiện — xem đoạn dưới
Debian, Ubuntu, Fedora, RHEL và các bản dùng glibc Không bị
Hệ dùng PAM với UsePAM yes Không bị
Hệ đã đặt PasswordAuthentication no Không bị
Container Docker không chạy sshd bên trong Không bị
Tài khoản bị khóa bằng ! trong shadow (không phải *) Không bị

Riêng tiny-cloud: các image chính thức (qcow2, VHD, AMI) từ 3.18.11 tới 3.24.3 đi kèm user alpine có trường mật khẩu * và quyền doas không cần mật khẩu. Máy an toàn ở lần khởi động đầu, nhưng trở nên khai thác được ngay khi trên máy xuất hiện một hash $6$ bất kỳ — ví dụ quản trị viên đặt mật khẩu console, hoặc user-data thêm user có mật khẩu. Khi đó kẻ tấn công vào được shell của user alpine rồi dùng doas leo lên root. Lưu ý thêm: root tuy cũng là tài khoản * nhưng được cấu hình mặc định PermitRootLogin prohibit-password bảo vệ — cửa vào thực tế là các tài khoản * còn lại có đường leo quyền.

4. Kiểm tra máy của bạn trong 2 phút

Trên máy Alpine (hoặc container Alpine có chạy sshd), chạy lần lượt các lệnh kiểm tra sau. Đây là ảnh chụp thật từ môi trường giả lập Alpine 3.21 mình dựng để đối chiếu — phiên bản gói, thư viện liên kết, các tài khoản * và trạng thái đăng nhập mật khẩu đều hiện rõ:

Ảnh terminal thật kiểm tra các điều kiện của lỗ hổng sshole trên Alpine Linux và tắt đăng nhập mật khẩu

Cách đọc kết quả:

  • sshd -V: hiện phiên bản OpenSSH (ở đây là 9.9p2) — đối chiếu với bảng đã vá ở mục 5. Nhỏ hơn bản vá của nhánh mình đang dùng = còn lỗi.
  • ldd /usr/sbin/sshd: nếu thấy ld-musl thì sshd đang chạy trên musl — một điều kiện của lỗi.
  • grep -E ':\*:' /etc/shadow: liệt kê các tài khoản * — đây chính là danh sách “cửa” mà lỗ hổng mở ra.
  • sshd -T | grep -i passwordauthentication: nếu ra yes thì đường đăng nhập bằng mật khẩu đang mở.

Nếu bạn dùng Ubuntu/Debian, chỉ cần biết máy mình dùng glibc là yên tâm với riêng lỗ hổng này.

5. Cách vá và giảm thiểu ngay

Cách 1 — Cập nhật (khuyến nghị). Trên Alpine, chạy:

apk upgrade -U -a
rc-service sshd restart

Bước restart là bắt buộc: nâng cấp gói không thay thế tiến trình sshd đang chạy. Các image điểm phát hành 3.21.10, 3.22.8, 3.23.8 và 3.24.4 đã chứa sẵn gói đã vá. Phiên bản openssh tối thiểu đã vá theo từng nhánh Alpine:

Nhánh Alpine Gói openssh đã vá
edge 10.6_p2-r0
3.24 10.3_p1-r2
3.23 10.2_p1-r1
3.22 10.0_p1-r11
3.21 9.9_p2-r1
3.20 9.7_p1-r6
3.19 9.6_p1-r3
3.18 9.3_p2-r4
3.17 9.1_p1-r7
3.16 9.0_p1-r6

Đáng ghi nhận: Alpine phát hành bản vá cho cả các nhánh đã hết hỗ trợ (3.16–3.20) vì mức độ nghiêm trọng của lỗi. Với hệ tự biên dịch OpenSSH, nâng lên 10.6p2.

Cách 2 — Chưa vá được thì tắt đăng nhập mật khẩu. Nếu bạn đăng nhập bằng khóa SSH, tắt hẳn đường mật khẩu là đóng lỗ hổng ngay. Trước khi làm, hãy chắc chắn khóa SSH của bạn đăng nhập được, và giữ nguyên phiên SSH hiện tại cho tới khi thử xong một phiên đăng nhập mới:

mkdir -p /etc/ssh/sshd_config.d
echo 'PasswordAuthentication no' > /etc/ssh/sshd_config.d/00-no-passwords.conf
sshd -t && rc-service sshd restart
sshd -T | grep -i passwordauthentication

Lệnh cuối phải in ra passwordauthentication no. (Với các bản Alpine cũ hơn 3.19 không đọc thư mục sshd_config.d, hãy sửa trực tiếp dòng PasswordAuthentication trong /etc/ssh/sshd_config — chi tiết có trong cảnh báo chính thức của Alpine ở cuối bài.)

Minh họa cập nhật vá lỗi cho các container và máy chủ đám mây dùng Alpine Linux

6. Kiểm tra dấu hiệu đã bị tấn công

Theo hướng dẫn của Alpine, hãy rà soát /var/log/messages tìm các dòng Accepted password for ứng với một tài khoản không hề có mật khẩu (alpine, root hoặc bất kỳ user chỉ dùng khóa nào) — đó là dấu hiệu đăng nhập bất thường rõ ràng nhất. Đồng thời kiểm tra: lịch sử dùng doas, các user mới được tạo gần đây, file lạ và khóa lạ trong authorized_keys trên các máy từng phơi cổng SSH ra ngoài. Nếu không loại trừ được khả năng đã có đăng nhập trái phép, hãy coi máy đó như đã bị xâm nhập và xử lý theo quy trình ứng cứu sự cố, không chỉ dừng ở việc vá.

7. Bài học cho người vận hành

  • Tài khoản “chỉ dùng khóa” không đồng nghĩa cánh cửa mật khẩu đã đóng. Nếu PasswordAuthentication vẫn bật, tài khoản * vẫn tham gia vào đường kiểm tra mật khẩu — và như vụ này cho thấy, chỉ một va chạm ký tự cũng đủ mở cửa. Không dùng mật khẩu thì tắt hẳn PasswordAuthentication.
  • Phân biệt * và ! trong /etc/shadow: * nghĩa là “không có mật khẩu” (vẫn đăng nhập được bằng cơ chế khác như khóa), còn ! là khóa hẳn tài khoản. Muốn vô hiệu hóa hoàn toàn một tài khoản, hãy dùng !.
  • Rủi ro nằm ở tổ hợp, không ở từng phần mềm riêng lẻ. OpenSSH đứng một mình không sao, musl đứng một mình cũng không sao — lỗ hổng sinh ra ở cách chúng ghép với nhau. Khi chọn base image siêu nhẹ cho production, hãy tính cả bề mặt tương tác kiểu này và theo dõi kênh cảnh báo của chính distro đó.

Kết luận

sshole (CVE-2026-123158) là lời nhắc hiếm hoi rằng một ký tự * cũng có thể thành lỗ hổng nghiêm trọng: trên Alpine và các hệ musl không dùng PAM, bất kỳ ai chạm được tới cổng SSH đều có thể vào các tài khoản không mật khẩu bằng một mật khẩu dài vô nghĩa. Bản vá đã có cho mọi nhánh Alpine kể cả nhánh hết hỗ trợ — việc của bạn chỉ là apk upgrade và restart sshd, hoặc tắt hẳn đăng nhập mật khẩu nếu chưa vá kịp. Đừng quên rà log sau khi vá: vá xong mà không kiểm tra dấu hiệu xâm nhập thì mới chỉ làm được nửa việc.

Câu hỏi thường gặp

Máy Ubuntu/Debian của mình có bị lỗ hổng sshole không? Không. Ubuntu/Debian dùng glibc và sshd đi qua PAM, không thỏa điều kiện của lỗi. Bạn vẫn nên cập nhật hệ thống thường xuyên, nhưng không cần hành động khẩn cấp cho riêng CVE này.

Mình dùng Docker image Alpine thì sao? Chỉ bị ảnh hưởng nếu container của bạn tự chạy một sshd bên trong và bật đăng nhập mật khẩu. Phần lớn container Alpine chỉ chạy ứng dụng, không có sshd — những container đó không bị. Nếu có chạy sshd trong container, hãy cập nhật gói openssh trong image và dựng lại.

CVSS chỉ 8.1, sao có nơi chấm tới 10? MITRE chấm 8.1 (mức High, độ phức tạp tấn công bị đánh giá là cao vì cần đủ tổ hợp điều kiện). Một số cơ sở dữ liệu thương mại chấm cao hơn vì trên các hệ thỏa điều kiện, việc khai thác lại cực kỳ đơn giản và cho quyền truy cập đầy đủ. Dù theo thang nào, đây cũng là lỗi cần vá ngay.

Cập nhật gói xong mà không restart sshd có được không? Không. Tiến trình sshd đang chạy vẫn là mã cũ. Alpine nhấn mạnh rõ trong cảnh báo: nâng cấp xong phải rc-service sshd restart.

Kẻ tấn công có vào thẳng root được không? Mặc định thì không: root được PermitRootLogin prohibit-password chặn đăng nhập mật khẩu. Nhưng các tài khoản * khác — như user alpine trên image tiny-cloud có doas không mật khẩu — lại là đường vòng lên root, nên đừng chủ quan.

Đã vá xong có cần kiểm tra gì thêm không? Có: rà /var/log/messages tìm Accepted password for ở các tài khoản không có mật khẩu, kiểm tra user/khóa lạ. Nếu thấy dấu hiệu và không loại trừ được, hãy coi máy đã bị xâm nhập.

Nguồn tham khảo

Chuyên mục:Cybersecurity

Bình luận (0)

+ =
Zalo