[하루한줄] CVE-2022-0847: Dirty Pipe - 리눅스 커널의 임의 파일 쓰기 취약점

URL

https://dirtypipe.cm4all.com/

Target

  • Linux Kernel 5.8

Explain

Linux 커널에서 임의 파일을 덮어쓸 수 있는 취약점의 세부 정보가 공개되었습니다. 해당 취약점은 CVE-2016-5195(Dirty Cow)와 유사하다는 점에서 Dirty Pipe로 명명되었습니다.

취약점은 잘못된 Unix 파이프 처리로 인해 발생합니다. 예제는 아래와 같습니다.

#include <unistd.h>
int main(int argc, char **argv) {
  for (;;) write(1, "AAAAA", 5);
}
// ./writer >foo

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char **argv) {
  for (;;) {
    splice(0, 0, 1, 0, 2, 0);
    write(1, "BBBBB", 5);
  }
}
// ./splicer <foo |cat >/dev/null

writer는 파일에 AAAAA를 쓰고, splicer는 splice함수)를 사용해 해당 파일에서 파이프로 데이터를 전송한 뒤 파이프에 BBBBB 를 씁니다. 이때 커널의 파이프 버퍼는 각각 페이지를 참조하는 struct pipe_buffer 링으로 구현되는데, 파이프에 대한 첫 번째 쓰기는 4KB의 페이지를 할당합니다. 첫 번째 쓰기에서 페이지를 완전히 채우지 않았다면 다음 쓰기가 새 페이지를 할당하는 대신 기존 페이지에 추가될 수 있습니다. 결과적으로 위 예제에서 파일에는 쓰인 적 없던 BBBBB 문자열이 파이프를 통해 쓰여지고 이는 프로세스 권한과 관계없이 발생하기 때문에 취약점을 악용하면 낮은 권한의 프로세스가 root 권한의 파일또한 수정할 수 있습니다.

또한 페이지 캐시는 항상 커널에서 쓰기 가능하고 파이프에 쓰는 것은 어떠한 권한도 확인하지 않기 때문에 변경 불가능 파일, 읽기 전용 btrfs 스냅샷 및 읽기 전용 마운트(CD-ROM 마운트 포함)에서도 취약점이 악용될 수 있습니다.

PoC는 링크 에서 확인할 수 있습니다.

Reference

https://attackerkb.com/topics/UwW7SVPaPv/cve-2022-0847/rapid7-analysis

https://haxx.in/files/dirtypipez.c PoC