← 목록으로

CVE-2021-3156 (Sudo Baron Samedit): 힙 오버플로우로 root 획득

[CVE] CVE 분석 · 작성: 2026-07-20 03:10:34 · 수정: 2026-07-21 23:19:31 · 조회 24

취약점 개요

패치 분석

패치는 plugins/sudoers/sudoers.cset_cmnd()(및 관련 유틸리티 함수)에서 이스케이프 카운팅과 실제 버퍼 쓰기 루프의 길이 계산을 일치시키는 것으로 요약된다.

1) 필요한 버퍼 크기 계산 — 이스케이프 카운팅 오류

Before

size_t new_size = 0;
for (i = 0; i < argc; i++) {
    char *arg = argv[i];
    // 셸 모드에서 백슬래시를 이스케이프 처리할 때 필요한 추가 길이를 계산
    new_size += strlen(arg) + 1;
    if (shell_mode) {
        // 특정 조건(인자가 이스케이프 안 된 백슬래시로 끝나는 경우)에서
        // 실제로 필요한 이스케이프 문자 수보다 적게 계산되는 경로가 있었음
        new_size += count_chars_needing_escape(arg);
    }
}
user_args = malloc(new_size);

2) 실제 복사 루프 — 계산과 무관하게 원본 길이 기준으로 씀

Before

for (i = 0; i < argc; i++) {
    // 이스케이프 처리하며 실제로 써넣는 바이트 수는 원본 인자 길이·내용에 따라 결정됨
    to = fill_args_with_escaping(to, argv[i]);
    // ↑ 위에서 과소 계산된 new_size를 넘어서는 경우 여기서 힙 버퍼 경계를 넘어 씀
}

"필요한 크기를 계산하는 코드"와 "실제로 그 버퍼에 쓰는 코드"가 서로 다른 조건 분기를 타면서, 특정 인자 조합(셸 모드 + 끝나지 않은 이스케이프 시퀀스)에서 계산된 new_size보다 실제 쓰기 양이 많아지는 불일치가 발생했다.

After (1.9.5p2 / 1.8.32)

size_t new_size = 0;
for (i = 0; i < argc; i++) {
    // 계산 로직과 쓰기 로직이 공유하는 단일 이스케이프 카운팅 함수로 통합
    new_size += calc_escaped_length(argv[i], shell_mode);
}
user_args = malloc(new_size);
for (i = 0; i < argc; i++) {
    to = fill_args_with_escaping(to, argv[i]);  // 동일한 calc_escaped_length 기준을 공유
}

크기 계산과 실제 쓰기가 같은 이스케이프 카운팅 함수를 공유하도록 리팩터링해서, 두 로직이 서로 다르게 계산할 여지 자체를 제거했다.

재현 결과 (공격 흐름)

  1. 로컬 셸 접근 권한이 있는 낮은 권한 사용자가 sudoedit -s 등 셸 모드 호출 방식과, 끝이 이스케이프 안 된 백슬래시로 끝나는 인자 조합을 준비
  2. setuid root로 실행되는 sudo가 set_cmnd()에서 이 인자들을 처리하며 이스케이프 카운팅이 어긋나 힙 버퍼를 과소 할당
  3. 복사 루프가 원본 인자 길이만큼 데이터를 써넣으며 할당된 버퍼 경계를 넘어 인접 힙 청크를 오버플로우
  4. 오버플로우로 조작된 힙 메타데이터를 이용해 임의 주소 쓰기 원시 능력 확보 → 함수 포인터/GOT 덮어쓰기로 실행 흐름 전환
  5. 공격자 코드가 이미 root 권한으로 실행 중이던 sudo 프로세스 컨텍스트에서 실행 — 세부 힙 그루밍 기법은 힙 익스플로잇 기초 글 참고

영향 및 체이닝

참고자료

CVE 분석 카테고리의 글 (7/8)

  1. CVE-2024-3400: Palo Alto PAN-OS GlobalProtect 원격 코드 실행
  2. CVE-2021-44228 (Log4Shell): 로그 한 줄로 서버를 장악당한 사건
  3. CVE-2014-0160 (Heartbleed): OpenSSL 하트비트가 새어나간 메모리
  4. CVE-2017-0144 (EternalBlue): WannaCry를 전 세계로 퍼뜨린 SMB 취약점
  5. CVE-2021-34527 (PrintNightmare): 프린터 드라이버 관리 기능이 만든 권한 상승
  6. CVE-2022-0847 (Dirty Pipe): 파이프로 읽기전용 파일을 덮어쓴 취약점
  7. CVE-2021-3156 (Sudo Baron Samedit): 힙 오버플로우로 root 획득
  8. CVE-2022-22965 (Spring4Shell): 클래스 로더 조작으로 이어지는 RCE
← CVE-2022-0847 (Dirty Pipe): 파이프로 읽기전용 파일을 덮어쓴 취약점 CVE-2022-22965 (Spring4Shell): 클래스 로더 조작으로 이어지는 RCE →