FlawOpen

flawopen.com/Teardowns/cve-2023-6246-glibc-syslog-heap-buffer-overflow

● CVE-2023-6246 · CVSS 7.8 · Tinggi
Riset Keamanan · FlawOpen

CVE-2023-6246: heap overflow pada syslog glibc

CVE-2023-6246 adalah heap overflow pada syslog glibc yang dipicu header log panjang. Perbarui paket glibc yang telah diperbaiki oleh distribusi Anda.

💡 Penjelasan Sederhana (ELI5)

Bayangkan petugas mengukur paket dan labelnya dengan penggaris pendek. Label terlalu panjang sehingga perhitungan tidak mencatat ruang yang diperlukan. Petugas lalu memesan kotak kecil dan mencoba mencetak seluruh label beserta isinya di sana. Di glibc, header syslog yang panjang dapat membuat ukuran yang diperlukan tidak tercatat, sehingga logger mengalokasikan terlalu sedikit memori heap.

Konsep Kunci & Istilah

glibc
GNU C Library menyediakan fungsi inti C runtime yang digunakan sebagian besar program Linux.
__vsyslog_internal()
Implementasi internal glibc yang dipakai syslog() dan vsyslog() untuk memformat pesan serta SYSLOG_HEADER sebelum mengirimkannya ke logger sistem.
SYSLOG_HEADER
Awalan prioritas dan identitas yang diformat sebelum pesan syslog. Isinya dapat berupa nama program atau ident yang diberikan melalui openlog().
Heap-based buffer overflow (CWE-122)
Penulisan melewati batas buffer yang dialokasikan di heap. Di sini, penghitungan gagal ketika header bernama panjang tidak muat pada buffer tetap awal.

Pemetaan kerangka kerja

  • Referensi CWE untuk kelemahan yang dijelaskan dalam panduan ini: CWE-122

Analisis Akar Masalah (Root Cause)

Pemberitahuan glibc menyebut __vsyslog_internal() gagal memperbarui ukuran buffer yang diperlukan saat memformat SYSLOG_HEADER dengan nama program panjang. Pada kode rentan, panjang header l dapat sama dengan atau melebihi buffer stack 1.024 byte, sehingga cabang yang memformat isi pesan dan menetapkan bufsize dilewati. Jalur alokasi heap berikutnya lalu memakai ukuran yang belum ditetapkan atau nol, kemudian menulis header dan pesan ke ruang yang terlalu kecil. Menurut Qualys, nama panjang dapat berasal dari basename argv[0] yang dikendalikan pemanggil atau ident openlog() yang melebihi 1.024 byte; program setuid rentan yang mencatat log melalui jalur ini dapat menimbulkan dampak keamanan. Qualys mendemonstrasikan eskalasi hak akses lokal melalui su di Fedora 38. Risiko bergantung pada akses lokal, konfigurasi, dan jalur pemanggilan; ini bukan eksploit syslog jarak jauh yang umum.

Alur Serangan Langkah demi Langkah

Langkah 1

Prasyarat lokal

Proses lokal harus mencapai syslog() atau vsyslog() melalui program yang memakai glibc terdampak. Dampak keamanan memerlukan pemanggil berhak istimewa dan jalur yang tidak mengganti awalan nama program dengan ident yang aman dan terbatas.

Langkah 2

Header panjang

Header melampaui buffer awal|SYSLOG_HEADER berisi nama program panjang (__progname, berasal dari basename argv[0]) atau ident openlog() yang panjang. Qualys menyebut nilai pemicu harus melebihi 1.024 byte.

Langkah 3

Perhitungan terlewat

Cabang penghitungan ukuran dilewati|Jika header tidak muat di buffer stack 1.024 byte, kode rentan melewati cabang yang menghitung bufsize. Alokasi heap berikutnya tidak cukup untuk header dan pesan yang diformat.

Langkah 4

Dampak pada memori

Penulisan melampaui alokasi|Logger menulis header dan pesan ke buffer yang terlalu kecil sehingga merusak memori heap. Qualys menunjukkan eskalasi lokal melalui su di Fedora 38; jangan menganggap semua aplikasi atau distribusi memiliki keterjangkauan yang sama.

Kode Sumber: Rentan vs Aman

Cabang lama membiarkan bufsize bernilai nol saat header tidak muat di buffer stack, sehingga fallback heap dapat mengalokasikan ruang terlalu kecil. Perbaikan menandai buffer stack tidak dapat dipakai, memformat ke sana untuk mengukur panjang isi, mencatat l + vl, lalu memakai jalur alokasi yang ada dengan ukuran yang diperlukan. Ini cuplikan fokus upstream, bukan fungsi lengkap mandiri.

Cuplikan sumber: misc/syslog.c

IMPLEMENTASI RENTAN
/* Kutipan terfokus misc/syslog.c sebelum commit 6bd0e4efcc78. */
char bufs[1024];
char *buf = NULL;
size_t bufsize = 0;
...
if (0 <= l && l < sizeof bufs)
  {
    va_list apc;
    va_copy (apc, ap);
    int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
                                   mode_flags);
    if (0 <= vl && vl < sizeof bufs - l)
      buf = bufs;
    bufsize = l + vl;
    va_end (apc);
  }
/* Header panjang melewati cabang di atas yang menetapkan ukuran. */
PERBAIKAN AMAN & KUAT
/* Kutipan terfokus misc/syslog.c setelah commit 6bd0e4efcc78. */
char bufs[1024];
char *buf = bufs;
size_t bufsize;
...
if (0 <= l && l < sizeof bufs)
  {
    pos = bufs + l;
    len = sizeof (bufs) - l;
  }
else
  {
    buf = NULL;
    pos = bufs;
    len = sizeof (bufs);
  }
vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
if (!(0 <= vl && vl < len))
  buf = NULL;
bufsize = l + vl;

Daftar Periksa Penguatan Sistem Rekayasa

Sumber