리눅스 TCP 취약점, CVSS 9.8로 상향

리눅스 TCP 취약점, CVSS 9.8로 상향

레드햇(Red Hat)은 11월 2일 리눅스 커널 취약점 CVE-2026-98432의 CVSS 점수를 9.8로 올렸다. 그전에는 5.9에서 8.1까지 다양한 점수를 매겼고, 11월 1일에는 RHEL 8, 9, 10용 패치 커널을 배포했다. Ubuntu의 상태는 여전히 수정 진행 중이다.

이 취약점은 IPv4 TCP 연결 수립 과정에 있으며, 네트워크 쪽에서 인증이나 사용자 조작 없이 촉발할 수 있다. 영향 범위는 리눅스 4.4부터이고, 원인은 2015년의 한 커밋까지 거슬러 올라간다.

두 줄 코드로 고친 경쟁 상태

SYN 패킷에 IPv4 옵션(Record Route, Timestamp 등)이 붙어 있으면 커널은 이를 요청 소켓에 저장한다. 핸드셰이크가 끝나면 이 메모리의 포인터는 복사 없이 그대로 자식 소켓에 넘어가, 두 소켓이 같은 영역을 공유한다.

이때 다른 CPU가 재전송된 SYN에 대한 SYN-ACK를 만들고 있는 중에 자식 소켓이 마침 파괴되면, 옵션 메모리는 kfree()로 즉시 해제된다. SYN-ACK를 만드는 경로는 이미 해제된 메모리를 읽게 된다.

수정은 Eric Dumazet이 제출했고 커밋은 e3f33b0a1d89다. kfree()를 kfree_rcu()로 바꿔 RCU 유예 기간이 지난 뒤에 해제하도록 했으며, 변경은 두 줄뿐이다. 취약점 보고자는 Anthropic의 Xinyang Ge다. CVE 기록은 10월 15일에 게시됐다. 안정 브랜치의 수정 버전은 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10이고 메인라인은 7.3이다.

Anthropic의 주장은 Anthropic만 입증할 수 있다

이 취약점이 주목받게 된 것은 10월 27일 Anthropic Frontier Red Team이 올린 글 때문이다. 글에 따르면 공개되지 않은 내부 모델이 익스플로잇을 작성했고, MPTCP 리스너가 켜진 서버에서 인증되지 않은 원격 공격자가 root 권한으로 명령을 실행할 수 있다.

공격은 두 단계다. 먼저 경쟁 상태를 이용해 커널 메모리를 범위 밖으로 읽어 포인터를 유출하고 KASLR을 우회한다. 그다음 범위 밖 쓰기로 콜백 함수 포인터를 덮어쓴다. Anthropic이 제시한 소요 시간은 포인터 유출에 약 48분, 이후 명령 실행까지 약 5분이다.

여기서는 몇 가지를 구분해서 봐야 한다. 익스플로잇 코드, 테스트에 쓴 커널 버전과 설정은 공개되지 않았고 제3자 검증도 아직 없다. CVE 기록과 수정 커밋 어디에도 MPTCP 언급은 없으며, 글도 MPTCP가 왜 필요한지 설명하지 않는다. 53분이라는 수치는 알려지지 않은 환경에서 나온 값이라 실제 서비스 서버에 그대로 적용할 수 없다. 11월 2일 기준으로 벤더, CERT, 커널 CVE 팀 어느 쪽도 실제 환경에서의 악용을 보고하지 않았고, CISA의 알려진 악용 취약점 카탈로그에도 등재되지 않았다.

중국어권 일부 보도는 "Anthropic이 익스플로잇 예시를 공개했다"고 쓰지만, 정확히는 공격 과정에 대한 설명을 공개했을 뿐 실행 가능한 코드는 내놓지 않았다.

점수를 둘러싼 이견도 남아 있다. 커널 CVE 팀과 레드햇은 현재 9.8을 매겼고, Oracle, SUSE, Amazon은 8.1을 매겼다. 차이는 공격 복잡도를 낮음으로 보느냐 높음으로 보느냐에 있다. NVD는 아직 자체 점수를 내지 않았다.

Go가 전제 조건을 기본값으로 만들었다

10월 29일 Go 보안팀의 공지로 영향 범위가 넓어졌다. Go 1.24부터 multipathtcp의 기본값은 2로, 대기하는 쪽에서만 MPTCP를 켠다는 뜻이다. 즉 net.Listen으로 서비스를 띄우는 Go 프로그램은 기본 설정만으로 Anthropic이 시연한 전제 조건을 충족한다.

Go 팀이 제시한 완화책은 실행 시 GODEBUG=multipathtcp=0을 설정하거나, 메인 모듈의 go.mod에 godebug multipathtcp=0을 쓰는 것이다. 동시에 프로그램별로 끄는 이 방식을 "a fragile mitigation(취약한 완화책)"이라고 불렀다. Go 팀은 지금 기본값을 바꾸는 것은 이르다고 본다. 커널 쪽에서는 net.mptcp.enabled를 0으로 설정할 수 있지만, 이는 시연된 전제 조건을 없앨 뿐 취약점 자체는 그대로 남는다.

운영자가 먼저 할 수 있는 일

배포판별 상태(일부는 10월 29일, 일부는 11월 2일 확인 기준)는 대략 다음과 같다.

배포판상태
RHEL 8, 9, 10수정됨
RHEL 9 real-time, OpenShift 4영향 받음, 수정 없음
RHEL 7영향 없음
Debian 12, 13수정됨
Ubuntu 22.04, 24.04, 26.04, 26.10영향 받음, 수정 진행 중
Ubuntu 16.04, 18.04, 20.04영향 받음, 수정 없음
Amazon Linux 2, 2023수정됨
Oracle Linux(UEK)수정됨

클라우드 호스트 사용자 가운데 Ubuntu 비중이 적지 않아, 이 표에서 가장 눈여겨봐야 할 곳이 Ubuntu다. 대부분의 배포판은 백포트 패치로 수정하므로, 패치 여부는 각 배포판 보안 공지의 패키지 버전과 대조해 판단해야 한다. uname -r의 메이저 버전만 보면 잘못 판단하기 쉽다. 새 커널은 재부팅해야 적용되며, 라이브 패치는 별개의 메커니즘이라 따로 확인해야 한다.

당장 패치를 받을 수 없는 서버는 먼저 어떤 서비스가 MPTCP로 대기하고 있는지, 특히 Go 1.24 이후로 빌드한 바이너리가 있는지 파악한 뒤 위 방법으로 끌지 결정하면 된다. MPTCP를 끄면 위험이 모두 사라진다고 벤더가 확인한 것은 아니므로, 이 조치는 시간을 버는 수단일 뿐이다. 커널 크래시 로그에 ip_options_build 같은 함수가 나타난다면 그것도 조사해야 한다.

참고 출처: Anthropic Frontier Red Team 글의 공개 소개, Rescana 취약점 공지, CocoLoop, Go 보안팀 공지, Debian 및 Red Hat 보안 추적 페이지. 점수와 배포판별 수정 상태는 각 벤더가 공표한 기준을 따르며, Anthropic의 익스플로잇 세부 내용은 독립적으로 검증되지 않았다.