1. 개요
본 보고서는 'Eternal-Tux: Crafting a Linux Kernel KSMBD 0-Click RCE Exploit from N-Days'를 통해 공개된, 리눅스 커널 SMB 서버(KSMBD)의 원격 코드 실행(Remote Code Execution, RCE) 취약점을 다룬다. 해당 취약점은 쓰기 권한을 보유한 SMB 사용자가 특수하게 조작된 요청을 전송하여 서버의 최고 관리자(root) 권한 획득을 가능하게 한다. 공격 성공 시 위험성은 매우 높으나, 후술할 원인으로 인해 공격 조건이 복잡하고 안정성이 낮아 실제 악용 가능성은 낮은 것으로 평가된다.
이에 본 보고서는 해당 공격에 사용된 CVE-2023-4130, CVE-2023-52440의 근본 원인을 심층 분석하고, 두 취약점이 조합되어 원격 코드 실행으로 이어지는 과정을 설명하며, 이에 대한 방어 및 완화 전략을 제시한다.
2. 사전 지식
2.1. KSMBD(Kernel SMB Daemon)
KSMBD는 리눅스 커널에 구현된 SMB(Server Message Block) 서버다. SMB는 본래 Windows 환경의 파일 공유를 위해 개발된 프로토콜이나, 리눅스 커널 5.4 버전부터 리눅스 환경에서도 이를 지원하기 위해 KSMBD 모듈이 선택적으로 포함되었다. 세부적인 구현에는 Windows와 일부 차이가 존재하지만, 대부분의 핵심 기능은 동일하게 구현되었다.
2.2. KASLR(Kernel Address Space Layout Randomization)
KASLR은 Kernel Address Space Layout Randomization의 약어다. KASLR이 적용되지 않은 리눅스 커널에서는 특정 함수가 항상 고정된 메모리 주소에 위치한다. 그러나 KASLR이 적용된 커널은 부팅 시마다 임의의 오프셋(Offset)을 주소 공간에 추가하기 때문에 함수나 전역 변수 등의 메모리 주소가 계속해서 변경된다.
따라서 공격자가 원격 코드 실행(RCE) 공격을 통해 특정 함수를 호출하기 위해서는, KASLR을 우회하여 KernelBase 주소를 알아내고 이를 통해 목표 함수의 정확한 메모리 주소를 계산해야 한다.
3. 취약점 근본 원인 분석
3.1. CVE-2023-52440 분석
항목 | 내용 |
취약점 번호 | CVE-2023-52440 |
취약점 이름 | Linux Kernel KSMBD Heap-based Buffer Overflow Vulnerability |
취약점 종류 | Heap-based Buffer Overflow |
CVSS | 7.8(/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) |
CVE-2023-52440은 KSMBD가 세션 키의 길이를 검증하지 않아 발생하는 힙 기반 버퍼 오버플로우(Heap-based Buffer Overflow) 취약점이다. 이 취약점을 통해 공격자는 할당된 버퍼의 경계를 넘어 인접한 메모리 영역에 임의의 데이터를 쓸 수 있다.
#define CIFS_KEY_SIZE (40)
int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
int blob_len, struct ksmbd_conn *conn, struct ksmbd_session *sess)
{
// ...
// authblob->SessionKey는 공격자가 제어할 수 있다.
sess_key_len = le16_to_cpu(authblob->SessionKey.Length);
if (blob_len < (u64)sess_key_off + sess_key_len)
return -EINVAL;
+ if (sess_key_len > CIFS_KEY_SIZE) // CIFS_KEY_SIZE = 40
+ return -EINVAL; // 40 바이트보다 더 긴 키를 입력 시 연결 해제
// 이하 생략
C
복사
[코드 1] ksmbd: fix slub overflow in ksmbd_decode_ntlmssp_auth_blob() 리눅스 커널 패치 diff
struct ksmbd_session {
// 생략
int state;
__u8 *Preauth_HashValue;
char sess_key[40]; // 힙 기반 오버플로우 발생 위치 (CIFS_KEY_SIZE = 40)
struct hlist_node hlist;
// 이하 생략 // sess_key의 범위 40 바이트를 넘어서 메모리를 작성해 오버플로우
};
C
복사
[코드 2] ksmbd_session 구조체
CVE-2023-52440의 근본 원인은 다음과 같다.
•
입력 값 길이 검증의 부재: [코드 1]의 ksmbd_decode_ntlmssp_auth_blob() 함수는 KSMBD의 NTLLMSSP_AUTH라는 서버
클라이언트 인증 메세지를 처리하는 함수다. 취약점 패치 버전과 취약한 버전의 차이를 확인해보면 sess_key_len 변수의 길이가 CIFS_KEY_SIZE(40 바이트) 보다 더 큰지 확인하는 코드가 추가되었다. sess_key_len은 공격자가 제어할 수 있는 KSMBD 세션 키의 길이다.
•
정상 범위 40 바이트를 넘어서는 메모리 복사: ksmbd_session 구조체를 살펴보면 sess_key 라는 필드가 존재한다. 위에서 분석한 함수에서 입력받은 세션 키는 최종적으로 ksmbd_session->sess_key 필드에 memcpy() 함수를 사용해 복사 된다. 키 길이를 검사하지 않았기 때문에 만약 KSMBD가 복사하려는 세션 키 길이가 40 바이트보다 더 크다면 ksmbd_session->sess_key 버퍼의 경계를 넘어선 쓰기가 발생해 힙 기반 버퍼 오버플로우로 이어진다.
[그림 1] SMB NTLM 인증에 포함된 정상 SMB 세션 키 (16 바이트)
[그림 2] SMB NTLM 인증에 포함된 오버플로우를 유발하는 비정상 SMB 세션 키 (50 바이트)
[그림 2]를 살펴보면, Session Key의 길이가 원래 버퍼 크기인 40 바이트를 초과하는 50 바이트임에도 불구하고 SMB 인증에 성공했다. 이렇게 서버에 전달된 Session Key는 버퍼 오버플로우를 일으킨다.
3.1.1. Buffer Overflow 발생 원리 및 예시
[그림 3] Buffer Overflow 예시
// 오버플로우 전
char sess_key[40] = { '0x00', '0x00', ..., '0x00' };
void* important_pointer = 0x0123456789abcdef;
// 오버플로우 후 (Input 48 Bytes: 'A' * 40 + 0xff * 8)
char sess_key[40] = { 'A', 'A', ..., 'A' }; // sess_key 필드에 Input 48 바이트를 복사
void* important_pointer = 0xffffffffffffffff; // 40 바이트 작성 후 남은 8 바이트는 여기에
// 복사되어 의도하지 않은 값이 변경됨
C
복사
[코드 3] Buffer Overflow 예시
버퍼 오버플로우(Buffer Overflow)의 구체적인 예시는 다음과 같다. [그림 3], [코드 3]과 같이 메모리 공간에 sess_key(40바이트)와 important_pointer(8바이트) 필드가 순차적으로 할당되어 있고, 공격자는 sess_key 값을 제어할 수 있다고 가정한다.
이때 공격자는 40바이트의 임의 데이터(예: 'A' * 40)와 8바이트의 특정 포인터 값(예: 0xffffffffffffffff)을 조합하여 총 48바이트 길이의 세션 키를 구성한다. 해당 세션 키를 서버로 전송하면, 데이터 복사 과정에서 40바이트만 저장할 수 있는 sess_key 버퍼에 48바이트 데이터가 복사된다. 결과적으로 sess_key 버퍼의 경계를 넘어 뒤따르는 important_pointer 필드의 값이 공격자가 의도한 8바이트 값으로 덮어써지는 현상이 발생한다.
요약하면, 버퍼 오버플로우는 이처럼 입력 값에 대한 길이 검증이 미흡할 경우 할당된 메모리 버퍼의 경계를 넘어 의도치 않은 영역의 데이터를 변조하는 보안 취약점이다. 이 현상이 힙 메모리에서 발생하면 힙 기반 버퍼 오버플로우, 스택 메모리에서 발생하면 스택 오버플로우로 부른다.
3.2. CVE-2023-4130 분석
항목 | 내용 |
취약점 번호 | CVE-2023-4130 |
취약점 이름 | Linux Kernel KSMBD Out-of-Bounds Read Vulnerability |
취약점 종류 | Out-of-Bounds Read |
CVSS | 5.5(/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H) |
CVE-2023-4130은 SMB 쿼리의 길이 검증 로직 결함으로 인해 발생하는 Out-of-Bounds(OOB) Read 취약점이다. 이 취약점을 통해 공격자는 정상적인 메모리 접근 범위를 벗어난 영역의 데이터를 읽을 수 있다. 이렇게 유출된 커널 메모리 정보는 리눅스의 보안 기능인 KASLR을 무력화하는 데 사용되거나 추가적인 취약점 공격에 사용될 수 있다.
static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, const struct path *path)
// 생략
next = le32_to_cpu(eabuf->NextEntryOffset);
if (next == 0 || buf_len < next)
break;
buf_len -= next;
eabuf = (struct smb2_ea_info *)((char *)eabuf + next);
// 이 코드는 결함이 존재함
- if (next < (u32)eabuf->EaNameLength + le16_to_cpu(eabuf->EaValueLength))
- break;
// 이 코드는 결함이 수정되었음
+ if (buf_len < sizeof(struct smb2_ea_info)) {
+ rc = -EINVAL;
+ break;
+ }
+
+ if (buf_len < sizeof(struct smb2_ea_info) + eabuf->EaNameLength +
+ le16_to_cpu(eabuf->EaValueLength)) {
+ rc = -EINVAL;
+ }
} while (next != 0);
// 이하 생략
C
복사
[코드 4] ksmbd: fix wrong next length validation of ea buffer in smb2_set_ea() 리눅스 커널 패치 diff
struct smb2_ea_info {
__le32 NextEntryOffset;
__u8 Flags;
__u8 EaNameLength;
__le16 EaValueLength;
char name[1]; // EaNameLength 크기 만큼의 값이 존재할 수 있다
// 정상적인 경우 EaValueLength 크기 만큼의 Value 값이 존재해야만 한다
} __packed;
C
복사
[코드 5] smb2_ea_info 구조체
smb2_ea_info는 다수의 엔트리를 포함할 수 있는 구조체로, 그 내용은 공격자에 의해 제어될 수 있다. 구조체 내 NextEntryOffset 필드는 다음 엔트리까지의 상대적인 오프셋(offset)을 나타낸다.
[코드 4]의 검증 로직은 NextEntryOffset 값이 EaNameLength와 EaValueLength의 합보다 작은지만을 확인한다. 표면적으로는 유효해 보이나, 이 검사는 버퍼의 실제 경계를 고려하지 않는 심각한 논리적 결함을 내포한다.
•
선언된 길이와 실제 버퍼 크기의 미검증: 해당 코드의 주된 결함은 공격자가 EaNameLength와 EaValueLength 필드에 명시한 길이 값이 실제 제공된 버퍼의 크기 내에 유효한지를 교차 검증하지 않는다는 점이다. 예를 들어, 공격자가 EaValueLength를 100으로 설정하고 실제로는 EaName에 해당하는 데이터까지만 버퍼에 담아 전송할 수 있다. 정상적인 경우라면 EaValue를 위한 100바이트의 데이터가 버퍼 내에 존재해야 하지만, 취약한 코드는 이를 확인하지 않는다. 그 결과, smb2_ea_info 구조체의 경계를 넘어 인접한 커널 메모리 100바이트를 읽어 공격자에게 전송하게 되고, 이로 인해 Out-of-Bounds Read가 발생한다.
이후 패치된 버전에서는 현재 처리 가능한 버퍼의 잔여 길이(buf_len)가 smb2_ea_info 구조체의 기본 크기 및 EaNameLength, EaValueLength의 합보다 큰지 검증하는 로직을 추가하여 이 취약점을 해결했다.
[그림 4] 비정상 smb2_ea_info 구조체를 전송하는 SMB 패킷
[그림 5] Out-of-Bounds Read로 노출된 인접한 커널 메모리
[그림 4]은 SetInfo 요청 패킷의 첫 번째 엔트리(EA) Next Offset에 399 바이트, 두 번째 엔트리의 Data Length에 비정상적인 크기 395 바이트로 설정해 전송한 사진이다. 그 후 GetInfo 요청 패킷을 전송하여 수신한 응답 패킷에 [그림 5]처럼 Data에 비정상적인 Data Length395 바이트 만큼의 인접한 커널 메모리가 포함되어 Out-of-Bounds Read가 발생했다.
3.2.1. Out-of-Bounds(OOB) Read 발생 원리 및 예시
[그림 6] Out-of-Bounds Read 예시
Out-of-Bounds Read의 동작 방식을 [그림 6]의 예시를 통해 설명하면 다음과 같다.
정상적인 사용자는 5바이트 크기를 갖는 'File1'의 'Value' 데이터에 대해 5바이트 읽기를 요청한다. 이 경우 서버는 정확히 해당 데이터 5바이트만을 클라이언트에게 응답으로 전송한다.
반면, 공격자는 동일한 'Value' 데이터에 대해 실제 크기를 초과하는 100바이트 읽기를 요청한다. 이때 서버가 요청된 길이를 데이터의 실제 크기와 비교하여 검증하지 않는다면, 'Value'의 경계를 넘어 인접한 메모리 영역의 95바이트를 추가로 읽게 된다. 결과적으로, 접근이 허용되지 않은 민감한 정보(예: 다른 세션의 연결 정보)가 포함된 100바이트의 데이터가 공격자에게 전송된다.
이처럼 Out-of-Bounds Read는 클라이언트가 제어하는 입력값(특히 읽기 길이)에 대한 검증이 미흡할 경우, 허가되지 않은 메모리 영역의 정보를 공격자에게 유출하는 보안 취약점이다.
Out-of-Bounds Read 취약점의 대표적인 예시로 파장이 컸던 OpenSSL의 Heartbleed 버그(CVE-2014-0160)가 있다.
4. 원격 코드 실행 공격 과정
[그림 7] 원격 코드 실행 공격 과정
앞서 분석한 두 취약점을 조합하면 원격 코드 실행(RCE) 공격이 가능하다. [그림 7]은 이 공격이 진행되는 전체 과정을 나타낸 플로우 차트다. 해당 공격에 성공할 경우, 공격자는 목표 시스템을 최고 관리자(root) 권한으로 완전히 제어할 수 있게 된다.
5. 공격 영향 및 한계점
5.1. 공격 영향
본 취약점을 성공적으로 악용할 경우, 공격자는 최고 관리자(root) 권한으로 원격 코드 실행이 가능하며, 이는 다음과 같은 심각한 위협으로 이어질 수 있다.
•
시스템 전체에 대한 제어권 탈취: 공격자는 서버의 모든 데이터에 접근하고 시스템 설정을 임의로 변경하는 등 완전한 제어 권한을 획득할 수 있다.
•
추가 악성코드 감염: 랜섬웨어를 통해 데이터를 암호화하거나, 암호화폐 채굴 악성코드를 설치하여 시스템 자원을 무단으로 사용하는 등 추가적인 악성 행위가 가능하다.
•
내부망 확산의 거점 활용: 공격자는 감염된 서버를 교두보로 삼아, 동일 네트워크에 연결된 다른 내부 시스템을 공격하는 수평 이동(Lateral Movement)을 시도할 수 있다.
5.2. 한계점
본 취약점의 악용은 심각한 위협을 초래하지만, 두 취약점을 조합해 원격 코드 실행 공격까지 성공시키기 위한 과정은 매우 복잡하며 성공 조건 또한 제한적이다.
원격 코드 실행(RCE) 공격이 성립하기 위한 전제 조건은 다음과 같다.
1.
KSMBD 활성화: 기본 모듈이 아닌 KSMBD가 시스템에 별도로 설치되어 활성화된 상태여야 한다.
2.
외부 접근 허용: 방화벽 등 보안 정책에 의해 차단되지 않아, 외부에서 KSMBD 서비스 포트(TCP/445)로의 접근이 가능해야 한다.
3.
취약한 커널 버전 사용: 대상 시스템이 장기간 보안 업데이트가 적용되지 않은 취약한 버전의 리눅스 커널을 사용하고 있어야 한다.
4.
쓰기 권한 계정 보유: 공격자는 사전에 탈취 또는 획득한, 쓰기 권한을 보유한 SMB 계정을 가지고 있어야 한다.
위의 조건들이 모두 충족되더라도, 공격의 안정성을 확보하는 과정에서 다음과 같은 기술적 난관이 존재한다.
•
시스템 불안정 유발: 힙 스프레이와 버퍼 오버플로우 기법은 메모리의 상당 부분을 설계 의도와 다르게 변경하기 때문에 커널 패닉(Kernel Panic) 등 시스템 전체의 불안정을 유발할 가능성이 높다. 따라서 공격 과정, 공격 성공 후에도 시스템을 안정적으로 유지하기 위한 정밀한 제어 및 예외 처리와 같은 취약점 고도화 난이도가 높다.
•
힙 스프레이의 제약: 리눅스의 힙 메모리 관리자인 Slab Allocator는 멀티 코어 환경에서 CPU 코어별로 힙 메모리를 할당한다. 대부분의 서버는 멀티 코어 CPU를 탑재하고 있어 힙 스프레이를 통해 메모리 레이아웃을 예측 가능하게 제어하는 것을 어렵게 만든다.
•
메모리 할당의 불확실성(Noise): 본 공격에 사용되는 512바이트 및 1KB 크기의 힙 청크(chunk)는 KSMBD 외 다른 커널 서비스에서도 빈번하게 사용된다. 이러한 메모리 할당 경쟁은 예측 불가능성을 높여 힙 스프레이나 Use-After-Free 기법의 실패 확률을 증가시킨다.
결론적으로, 공격 성공의 어려움과 별개로 잠재적인 위협의 심각성을 고려할 때 관련 보안 조치는 반드시 필요하다.
6. 완화 및 권고 사항
Product | 취약점 영향 버전 |
Linux Kernel | 5.15.0 ~ 5.15.144 |
Linux Kernel | 6.1.0 ~ 6.1.51 |
Linux Kernel | 6.4.0 ~ 6.4.14 |
Linux Kernel | 6.5.0 ~ 6.5.1 |
Linux Kernel | 5.16.x ~ 6.0.x 모든 버전 |
Linux Kernel | 6.2.x ~ 6.3.x 모든 버전 |
1.
즉각적인 보안 업데이트 적용: 본 보고서에서 분석한 취약점에 해당하는 리눅스 커널 버전은 위의 표에 명시된 바와 같다. 해당 버전의 커널을 사용 중인 시스템은 즉시 최신 안정 버전으로 업데이트해야 한다. 시스템의 현재 커널 버전은 uname -a 명령어를 통해 확인할 수 있다.
2.
방화벽을 통한 네트워크 접근 제어 강화: KSMBD 서비스 사용이 불가피한 경우, 서비스 포트(TCP/445)는 신뢰할 수 있는 내부 네트워크 대역에서만 접근 가능하도록 방화벽 정책을 강화해야 한다. KSMBD 포트를 외부 네트워크에 개방하는 것은 본 취약점 외에도 예측하지 못한 다른 보안 위협에 시스템이 잠재적으로 노출될 가능성이 존재한다.
3.
불필요한 KSMBD 사용 자제: KSMBD는 기본 설치 모듈이 아니기 때문에 서비스가 불필요한 경우에는 설치하지 않거나 비활성화하는 것이 가장 근본적인 해결책이다. 앞서 제시된 네트워크 접근 제어는 다소 극단적인 사례지만 내부망을 통한 공격 위협까지 방어할 수는 없기 때문이다. 시스템의 KSMBD 활성화 여부는 systemctl status ksmbd 명령어를 통해 확인할 수 있다.
7. 결론
CVE-2023-4130과 CVE-2023-52440은 모두 신뢰할 수 없는 사용자 입력값, 특히 데이터 길이에 대한 검증이 미흡하여 발생한 보안 취약점이다. 실제 취약점 악용은 제한적이지만, 이러한 보안 취약점을 결합해 원격 코드 실행이 가능함을 증명했고, 추후 더 나은 방식으로 취약점을 악용할 가능성도 배제할 수 없다.
당사의 솔루션인 PurpleHound는 실전 기반 시나리오를 재구성하여 기업이 보유한 보안 장비와 시스템이 실제 공격에 얼마나 효과적으로 대응 가능한지 검증할 수 있도록 지원한다.
본 문서에서 분석한 취약점 뿐만 아니라 다른 유형의 취약점, 악성코드 활동, 파일 시스템 조작 등 다양한 위협 시나리오를 직접 실행해보며 보안 인프라의 실효성을 객관적으로 확인할 수 있다.









