Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2021-3560 — Eingehende Analyse von CVE-2021-3560, einer lokalen Schwachstelle zur Privilegieneskalation in Linux PolKit. Umfasst Root-Cause-Analyse, Exploit-Mechanismen und eine Demonstration der Race Condition, die zu Root-Zugriff führt. | Kitploit
Tools/GitHubGitHub/chenaotian/cve-2021-3560
Privilege EscalationSchwachstellenanalyseExploitationBinäranalyseLernen & Bildung
GitHubchenaotian/cve-2021-3560

CVE-2021-3560

Eingehende Analyse von CVE-2021-3560, einer lokalen Schwachstelle zur Privilegieneskalation in Linux PolKit. Umfasst Root-Cause-Analyse, Exploit-Mechanismen und eine Demonstration der Race Condition, die zu Root-Zugriff führt.

Repository anzeigen
936vor 4 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2021-3560 PolKit Race-Condition – Analyse zur lokalen Privilegieneskalation

[toc]

Einführung in die Schwachstelle

Schwachstellen-ID: CVE-2021-3560

Schwachstellenbewertung:

Betroffenes Produkt: Linux PolKit (polkitd)

Betroffene Systeme: Eingeführt in Quellcode 0.113; https://www.venustech.com.cn/new_type/aqtg/20210611/22788.html

  • RHEL 8
  • Fedora 21 und höher
  • Debian testing („bullseye")
  • Ubuntu 20.04

Voraussetzungen für die Ausnutzung: lokaler Linux-Zugriff; dbus + polkitd vorhanden

Auswirkung der Ausnutzung: lokale Privilegieneskalation

Quellcode-Beschaffung:

  • polkit-0.113: https://launchpad.net/debian/+source/policykit-1/0.113-5
  • accountsservice: apt source accountsservice
  • dbus: apt source dbus

Einrichtung der Umgebung

Das Standard-Ubuntu-Image ubuntu-20.04.2 ist ausreichend, um die Schwachstelle zu reproduzieren: http://old-releases.ubuntu.com/releases/20.04.2/ubuntu-20.04.2-desktop-amd64.iso

Funktionsweise der Schwachstelle

Ursache der Schwachstelle

Zuerst betrachten wir den problematischen Code

/polkit-0.113/src/polkit/polkitsystembusname.c : 388 : polkit_system_bus_name_get_creds_sync

static void
on_retrieved_unix_uid_pid (GObject              *src,
			   GAsyncResult         *res,
			   gpointer              user_data)
{
  AsyncGetBusNameCredsData *data = user_data;
  GVariant *v;

  v = g_dbus_connection_call_finish ((GDBusConnection*)src, res,
				     data->caught_error ? NULL : data->error);
  if (!v)
    {
      data->caught_error = TRUE; //某些原因失败之后设置error位
    }
  else
  {
      ··· ···//执行成功的数据处理
  }
  ··· ···
}

static gboolean
polkit_system_bus_name_get_creds_sync (PolkitSystemBusName           *system_bus_name,
				       guint32                       *out_uid,
				       guint32                       *out_pid,
				       GCancellable                  *cancellable,
				       GError                       **error)
{
  gboolean ret = FALSE;
  AsyncGetBusNameCredsData data = { 0, }; //data 被初始化为0
  ··· ···
  g_dbus_connection_call (connection,
			  "org.freedesktop.DBus",       /* name */
			  "/org/freedesktop/DBus",      /* object path */
			  "org.freedesktop.DBus",       /* interface name */
			  "GetConnectionUnixUser",      /* method */
			  g_variant_new ("(s)", system_bus_name->name),
			  G_VARIANT_TYPE ("(u)"),
			  G_DBUS_CALL_FLAGS_NONE,
			  -1,
			  cancellable,
			  on_retrieved_unix_uid_pid, //回调函数
			  &data);
  g_dbus_connection_call (connection,
			  "org.freedesktop.DBus",       /* name */
			  "/org/freedesktop/DBus",      /* object path */
			  "org.freedesktop.DBus",       /* interface name */
			  "GetConnectionUnixProcessID", /* method */
			  g_variant_new ("(s)", system_bus_name->name),
			  G_VARIANT_TYPE ("(u)"),
			  G_DBUS_CALL_FLAGS_NONE,
			  -1,
			  cancellable,
			  on_retrieved_unix_uid_pid, //回调函数
			  &data);

  while (!((data.retrieved_uid && data.retrieved_pid) || data.caught_error))
    g_main_context_iteration (tmp_context, TRUE); //等待总线那边执行完毕,uid、pid都处理完毕或异常

  if (out_uid)
    *out_uid = data.uid;
  if (out_pid)
    *out_pid = data.pid;
  ret = TRUE; //无论如何都是 TRUE?
 out:
  if (tmp_context)
    {
      g_main_context_pop_thread_default (tmp_context);
      g_main_context_unref (tmp_context);
    }
  if (connection != NULL)
    g_object_unref (connection);
  return ret;
}

In der Funktion polkit_system_bus_name_get_creds_sync wird die Authentifizierung bestimmter Anfragen durchgeführt (die konkreten Szenarien und die Logik werden später im Detail erläutert). Über den org.freedesktop.DBus-Bus werden nacheinander die Methoden GetConnectionUnixUser und GetConnectionUnixProcessID aufgerufen. Diese beiden Methoden werden vom org.freedesktop.DBus-Bus bereitgestellt und dienen dazu, die PID und die Benutzer-UID des anfragenden Prozesses zu ermitteln. Anschließend werden sie an die Callback-Funktion on_retrieved_unix_uid_pid übergeben, die die zurückgegebenen Daten verarbeitet. Danach wird blockierend gewartet, bis der Prozess auf der Bus-Seite abgeschlossen ist.

In der Funktion on_retrieved_unix_uid_pid ist zu erkennen, dass anhand des von der Bus-Seite zurückgegebenen Ausführungsergebnisses festgelegt wird, ob ein Fehler aufgetreten ist (error?), und anschließend das Fehlerflag gesetzt wird. Bei erfolgreicher Ausführung werden ordnungsgemäß die Benutzer-UID oder die Prozess-PID zurückgegeben. In der Funktion polkit_system_bus_name_get_creds_sync hingegen blockiert der Prozess, bis die Bus-Seite ein Ergebnis zurückgibt (als Kriterium für die abgeschlossene Verarbeitung gilt: sowohl UID als auch PID wurden verarbeitet oder es ist ein Fehler aufgetreten). Logisch betrachtet kann die Bus-Seite also drei Ergebnisse liefern: eine Benutzer-UID von 0 (privilegierter Benutzer), eine Benutzer-UID ungleich 0 (normaler Benutzer) oder einen Fehler. In der anschließenden Verarbeitung wird der Fehlerfall jedoch nicht behandelt: Das an die obere Ebene zurückzugebende out_uid wird direkt auf das von der Bus-Seite zurückgegebene data.uid gesetzt und ret wird direkt auf TRUE gesetzt:

  while (!((data.retrieved_uid && data.retrieved_pid) || data.caught_error))
    g_main_context_iteration (tmp_context, TRUE); //等待总线那边执行完毕,uid、pid都处理完毕或异常

  if (out_uid)
    *out_uid = data.uid;
  if (out_pid)
    *out_pid = data.pid;
  ret = TRUE; //无论如何都是 TRUE?

Es wird jedoch ein Fall übersehen: Wenn auf der DBUS-Bus-Seite ein Fehler auftritt, setzt die Callback-Funktion lediglich das Fehlerflag und kehrt zurück, ohne die Daten in data zu verarbeiten. Da data mit 0 initialisiert wird, wird out_uid in der Folge direkt auf 0 gesetzt – also auf den privilegierten Benutzer.

Wo wird diese fehlerhafte Funktion polkit_system_bus_name_get_creds_sync nun verwendet?

Auslösungspfad

Der von der Schwachstelle betroffene Prozess ist der polkitd-Prozess:

polkit ist ein Toolkit auf Anwendungsebene, das durch die Definition und Überprüfung von Berechtigungsregeln die Kommunikation zwischen Prozessen unterschiedlicher Priorität ermöglicht: Die Kontrollentscheidungen sind in einem einheitlichen Rahmen zentralisiert und legen fest, ob ein Prozess mit niedriger Priorität auf einen Prozess mit hoher Priorität zugreifen darf.

Kurz gesagt handelt es sich um einen im Hintergrund laufenden Root-Prozess, der über Interprozesskommunikation eine Berechtigungsentscheidung trifft, wenn andere Prozesse mit niedrigen Rechten auf Funktionen zugreifen möchten, die von Prozessen mit hohen Rechten bereitgestellt werden. Da dieser Prozess neu startet, sobald gdb daran angehängt wird, können wir nur auf Quellcode-Ebene analysieren, um den Auslösungspfad der verwundbaren Funktion zu finden:

polkitd wurde in großem Umfang mit dem GIO DBUS-Framework für Interprozesskommunikation entwickelt. Es lohnt sich, vorab einen Blick in das Handbuch zu werfen und sich auf einige wichtige Funktionen zu konzentrieren.

Als Nächstes analysieren wir den Auslösungspfad der Schwachstelle in polkitd:

  1. Zunächst main:

    polkit-0.113\src\polkitbackend\polkitd.c : 155 : main

    int
    main (int    argc,
          char **argv)
    {
      ··· ···
      ··· ···
    
      loop = g_main_loop_new (NULL, FALSE);
    
      sigint_id = g_unix_signal_add (SIGINT,
                                     on_sigint,
                                     NULL);
    
Tool herunterladen