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

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2017-5123 — PoC CVE-2017-5123 - LPE - SMEP/SMAP को बायपास करना। कोई KASLR नहीं | Kitploit
उपकरण/GitHubGitHub/c3r34lk1ll3r/cve-2017-5123
विशेषाधिकार वृद्धिशोषणलर्निंग और शिक्षाबाइनरी शोषणलैब और अभ्यास
GitHubc3r34lk1ll3r/cve-2017-5123

CVE-2017-5123

PoC CVE-2017-5123 - LPE - SMEP/SMAP को बायपास करना। कोई KASLR नहीं

रिपॉजिटरी देखें
334116 साल पहलेKitploit द्वारा समीक्षित

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

सभी देखें →

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

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

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

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

CVE-2017-5123

PoC CVE-2017-5123 - LPE - SMEP/SMAP को बायपास करना। KASLR नहीं

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

परिचय

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

यह फ़ाइल चार भागों में विभाजित है:

  1. VM सेटअप;
  2. भेद्यता विश्लेषण;
  3. शोषण;
  4. PoC।

मैं यह बताना चाहता हूं कि इस CVE का शोषण करने के कई बेहतर तरीके हैं (वास्तव में, यह केवल कर्नेल सीखने के लिए एक PoC है, इसे जंगल में उपयोग नहीं किया जा सकता) लेकिन मुझे लगता है कि यह पद्धति कर्नेल शोषण के परिचय के रूप में उपयोगी हो सकती है।

VM सेटअप

कर्नेल बिल्ड

यह भेद्यता 4c48abe91be0 में पेश की गई थी, इसलिए हमें कर्नेल का वह संस्करण बनाना होगा।

यह थोड़ा मुश्किल हो सकता है क्योंकि यह एक पुराना संस्करण है और कोड को पैच किया जाना चाहिए। मैंने पहले से पैच किए गए कर्नेल कोड के साथ एक रिपॉजिटरी और एक .config फ़ाइल बनाई है ताकि आप क्लोन और बिल्ड कर सकें।

git clone https://github.com/c3r34lk1ll3r/kernel_mirror.git
cd kernel_mirror
git checkout origin/modified_v4.14
wget https://gist.githubusercontent.com/c3r34lk1ll3r/c9c34ae86140cc7a24d0d90141686ee8/raw/52431b577a71e3fe8f89d6ce355ce9c1c54c53b6/.config
make -j 8 --output-sync=recurse

ध्यान दें कि यह कर्नेल virtio ड्राइवरों के साथ बनाया जाएगा ताकि आप वीएम से/में फ़ाइलें साझा करने के लिए virtio डिस्क का उपयोग कर सकें।

रूटफ्स सेटअप

अब, हम प्रारंभिक रूटफ्स बनाएंगे:

qemu-img create -f raw hda.raw 10G
# डिस्क को ext4 में फॉर्मेट करें
mkfs.ext4 ./hda.raw 
# इमेज के लिए माउंटपॉइंट बनाएं
mkdir /tmp/mount1
# डिस्क माउंट करें
sudo mount -o loop ./hda.raw /tmp/mount1

फिर, हमें एक बुनियादी लिनक्स वितरण स्थापित करना चाहिए, उदाहरण के लिए pacstrap या debootstrap का उपयोग करके।

sudo pacstrap /tmp/mount1 base base-devel vim

अंत में, हम सिस्टम को संशोधित कर सकते हैं:

# एक 'test' उपयोगकर्ता जोड़ें
echo 'test:x:1000:1000::/home/test:/bin/bash' | sudo tee -a /tmp/mount1/etc/passwd
# बिना पासवर्ड के
echo 'test::14871::::::' | sudo tee -a /tmp/mount1/etc/shadow 
# हम होस्ट और गेस्ट के बीच फ़ाइलें साझा करने के लिए एक virtio डिस्क माउंट कर सकते हैं
echo '/transient /home/test/shared 9p trans=virtio,version=9p2000.L,rw,user,exec 0 0' | sudo tee -a /tmp/mount1/etc/fstab
sudo mkdir -p /tmp/mount1/home/test/shared 
# sudo अनुमति होना उपयोगी है
echo '%wheel ALL=(ALL) NOPASSWD: ALL' | sudo tee -a /tmp/mount1/etc/sudoers
echo 'wheel:x:998:test' | sudo tee -a /tmp/mount1/etc/group

sudo chown -R 1000:1000 /tmp/mount1/home/test
sudo umount /tmp/mount1

यदि सब कुछ क्रम में है, तो हम अब qemu के साथ अपने परीक्षण सिस्टम का प्रयास कर सकते हैं:

qemu-system-x86_64 \
    -kernel ./kernel_mirror/arch/x86_64/boot/bzImage \
    -hda ./hda.raw \
    -m 4G \
    -cpu "Skylake-Client-IBRS,ss=on,vmx=on,hypervisor=on,tsc-adjust=on,clflushopt=on,umip=on,md-clear=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,pdpe1gb=on,ibpb=on,amd-ssbd=on,skip-l1dfl-vmentry=on,hle=off,rtm=off" \
    -smp 4 \
    -vga virtio \
    -enable-kvm \
    -nographic \
    -machine type=q35,accel=kvm \
    -virtfs "fsdriver=local,id=fs.1,path=./trans_fs,security_model=mapped,writeout=immediate,mount_tag=/transient" \
    -append "root=/dev/sda rw noquiet nokaslr console=ttyS0 loglevel=5" \
    -chardev "vc,id=vc.0,cols=1920,rows=1080" \
    -net "user,hostfwd=tcp::10022-:22" \
    -net "nic" \
    -s

भेद्यता

CVE का विवरण कहता है कि waitid सिस्टम कॉल के दौरान एक अप्रतिबंधित लेखन ऑपरेशन है।

आइए kernel/exit.c खोलें और कोड देखें:

SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
		infop, int, options, struct rusage __user *, ru)
{
    struct rusage r;
    struct waitid_info info = {.status = 0};
    long err = kernel_waitid(which, upid, &info, options, ru ? &r : NULL);
    int signo = 0;

    if (err > 0) {
        signo = SIGCHLD;
        err = 0;
        if (ru && copy_to_user(ru, &r, sizeof(struct rusage)))
            return -EFAULT;
    }
    if (!infop)
        return err;
    user_access_begin();
    unsafe_put_user(signo, &infop->si_signo, Efault);
    unsafe_put_user(0, &infop->si_errno, Efault);
    unsafe_put_user(info.cause, &infop->si_code, Efault);
    unsafe_put_user(info.pid, &infop->si_pid, Efault);
    unsafe_put_user(info.uid, &infop->si_uid, Efault);
    unsafe_put_user(info.status, &infop->si_status, Efault);
    user_access_end();
    return err;
Efault:
    user_access_end();
    return -EFAULT;
}

यह फ़ंक्शन काफी सीधा है: कुछ जांचों के बाद, unsafe_put_user(...) के विभिन्न कॉल हैं और फ़ंक्शन वापस आ जाता है।

इस फ़ंक्शन का मुख्य भाग unsafe_put_user(...) फ़ंक्शन से बना है, तो चलिए वहां चलते हैं (arch/x86/include/asm/uaccess.h):

/*
 * The "unsafe" user accesses aren't really "unsafe", but the naming
 * is a big fat warning: you have to not only do the access_ok()
 * checking before using them, but you have to surround them with the
 * user_access_begin/end() pair.
 */
#define user_access_begin()	__uaccess_begin()
#define user_access_end()	__uaccess_end()

#define unsafe_put_user(x, ptr, err_label)					\
do {										\
    int __pu_err;								\
    __typeof__(*(ptr)) __pu_val = (x);					\
    __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);	\
    if (unlikely(__pu_err)) goto err_label;					\
} while (0)

#define unsafe_get_user(x, ptr, err_label)					\
do {										\
    int __gu_err;								\  
    __inttype(*(ptr)) __gu_val;						\
    __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT);	\
    (x) = (__force __typeof__(*(ptr)))__gu_val;				\
    if (unlikely(__gu_err)) goto err_label;					\
} while (0)

टिप्पणी में एक बड़ी मोटी चेतावनी है: यदि आप unsafe_put/get_user का उपयोग करना चाहते हैं, तो आपको पहले access_ok() कॉल करना चाहिए और उन्हें user_access_begin/end() से घेरना चाहिए।

यदि हम पिछले कोड (waitid) पर एक नज़र डालें, तो हम देख सकते हैं कि access_ok() कभी नहीं बुलाया जाता है, इसलिए सिस्टम कॉल इस चेतावनी का उल्लंघन करता है।

लेकिन ये मैक्रोज़ क्या हैं?

SMAP/SMEP

SMAP और SMEP दो सुरक्षा विशेषताएं हैं जो शोषण लिखना कठिन बनाने के लिए कर्नेल में पेश की गई थीं। ध्यान दें कि ये विशेषताएं CPU द्वारा लागू की जाती हैं।

SMEP सुपरवाइज़र मोड में CPU होने पर उपयोगकर्तास्पेस कोड को निष्पादित करने से रोकता है; SMAP, इसके बजाय, उपयोगकर्ता मेमोरी तक पढ़ने/लिखने की पहुंच को अवरुद्ध करता है।

कर्नेल को उपयोगकर्ता मेमोरी में/से डेटा लिखने/पढ़ने की आवश्यकता होती है और इसे दो तरीकों से पूरा किया जा सकता है:

  1. ऐसे फ़ंक्शन हैं (जैसे copy_from_user) जो कर्नेल स्पेस में मेमोरी कॉपी करने की अनुमति देते हैं;
  2. SMAP को अस्थायी रूप से अक्षम करें

जैसा कि हम unsafe_put_user की परिभाषा में देख सकते हैं, यह फ़ंक्शन केवल x के मान को ptr द्वारा इंगित मेमोरी में कॉपी करेगा (और यदि कोई त्रुटि हुई तो err_label पर जाएगा)। हमने अभी कहा है कि कर्नेल SMAP के कारण उपयोगकर्तास्पेस तक नहीं पहुंच सकता है और यही कारण है कि इन फ़ंक्शनों को user_access_begin/end() के बीच लपेटा जाना चाहिए।

#define __uaccess_begin() stac()
#define __uaccess_end()   clac()

जैसा कि हम देख सकते हैं, user_access_begin/end केवल ASM निर्देश stac और clac हैं।

टूल डाउनलोड करें