Alpine Linux SSH 임의 비밀번호 허용 버그

원제: sshole

왜 중요한가

Docker 이미지와 임베디드 Linux 환경에서 광범위하게 사용되는 Alpine 기반 시스템의 SSH 인증 자체가 약 10년간 무력화될 수 있었음을 보여준다.

2016년부터 musl libc 기반 Linux(Alpine, OpenWrt, Docker 이미지 등)의 OpenSSH에서 비밀번호가 없어야 할 계정(root, 키 전용 계정 등)에 256자 이상의 임의 문자열로 로그인 가능한 취약점이 존재해왔다. 이 문제는 2012년 musl의 crypt() 반환값 변경과 256바이트 상한 제한이 결합돼 발생했다.

이 취약점의 뿌리는 1980년대 Unix의 `/etc/passwd`까지 거슬러 올라간다. 당시 로그인 불가 계정에는 해시 대신 `*`를 삽입해 어떤 비밀번호도 일치하지 않도록 했다. 문제는 2012년 musl이 crypt() 실패 시 NULL 대신 `*`를 반환하도록 변경하면서 시작된다(커밋 b3c4cc12). 같은 달 20일 뒤 musl은 sha512crypt의 DoS 방지를 위해 비밀번호를 256바이트로 제한하는 코드를 추가했다(커밋 88bf5a8a). 256바이트를 초과하면 crypt()가 실패하고, 실패하면 `*`를 반환한다.

2016년 CVE-2016-6210 대응으로 OpenSSH는 존재하지 않는 사용자에 대한 타이밍 공격을 막기 위해 임의의 솔트로 비밀번호를 해시하는 우회 로직을 추가했다. 그런데 이 로직이 `*`가 저장된 실제 계정에도 동일하게 적용됐다. 결과적으로 256자 이상의 비밀번호를 입력하면 crypt()가 `*`를 반환하고, 저장된 필드도 `*`이므로 두 값이 일치해 인증이 통과된다.

2019년 CVE-2019-5021로 Alpine Docker 이미지의 root 계정 비밀번호 미설정 문제가 공개됐고, Alpine은 `!`로 계정을 잠갔다. 그러나 PAM 없이 `!` 처리가 올바르게 동작하지 않아 취약점이 완전히 해소되지 않았다. musl 기반 시스템에서 키 전용으로 운영하는 deploy 계정, LDAP 사용자, AWS·Azure의 Alpine 기본 이미지 계정 등이 모두 영향권에 있다.

출처

sshhole.com — 원문 읽기 →