
पोलकिट CVE-2021-4034 के सभी चरणों की खोज कोडक्यूएल का उपयोग करके
** अवलोकन यह रिपॉजिटरी CodeQL का उपयोग करके polkit pkexec बग की जांच करती है। इसमें शामिल है
ये पूर्ण हो चुके हैं:
अभी भी किया जाना बाकी है:
** बग Polkit pkexec बग [[https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034][(CVE-2021-4034)]] argv के संबंध में एक ऐरे बाउंड्स त्रुटि से शुरू होता है और उसी पर आधारित है। समस्या का आउट-ऑफ-बाउंड्स हिस्सा कुछ ऐसा है जिसे हम codeql रेंज विश्लेषण लाइब्रेरी के साथ देख सकते हैं।
polkit/src/programs/pkexec.c में pkexec का main() फ़ंक्शन निम्न संरचना रखता है #+begin_src text 435 main (int argc, char *argv[]) 436 { ... 534 for (n = 1; n < (guint) argc; n++) 535 { ... 568 } ... 610 path = g_strdup (argv[n]); ... #+end_src
मुख्य विचार:
जाँचने के लिए संस्करण:
2009 से सभी Polkit संस्करण कमजोर हैं; पहला संस्करण मई 2009 में (कमिट c8c3d83, "Add a pkexec(1) command")।
हम /a/ डेटाबेस [[https://lgtm.com/projects/g/freedesktop/polkit/ci/#ql][lgtm से]] प्राप्त कर सकते हैं, वर्तमान <2022-02-11 शुक्र> है =...srcVersion_a6bedfd...= लेकिन यह पहले से ही polkit पैच से आगे है: #+BEGIN_SRC text commit a6bedfd09b7bba753de7a107dc471da0db801858 (origin/master, origin/HEAD, master) Author: Xi Ruoyao [email protected] Date: Thu Jan 27 10:16:32 2022 +0000
jsauthority: port to mozjs-91
commit a2bf5c9c83b6ae46cbd5c779d3055bff81ded683 Author: Jan Rybar [email protected] Date: Tue Jan 25 17:21:46 2022 +0000
pkexec: local privilege escalation (CVE-2021-4034)
#+END_SRC और हम देख सकते हैं कि समस्या ठीक हो गई है: #+BEGIN_SRC text commit a2bf5c9c83b6ae46cbd5c779d3055bff81ded683 Author: Jan Rybar [email protected] Date: Tue Jan 25 17:21:46 2022 +0000
pkexec: local privilege escalation (CVE-2021-4034)
diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c index f1bb4e1..768525c 100644 --- a/src/programs/pkcheck.c +++ b/src/programs/pkcheck.c @@ -363,6 +363,11 @@ main (int argc, char *argv[]) local_agent_handle = NULL; ret = 126;
exit(126);
इसलिए हमें [[https://gitlab.freedesktop.org/polkit/polkit.git][स्रोत कोड]] चाहिए और अपने स्वयं के डेटाबेस बनाने होंगे, एक पैच-पूर्व, एक पैच-पश्चात।
अगला अनुभाग Docker कंटेनर का उपयोग करके निर्माण चरणों से गुजरता है।
** polkit और CodeQL DB बनाएं codeql डेटाबेस प्राप्त करने से पहले हमें polkit के लिए निर्माण सेटअप की आवश्यकता है।
निर्माण के लिए ऑपरेटिंग सिस्टम विकल्प:
macOS आज़माने लायक है, लेकिन यह जल्दी ही मुश्किल हो जाता है। निर्भरताएँ प्राप्त करने के लिए =brew= का उपयोग करना एक बिंदु तक काम करता है, लेकिन =mozjs-78= निर्भरता spidermonkey का एक विशिष्ट संस्करण है और /उसे/ बनाना व्यावहारिक नहीं है। #+BEGIN_SRC sh # autoconf... a little tricky on a mac brew install autoconf automake libtool gtk-doc export PATH="/usr/local/opt/libtool/libexec/gnubin:$PATH" ./autogen.sh
# Use meson?
brew install meson ninja intltool glib gobject-introspection
#+END_SRC
Linux polkit के लिए मूल वातावरण है, लेकिन कौन सा? mozjs-78 निर्भरता spidermonkey का एक विशिष्ट संस्करण है; साथ ही, polkit सभी वितरणों द्वारा उपयोग नहीं किया जाता है:
Ubuntu 22.04 को कई तरीकों से चलाया जा सकता है, हार्डवेयर पर, VM (vmware, virtualbox, multipass, आदि), या किसी अन्य होस्ट पर docker कंटेनर में। इस समस्या के लिए, हम एक Docker कंटेनर का उपयोग कर सकते हैं और codeql कमांड-लाइन उपकरण भी शामिल कर सकते हैं।
कंटेनर की परिभाषा ./Dockerfiles में है, यहाँ निर्माण अनुक्रम है: #+BEGIN_SRC shell # Base image for setting up the qlbuild container docker pull ubuntu:jammy docker images docker run --cpus 4 -m 8GB -ti ubuntu:jammy
# To-be-customized image
docker build -t qlbuild .
#+END_SRC नोट: विंडोज़ और मैक पर docker desktop का उपयोग करते समय, मेमोरी और सीपीयू सीमाएँ वहाँ बढ़ाई जानी चाहिए। एक बार सेट हो जाने पर, कंटेनर चलाने का अनुक्रम केवल है #+BEGIN_SRC sh # Run as daemon so it stays around even when disconnecting. docker run -d -p 127.0.0.1:2020:22 --cpus 8 -m 16GB qlbuild
# And connect
ssh -p 2020 test@localhost
#+END_SRC
Ubuntu 22.04 पर निर्माण
#+BEGIN_SRC sh
# ---------------------------------
# System setup/install, as root:
echo "deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted" >> /etc/apt/sources.list
apt-get update
apt-get install -y zile build-essential git cmake
meson ninja-build
libmozjs-78-0 libmozjs-78-dev
libdbus-1-3 libdbus-1-dev
apt-get build-dep -y policykit-1
apt install unzip
# polkit version a2bf5c9c also needs some extras
apt install duktape duktape-dev
# older meson into /usr/local/bin
pip3 install meson==0.60.3
# Or get the source and use that:
# wget https://github.com/mesonbuild/meson/archive/refs/tags/0.60.3.tar.gz
# tar zxf 0.60.3.tar.gz
# etc.
# ---------------------------------
# codeql setup -- still root
# grab -- retrieve and extract codeql cli and library
# Usage: grab version url prefix
grab() {
version=$1; shift
platform=$1; shift
prefix=$1; shift
mkdir -p $prefix/codeql-$version &&
cd $prefix/codeql-$version || return
# Get cli
wget "https://github.com/github/codeql-cli-binaries/releases/download/$version/codeql-$platform.zip"
# Get lib
wget "https://github.com/github/codeql/archive/refs/tags/codeql-cli/$version.zip"
# Fix attributes
if [ `uname` = Darwin ] ; then
xattr -c *.zip
fi
# Extract
unzip -q codeql-$platform.zip
unzip -q $version.zip
# Rename library directory for VS Code
mv codeql-codeql-cli-$version/ ql
# Remove archives
rm codeql-$platform.zip
rm $version.zip
}
grab v2.7.6 linux64 /opt
grab v2.6.3 linux64 /opt
# ---------------------------------
# As user test:
# Get polkit source
cd /tmp && git clone https://gitlab.freedesktop.org/polkit/polkit.git
# Build version 0.119
cd /tmp/polkit
git checkout 0.119
git clean -fxd
meson setup builddir
meson compile -C builddir
find builddir -name pkexec -ls
: 139269 76 -rwxr-xr-x 1 test root 76696 Feb 12 03:06 builddir/src/programs/pkexec
# ---------------------------------
# Build codeql database for version 0.119
cd /tmp/polkit
git checkout 0.119
git clean -fxd
# Run the configuration step as usual, without codeql
cd /tmp/polkit && rm -fR builddir
meson setup builddir
# Run the build step under codeql
export CODEQL=/opt/codeql-v2.7.6/codeql/codeql
$CODEQL --version
$CODEQL database create --language=cpp -s . -j 8 -v \
polkit-0.119.db \
--command='meson compile -C builddir'
# Wait for
# TRAP import complete (10.2s).
# Successfully created database at /tmp/polkit/polkit-0.119.db.
# And a quick check to make sure pkexec was seen:
unzip -v polkit-0.119.db/src.zip |grep pkexec
: 29713 Defl:N 8477 72% 2022-02-14 20:12 bb39f235 tmp/polkit/src/programs/pkexec.c
# ---------------------------------
# Build codeql database for version a2bf5c9c, the patched version (and still using
# mozjs-78)
cd /tmp/polkit
git checkout a2bf5c9c
git clean -fxd
# Run the configuration step as usual, without codeql
cd /tmp/polkit && rm -fR builddir
/usr/local/bin/meson setup builddir
# With meson 0.61, configuration runs into the error
# actions/meson.build:3:5: ERROR: Function does not take positional arguments.
# quick search leads to
# https://lore.kernel.org/all/20220111222135.693a88f2@windsurf/T/
# and from there to
# [1/1] package/gobject-introspection: bump to version 1.70.0
# Run the build step under codeql
export CODEQL=/opt/codeql-v2.7.6/codeql/codeql
$CODEQL --version
$CODEQL database create --language=cpp -s . -j 8 -v \
polkit-a2bf5c9c.db \
--command='/usr/local/bin/meson compile -C builddir'
# Wait for
# TRAP import complete (7.2s).
# Successfully created database at /tmp/polkit/polkit-a2bf5c9c.db.
# And a quick check to make sure pkexec was seen:
unzip -v polkit-a2bf5c9c.db/src.zip |grep pkexec
: 30136 Defl:N 8647 71% 2022-02-14 21:27 6af18604 tmp/polkit/src/programs/pkexec.c
#+END_SRC
db को होस्ट पर स्थायी स्थान पर कॉपी करें #+BEGIN_SRC sh # Copy from the container mkdir -p ~/local/polkit && cd ~/local/polkit scp -rq -P 2020 test@localhost:/tmp/polkit/polkit-0.119.db . scp -rq -P 2020 test@localhost:/tmp/polkit/polkit-a2bf5c9c.db .
# Keep originals
zip -rq polkit-0.119.zip polkit-0.119.db
zip -rq polkit-a2bf5c9c.zip polkit-a2bf5c9c.db
#+END_SRC
अगला, क्वेरी विकास के लिए सेटअप।
** क्वेरी विकास सेटअप क्वेरीज़ को codeql cli द्वारा अकेले, या codeql cli + VS Code प्लगइन का उपयोग करके खोजा जा सकता है। दोनों मामलों के लिए, cli स्थापित करें (ऊपर =grab()= फ़ंक्शन देखें), और [[./db]] से डेटाबेस निकालें या उन्हें [[*Build polkit and codeql db][Build polkit and codeql db]] में किए गए अनुसार बनाएं।
निम्नलिखित में, हम डेटाबेस के लिए यह निर्देशिका संरचना मानते हैं: #+BEGIN_SRC text . ├── polkit-0.119.db │ ├── codeql-database.yml │ ├── db-cpp │ ├── log │ └── src.zip ├── polkit-0.119.zip ├── polkit-a2bf5c9c.db │ ├── codeql-database.yml │ ├── db-cpp │ ├── log │ └── src.zip └── polkit-a2bf5c9c.zip #+END_SRC
** क्वेरी क्वेरी को [[./argv-out-of-bounds-*.ql]] में वृद्धिशील रूप से विकसित किया गया है।
[[./argv-out-of-bounds-0.ql]] में पहले चरण AST और चर संदर्भों का उपयोग करके परिणामों को समस्या के ज्ञात भागों तक सीमित करते हैं, जैसा कि निम्नलिखित में है।
#+BEGIN_SRC text declaration | 435 main (int argc, char *argv[]) | 436 { | ... init other var; | 534 for (n = 1; compare to argc | n < (guint) argc; update other var | n++) | 535 { | ... | 568 } | ... indexed read | 610 path = g_strdup (argv[n]); | ... | 629 if (path[0] != '/') | 630 { | ... | 632 s = g_find_program_in_path (path); | ... indexed write | 639 argv[n] = path = s; | 640 } #+END_SRC
मानों की खोज [[./argv-out-of-bounds-1.ql]] में =SimpleRangeAnalysis= लाइब्रेरी का उपयोग करने के प्रयास के साथ शुरू होती है #+begin_src javascript lowerBound(cmp.getLeftOperand().getFullyConverted()), "left lower bound", lowerBound(cmp.getRightOperand().getFullyConverted()), "right lower bound" #+end_src बाउंड्स प्रकारों के लिए सही बाउंड्स हैं, लेकिन बहुत सामान्य हैं -- वे पुनरावृत्ति के संभावित परिणामों को शामिल करते हैं। हम केवल प्रारंभिक बाउंड्स में रुचि रखते हैं जो स्थिर रूप से निर्धारित हैं, वे जो किसी भी पुनरावृत्ति से पहले हैं।
दूसरे शब्दों में, यह एक सामान्य डेटा प्रवाह समस्या नहीं है; हम केवल कुछ निष्पादन पथों के साथ प्रारंभिक मान प्रसार की जाँच करना चाहते हैं। =for= लूप इसे जटिल बनाता है, जैसा कि इसके भीतर के संचालन करते हैं।
हम वास्तव में उन निष्पादन पथों को देखना चाहते हैं जो लूप को पूरी तरह से बायपास करते हैं। यह [[./argv-out-of-bounds-1.ql]] के बाद के भागों में, =SsaDefinition= का उपयोग करके किया जाता है।
क्वेरी [[./argv-out-of-bounds-2.ql]] [[./argv-out-of-bounds-1.ql]] से खोज को साफ करती है और ज्ञात सूचकांक मान =n > 0= के साथ =n= का उपयोग करने वाले सभी स्थानों की सही पहचान करती है।
यह क्वेरी कोड के कमजोर संस्करण, =polkit-0.119.db= पर परिणाम रिपोर्ट करती है। अगला, इसे जाँचने और बढ़ाने की आवश्यकता है ताकि यह पैच किए गए संस्करण, =polkit-a2bf5c9c.db= पर कुछ भी रिपोर्ट न करे।