| 항목 | 내용 |
|---|---|
| CVE ID | CVE-2024-28085 |
| 영향 버전 | util-linux 2.40 이하 전 버전 (2013년 도입, 약 11년간 존재) |
| CVSS v3.1 | 5.5 (Medium) 전후 (배포판별 상이) |
| 공개일 | 2024-03-27 (oss-security 공개) |
| 별칭 | WallEscape |
wall 은 로그인해 있는 다른 사용자들의 터미널에 메시지를 broadcast 하는 유틸리티다.
Ubuntu/Debian 계열에서는 기본적으로 setgid tty 로 설치되어 있고, mesg 가 y 로 설정된
사용자라면 누구나 이 명령을 실행해 남의 터미널에 메시지를 띄울 수 있다. CVE-2024-28085는
wall 이 표준입력으로 받은 메시지는 이스케이프 시퀀스를 걸러내면서, 명령행 인자(argv)로
받은 메시지는 걸러내지 않는 불일치 때문에, 권한 없는 로컬 사용자가 다른 사용자의 터미널에
임의의 터미널 이스케이프 시퀀스를 주입할 수 있게 되는 취약점이다.
터미널은 화면에 그냥 텍스트만 찍는 게 아니라, 특정 바이트 시퀀스(예: ESC 로 시작하는
시퀀스)를 "커서 이동", "색상 변경", "제목 변경" 같은 명령으로 해석한다. 문제는 일부
터미널 에뮬레이터가 이 시퀀스 중 일부를 "클립보드에 텍스트 쓰기"나 "임의 문자열을 터미널에
다시 입력된 것처럼 흉내내기(키 입력 인젝션)" 같은 위험한 동작까지 지원한다는 점이다. 즉
터미널에 "텍스트를 출력하는 것"만으로도, 상대방의 클립보드를 바꾸거나 상대방이 다음에 칠
명령을 조작하는 것과 비슷한 효과를 낼 수 있다.
wall 은 메시지를 두 가지 방식으로 받을 수 있다.
- 표준입력(stdin):
wall < message.txt처럼 파일이나 파이프로 메시지를 준다. - 명령행 인자(argv):
wall "안녕하세요"처럼 메시지 자체를 인자로 준다.
두 경로 모두 결국 같은 "터미널에 메시지를 출력하는" 목적지로 가지만, 각 경로에서 메시지 문자열이 어떤 함수를 거쳐 출력되는지가 서로 달랐다는 것이 이 취약점의 핵심이다.
wall 개발자는 이전에 이미 "이스케이프 시퀀스를 걸러내고 출력하는" 안전한 함수
(fputs_careful, 위험한 바이트를 ^ 로 escape 하고 표시 폭을 제한)를 만들어 두었다. 그런데
이 함수는 표준입력으로 받은 메시지에만 적용되고 있었다. 명령행 인자로 받은 메시지는
그냥 일반 fputs() 로 그대로(필터링 없이) 출력되고 있었다.
// term-utils/wall.c — makemsg() 의 argv 처리 부분 (패치 전)
for (i = 0; i < mvecsz; i++) {
fputs(mvec[i], fs); // 필터링 없이 그대로 출력
if (i < mvecsz - 1)
fputc(' ', fs);
}즉 코드베이스 안에 "안전한 출력 함수"와 "안전하지 않은 출력 함수"가 공존했고, 어느 경로가 어느 함수를 쓰는지의 일관성이 깨져 있었던 것이 근본 원인이다. 두 경로를 박스로 그리면:
사용자 입력
│
├─ stdin 경로 ──▶ fputs_careful() ──▶ 이스케이프 문자를 '^X' 형태로 안전하게 변환 ──▶ 출력
│ (필터링 있음)
│
└─ argv 경로 ──▶ fputs() ─────────▶ 아무 변환 없이 그대로 ──▶ 출력
(필터링 없음) ↑
여기가 취약점: 같은 목적지인데 다른 관문을 통과
- 대상 시스템에서
wall이 setgid tty 로 설치되어 있고(다수 배포판 기본값), 피해자의mesg설정이y다(다수 배포판 기본값). - 권한 없는 로컬 공격자가
wall을 명령행 인자로 호출하며, 인자 안에 터미널 이스케이프 시퀀스를 포함시킨다. wall은 이 인자를 필터링 없이 그대로 로그인 중인 모든 사용자의 터미널에 broadcast 한다.- 피해자의 터미널 에뮬레이터가 해당 이스케이프 시퀀스를 지원하면, 클립보드 내용이 공격자가 원하는 문자열로 바뀌거나 그 외 터미널 조작이 발생할 수 있다.
수정 커밋(404b0781f52f7c045ca811b2dceec526408ac253, "wall: fix escape sequence
Injection [CVE-2024-28085]")은 argv 경로도 동일하게 fputs_careful() 을 쓰도록 바꿔서,
두 입력 경로가 같은 필터링 관문을 통과하게 만들었다.
--- a/term-utils/wall.c
+++ b/term-utils/wall.c
@@ makemsg() argv 처리 부분
for (i = 0; i < mvecsz; i++) {
- fputs(mvec[i], fs);
+ fputs_careful(mvec[i], fs, '^', true, TERM_WIDTH);
if (i < mvecsz - 1)
fputc(' ', fs);
}패치 후 그림으로 다시 그리면:
사용자 입력
│
├─ stdin 경로 ──▶ fputs_careful() ──▶ 이스케이프 문자를 '^X' 형태로 안전하게 변환 ──▶ 출력
│
└─ argv 경로 ──▶ fputs_careful() ──▶ 이스케이프 문자를 '^X' 형태로 안전하게 변환 ──▶ 출력
(이제 같은 함수, 같은 필터링)
두 경로가 동일한 함수를 쓰게 되면서, "어느 경로로 들어왔느냐"에 따라 필터링 여부가 달라지는 불일치 자체가 사라졌다.
- CVE-2024-28085: Escape sequence injection in util-linux wall — oss-security (공개 공지)
- Full Disclosure: Escape sequence injection in util-linux wall
- 수정 커밋 404b0781f52f7c045ca811b2dceec526408ac253 — util-linux/util-linux
- CVE-2024-28085 — NVD
- "클립보드를 바꾸는 이스케이프 시퀀스"의 정확한 바이트열과, 어떤 터미널 에뮬레이터가 이를 지원하는지의 목록은 이번에는 다루지 않았다(공개 PoC/Full Disclosure 게시물에 있을 것으로 보이나, 정적 분석 범위상 직접 대조하지 않았다).