[하루한줄] CVE-2022-24986: KCron Insecure temporary file handling

URL

CVE-2022-24986: KCron: Insecure temporary file handling

Target

  • KCron <= 21.12.2

Explain

다양한 운영체제에 대한 프로그램을 제작하는 자유 소프트웨어 커뮤니티인 KDE에서 제작한 Task Scheduler KCron에서 임시 파일 핸들링에 관한 취약점이 발견되었습니다.

권한을 가지고 있지 않은 클라이언트 코드는 src/crontablib/ctcron.cpp:CTCron::save()src/crontablib/ctSystemCron:CTSystemCron::CTSystemCron()에 대부분 존재하며 클라이언트 측에서는 두 가지 동작 모드가 존재합니다.

  1. 사용자별로 crontab 내용 저장(/usr/bin/crontab setuid-root 바이너리를 통해 수행)
  2. 시스템 전체 crontab 내용 저장(D-Bus(src/helper/kcronhelper.cpp)에서 권한을 가진 프로그램을 호출하여 수행)

두 가지 동작 모두 임시 파일이 만들어진 후 해당 메커니즘이 전달됩니다. 이때 생성된 임시 파일은 /tmp 폴더에 ‘0644’로 systemsettings.XXXXXX 형식의 이름으로 생성되어 누구나 읽을 수 있습니다. 첫 번째 모드의 경우 정보 누출이 가능하며 두 번째 모드는 권한 상승으로 이어질 가능성이 있습니다.

1. 부적절한 파일 권한으로 인한 정보 누출

임시 파일이 생성될 때 open call에 전달된 모드는 ‘0666’ 모드로 누구나 읽을 수 있습니다.

openat(AT_FDCWD, "/tmp/systemsettings.jhcCtT", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 15)

이를 통해 시스템의 사용자가 타인의 crontab 내용을 얻을 수 있습니다.

2. 파일이 름 재사용을 통한 권한 상승

생성되는 임시 파일의 이름은 한 번 주어지고, 그 후 해당 사용자가 crontab 내용을 저장할 때마다 재사용됩니다. 임시 파일의 이름을 알고 있으며 동일한 tool instance를 사용할 경우 권한 상승이 가능합니다.

CTCron::CTCron(...)
{
    ...
    QTemporaryFile tmp;
    tmp.open();
    d->tmpFileName = tmp.fileName(); // [A]
    ...
}

CTSaveStatus CTCron::save()
{
    bool saveStatus = saveToFile(d->tmpFileName); // [B]
    ...
    QFile::remove(d->tmpFileName); // [C]
    ...
}

bool CTCron::saveToFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        ...
    ...
}

파일 이름은 CTCron 객체가 인스턴스화 될 때 [A]에서 한 번 주어지고, 사용자가 수정할 때마다 [B]에서 재사용됩니다. 그 후 파일은 [C]에서 명시적으로 제거됩니다. 이를 통해 다음과 같이 악용이 가능합니다.

  • 해커가 누구나 쓸 수 있는(writable) 디렉터리를 생성하고 이 디렉터리에 대한 심볼릭 링크 공격을 준비
    1. mkdir -m 777 /tmp/evil-directory
    2. ln -s /tmp/evil-directory/evil-file /tmp/systemsttings.abcdef
  • KCron이 임시 파일을 재생성하면 대상 파일이 아직 존재하지 않으므로 호출 성공
  • /tmp/evil-directory에 파일이 생성된 후, 해커는 디렉터리에 쓰기 권한을 가지고 있으므로 파일을 삭제할 수 있습니다. 그 후 공격자의 제어 하에 crontab의 내용을 악의적으로 배치하여 arbitrary code execution이 가능합니다.