
एक कर्नेलस्पेस सिस्कॉल इंटरसेप्टर और रैंडमाइज़्ड फॉल्टर
KRF एक कर्नलस्पेस रैंडमाइज्ड फॉल्टर है।
यह वर्तमान में Linux और FreeBSD कर्नेल का समर्थन करता है।
फॉल्ट इंजेक्शन एक सॉफ्टवेयर परीक्षण तकनीक है जिसमें किसी प्रोग्राम द्वारा कॉल किए गए फंक्शनों में विफलताएं ("फॉल्ट") प्रेरित की जाती हैं। यदि कैली उचित त्रुटि जांच और हैंडलिंग करने में विफल रहा है, तो ये फॉल्ट अविश्वसनीय एप्लिकेशन व्यवहार या शोषण योग्य कमजोरियों का कारण बन सकते हैं।
वहां मौजूद कई यूजरस्पेस फॉल्ट इंजेक्शन सिस्टम के विपरीत, KRF एक लोडेड मॉड्यूल के माध्यम से कर्नेलस्पेस में चलता है। इसके कई फायदे हैं:
LD_PRELOAD पर निर्भर नहीं करता।syscall(3) या इनलाइन असेंबली द्वारा किए गए कॉल में फॉल्ट इंजेक्ट कर सकता है।dlsym के साथ छेड़छाड़ करने से तेज और कम त्रुटि-प्रवण है।इसके कई नुकसान भी हैं:
cr0 को बदलता है। Linux में ऐसा करने का एक आर्किटेक्चर-स्वतंत्र तरीका शायद कहीं है।KRF Linux या FreeBSD सिस्टम कॉल टेबल को फिर से लिखता है: जब krfctl के माध्यम से कॉन्फ़िगर किया जाता है, तो KRF फॉल्ट योग्य syscalls को पतले रैपर से बदल देता है।
प्रत्येक रैपर फिर यह जांच करता है कि कॉल को फॉल्ट किया जाना चाहिए या नहीं, एक कॉन्फ़िगरेबल टार्गेटिंग सिस्टम का उपयोग करके जो एक विशिष्ट personality(2), PID, UID, और/या GID को लक्षित करने में सक्षम है। यदि प्रक्रिया को फॉल्ट नहीं किया जाना चाहिए, तो मूल syscall को आमंत्रित किया जाता है।
अंत में, लक्षित कॉल को एक यादृच्छिक विफलता फंक्शन के माध्यम से फॉल्ट किया जाता है। उदाहरण के लिए, एक read(2) कॉल को EBADF, EINTR, EIO, इत्यादि में से एक प्राप्त हो सकता है।
आप KRF के कार्यान्वयन के बारे में अधिक पढ़ सकते हैं हमारे ब्लॉग पोस्ट में।
नोट: यदि आपके पास Vagrant है, तो बस Vagrantfile का उपयोग करें और बिल्ड चरणों पर जाएं।
KRF को CONFIG_KALLSYMS=1 के साथ किसी भी हालिया (4.15+) Linux कर्नेल पर काम करना चाहिए।
इसमें Ubuntu 18.04 पर डिफ़ॉल्ट कर्नेल और संभवतः कई अन्य हालिया डिस्ट्रो शामिल हैं।
नोट: यदि आप Vagrant का उपयोग कर रहे हैं तो इसे अनदेखा करें।
C टूलचेन के अलावा (GCC संभवतः Linux के लिए आवश्यक है), KRF की एकमात्र निर्भरताएं libelf, कर्नेल हेडर और Ruby (>=2.4, कोड जनरेशन के लिए) होनी चाहिए।
GNU Make सभी प्लेटफार्मों पर आवश्यक है; FreeBSD को अतिरिक्त रूप से BSD Make की आवश्यकता है।
apt वाले सिस्टम के लिए:
sudo apt install gcc make libelf-dev ruby linux-headers-$(uname -r)
git clone https://github.com/trailofbits/krf && cd krf
make -j$(nproc)
sudo make install # Installs module to /lib/modules and utils to /usr/local/bin
sudo make insmod # Loads module
या, यदि आप Vagrant का उपयोग कर रहे हैं:
git clone https://github.com/trailofbits/krf && cd krf
vagrant up linux && vagrant ssh linux
# inside the VM
cd /vagrant
make -j$(nproc)
sudo make install # Installs module to /lib/modules and utils to /usr/local/bin
sudo make insmod # Loads module
या, FreeBSD के लिए:
git clone https://github.com/trailofbits/krf && cd krf
cd vagrant up freebsd && vagrant ssh freebsd
# inside the VM
cd /vagrant
gmake # NOT make!
gmake install-module # Installs module to /boot/modules/
sudo gmake install-utils # Installs utils to /usr/local/bin
gmake insmod # Loads module
KRF के तीन घटक हैं:
krfx)krfexec)krfctl)krfmesg)कर्नेल मॉड्यूल लोड करने के लिए, make insmod चलाएं। इसे अनलोड करने के लिए, make rmmod चलाएं।
पहली बार उपयोग के लिए, krfx से लॉग किए गए संदेशों को देखने के लिए एक अलग टर्मिनल पर sudo krfmesg लॉन्च करना उपयोगी हो सकता है।
KRF एक तटस्थ स्थिति में शुरू होता है: जब तक उपयोगकर्ता krfctl के माध्यम से कुछ व्यवहार निर्दिष्ट नहीं करता, तब तक कोई syscalls इंटरसेप्ट या फॉल्ट नहीं किया जाएगा:
# no induced faults, even with KRF loaded
ls
# tell krf to fault read(2) and write(2) calls
# note that krfctl requires root privileges
sudo krfctl -F 'read,write'
# tell krf to fault any program started by
# krfexec, meaning a personality of 28
sudo krfctl -T personality=28
# may fault!
krfexec ls
# tell krf to fault with a 1/100 (or 1%) probability
# note that this value is represented as a reciprocal
# so e.g. 1 means all faultable syscalls will fault
# and 500 means that on average every 500 syscalls will fault (1/500 or 0.2%)
sudo krfctl -p 100
# tell krf to fault `io` profile (and so i/o related syscalls)
sudo krfctl -P io
# krfexec will pass options correctly as well
krfexec echo -n 'no newline'
# clear the fault specification
sudo krfctl -c
# clear the targeting specification
sudo krfctl -C
# no induced faults, since no syscalls are being faulted
krfexec firefox
नोट: अधिकांश उपयोगकर्ताओं को इन फ़ाइलों को हाथ से संशोधित करने के बजाय krfctl का उपयोग करना चाहिए। FreeBSD में, ये समान मान procfs के बजाय sysctl krf.whatever के माध्यम से सुलभ हैं।
/proc/krf/rng_stateयह फ़ाइल उपयोगकर्ता को KRF के PRNG की आंतरिक स्थिति को पढ़ने और संशोधित करने की अनुमति देती है।
उदाहरण के लिए, निम्नलिखित में से प्रत्येक स्थिति को सही ढंग से अपडेट करेगा:
echo "1234" | sudo tee /proc/krf/rng_state
echo "0777" | sudo tee /proc/krf/rng_state
echo "0xFF" | sudo tee /proc/krf/rng_state
स्थिति एक 32-बिट अहस्ताक्षरित पूर्णांक है; इससे आगे इसे बदलने का प्रयास विफल हो जाएगा।
/proc/krf/targetingयह फ़ाइल उपयोगकर्ता को syscall लक्ष्यीकरण के लिए KRF द्वारा उपयोग किए जाने वाले मान सेट करने की अनुमति देती है।
नोट: KRF एक डिफ़ॉल्ट पर्सनैलिटी का उपयोग करता है जो वर्तमान में Linux कर्नेल द्वारा डिफ़ॉल्ट रूप से उपयोग नहीं की जाती है। यदि आप इसे बदलते हैं, तो आपको सावधान रहना चाहिए कि इसे ऐसा कुछ न बनाएं जिसकी Linux को परवाह हो। man 2 personality में विवरण हैं।
echo "0 28" | sudo tee /proc/krf/targeting
पर्सनैलिटी 28 krfexec में हार्डकोड की गई है, और krfexec द्वारा निष्पादित चीजों को फॉल्ट करने के लिए इसे सेट किया जाना चाहिए।
/proc/krf/probabilityयह फ़ाइल उपयोगकर्ता को किसी दिए गए (फॉल्ट योग्य) syscall के लिए फॉल्ट प्रेरित करने की संभावना को पढ़ने और लिखने की अनुमति देती है।
संभावना को एक व्युत्क्रम के रूप में दर्शाया जाता है, उदाहरण के लिए 1000 का अर्थ है कि औसतन, फॉल्ट योग्य syscalls का 0.1% फॉल्ट किया जाएगा।
echo "100000" | sudo tee /proc/krf/probability
/proc/krf/controlयह फ़ाइल उन syscalls को नियंत्रित करती है जिन्हें KRF फॉल्ट करता है।
नोट: अधिकांश उपयोगकर्ताओं को इस फ़ाइल के साथ सीधे बातचीत करने के बजाय krfctl का उपयोग करना चाहिए — पूर्व syscall नाम-से-संख्या अनुवाद स्वचालित रूप से करेगा और जब चीजें गलत होंगी तो स्पष्ट त्रुटि संदेश प्रदान करेगा।
# replace the syscall in slot 0 (usually SYS_read) with its faulty wrapper
echo "0" | sudo tee /proc/krf/control
KRF_NR_SYSCALLS से अधिक कोई भी संख्या पास करने से KRF पूरी syscall तालिका को फ्लश कर देगा, इसे तटस्थ स्थिति में लौटा देगा। चूंकि KRF_NR_SYSCALLS Linux कर्नेल के मनमाने संस्करणों के लिए आवश्यक रूप से अनुमानित नहीं है, एक बड़ी संख्या (जैसे 65535) चुनना ठीक है।
एक वैध syscall नंबर पास करना जिसमें फॉल्ट इंजेक्शन रैपर नहीं है, write(2) को फ़ाइल पर EOPNOTSUPP के साथ विफल कर देगा।
/proc/krf/log_faultsयह फ़ाइल नियंत्रित करती है कि KRF दोषपूर्ण syscalls पर कर्नेल लॉग उत्सर्जित करता है या नहीं। डिफ़ॉल्ट रूप से, कोई लॉगिंग संदेश उत्सर्जित नहीं होते हैं।
नोट: अधिकांश उपयोगकर्ताओं को इस फ़ाइल के साथ सीधे बातचीत करने के बजाय krfctl का उपयोग करना चाहिए।
# enable fault logging
echo "1" | sudo tee /proc/krf/log_faults
# disable fault logging
echo "0" | sudo tee /proc/krf/log_faults
# read the logging state
cat /proc/krf/log_faults
ENOMEM)।
personality(2) मान में कुछ और बिट्स जोड़कर किया जा सकता है।FreeBSD के लिए KRF के प्रारंभिक पोर्ट के लिए Andrew Reiter को बहुत-बहुत धन्यवाद। Andrew का काम Veracode में एप्लाइड रिसर्च ग्रुप की ओर से किया गया था।
KRF GNU GPLv3 की शर्तों के तहत लाइसेंस प्राप्त है।
सटीक शर्तों के लिए LICENSE फ़ाइल देखें।