요약
- OpenSSH의 보안 취약점 발견: OpenSSH 서버(sshd)에서 신호 핸들러 경합 조건으로 인한 원격 코드 실행(RCE) 취약점 발견. 이 취약점은 기본 설정에서 sshd에 영향을 미침.
- 취약점의 기원: 이 취약점은 2006년에 보고된 CVE-2006-5051의 회귀로, 2020년 10월에 OpenSSH 8.5p1에서 도입된 코드 변경으로 인해 발생.
- 취약점의 영향: glibc 기반의 Linux 시스템에서 원격으로 악용 가능하며, sshd의 특권 코드에 영향을 미쳐 루트 권한으로 원격 코드 실행 가능.
- 취약점 악용 방법: 이 취약점을 악용하기 위해서는 특정 코드 경로를 찾아야 하며, 이를 적절한 시점에 중단시켜야 함. 이를 위해 오래된 OpenSSH 버전에서부터 시작하여 최신 버전으로 확장.
- 패치 및 완화: 취약점을 해결하기 위한 패치와 완화 방법 제공.
SSH-2.0-OpenSSH_3.4p1 Debian 1:3.4p1-1.woody.3 (Debian 3.0r6, 2005년)
이론
-
SIGALRM 핸들러: 이 버전의 SIGALRM 핸들러는
packet_close()
를 호출하며, 이는buffer_free()
를 호출하고, 이는xfree()
와free()
를 호출함.free()
는 비동기 신호 안전하지 않음. -
malloc 코드 분석: malloc 코드에서
free()
호출이 SIGALRM으로 중단되고, SIGALRM 핸들러 내에서 다시 호출될 때 취약점을 악용할 수 있는 경로를 발견.
실습
-
공격 방법: DSA 공개 키를 파싱하는 코드에서
free()
호출을 중단시키고, SIGALRM 핸들러 내에서 이를 악용하여 원격 코드 실행을 달성. - 경합 조건 승리: 이 경합 조건을 승리하기 위해 약 10,000번의 시도가 필요하며, 평균적으로 1주일 정도 소요.
타이밍
- 타이밍 전략: 네트워크 지연을 최소화하기 위해 마지막 바이트를 마지막 순간에 전송하고, 라운드 트립 시간을 추적하여 타이밍을 조정. 이를 통해 경합 조건 승리 확률을 높임.
SSH-2.0-OpenSSH_4.2p1 Debian-7ubuntu3 (Ubuntu 6.06.1, 2006년)
이론 1차
-
SIGALRM 핸들러: 이 버전의 SIGALRM 핸들러는
packet_close()
를 호출하지 않으며, malloc 함수가 항상 잠금을 걸기 때문에 다른 해결책 필요. -
PAM 사용: PAM의
pam_end()
가 비동기 신호 안전하지 않음을 발견하고, 이를 악용할 수 있는 경로를 탐색.
이론 2차
-
pam_start() 분석:
pam_start()
가 중단될 경우 PAM 구조체가 일관성 없는 상태로 남을 수 있으며, 이를 SIGALRM 핸들러 내에서 악용 가능. - House of Mind 기법: 공격을 위해 House of Mind 기법을 사용하여 메모리 할당을 조작하고, 루트 권한으로 원격 코드 실행 달성.
실습
-
공격 방법: 긴 사용자 이름을 사용하여 메모리 할당을 조작하고, 여러 번의
pam_start()
호출을 통해 경합 조건 승리 확률을 높임.
타이밍
- 타이밍 전략: 이전 Debian 버전에서 사용한 타이밍 전략을 재사용하여 경합 조건 승리 확률을 높임. 평균적으로 1-2일 소요.
SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 (Debian 12.5.0, 2024년)
이론
-
SIGALRM 핸들러: 이 버전의 SIGALRM 핸들러는
syslog()
를 호출하며, 이는 비동기 신호 안전하지 않은 함수들을 호출함. -
glibc 분석: glibc의
syslog()
가 malloc을 호출하며, 이는 비동기 신호 안전하지 않음. 또한, glibc의 malloc 함수가 단일 스레드일 때 잠금을 걸지 않음.
패치 및 완화
- 패치: OpenSSH 개발자들에게 취약점을 보고하고, 이를 해결하기 위한 패치 제공.
GN⁺의 의견
- 보안 중요성: OpenSSH는 매우 중요한 보안 소프트웨어로, 이 취약점은 매우 드물게 발생한 사례임.
- 취약점 악용 난이도: 이 취약점을 악용하기 위해서는 매우 정교한 타이밍과 많은 시도가 필요함.
- 대체 솔루션: OpenSSH 외에도 다양한 보안 솔루션이 존재하며, 이를 함께 사용하는 것이 좋음.
- 기술적 도전: 이 연구는 매우 높은 기술적 도전을 요구하며, 보안 연구자들에게 큰 영감을 줄 수 있음.
- 취약점 완화: 최신 보안 패치를 적용하고, 보안 설정을 강화하는 것이 중요함.
Hacker News 의견
-
RCE 수정이 거의 한 달 전에 공개적으로 "은밀하게" 이루어졌음
- PerSourcePenalties가 활성화되면 sshd(8)는 자식 사전 인증 세션 프로세스의 종료 상태를 모니터링함
- 클라이언트가 인증을 반복적으로 시도하거나 sshd가 충돌할 때 페널티를 기록함
- 이 패치는 바이너리 아키텍처를 변경하여 특정 취약점을 제거하고 전체 익스플로잇 클래스를 완화함
-
버그를 도입한 diff에서 함수가 다음과 같이 리팩토링됨
- 원래 함수:
sigdie(const char *fmt,...)
- 리팩토링된 함수:
sshsigdie(const char *file, const char *func, int line, const char *fmt, ...)
- #ifdef가 누락됨
- 더 많은 사람들이 풀 리퀘스트를 검토했다면 예방할 수 있었을 것임
- 원래 함수:
-
OpenSSH 릴리스 노트에서 흥미로운 코멘트
- 32비트 Linux/glibc 시스템에서 ASLR과 함께 성공적인 익스플로잇이 시연됨
- 64비트 시스템에서도 가능할 것으로 보임
-
OpenBSD는 SIGALRM 핸들러가 syslog_r()를 호출하여 이 취약점에 영향을 받지 않음
- 비동기 신호 안전 버전의 syslog()를 사용함
- 신호 핸들러 내의 코드 양을 최소화하는 리팩토링이 필요했음
-
musl의 syslog(3)를 조사한 결과, glibc와 달리 쉽게 익스플로잇되지 않음
- 모든 것이 스택 또는 재진입 보호된 정적 변수에 있음
-
FreeBSD용 패치가 나왔으며, glibc를 사용하지 않기 때문에 영향을 받지 않을 가능성이 높음
-
sshd_config 파일에서 'LoginGraceTime 0'을 설정하면 문제를 완화할 수 있음
- 이는 서비스 거부 공격에 취약하게 만들지만 원격 코드 실행을 방지함
-
Debian 12용 패치가 나왔으며, Debian 11은 영향을 받지 않음
-
OpenSSH 릴리스 노트와 최소 패치 링크 제공
-
독립적인 입장에서 단일 취약점을 찾는 것만으로도 충분해야 한다고 생각함
- 전체 체인을 찾아야만 사람들이 심각하게 받아들이거나 보상금을 지급하는 경향이 있음