initial commit: build code and codeql db using Docker

This commit is contained in:
Michael Hohn
2022-02-14 14:07:35 -08:00
committed by =Michael Hohn
commit f3a4b6cd36
6 changed files with 384 additions and 0 deletions

13
Dockerfile Normal file
View File

@@ -0,0 +1,13 @@
FROM ubuntu:jammy
RUN apt update && apt install openssh-server sudo -y
RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u 1000 test
RUN echo 'test:test' | chpasswd
RUN service ssh start
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Michael Hohn
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. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

325
README.org Normal file
View File

@@ -0,0 +1,325 @@
# -*- coding: utf-8 -*-
* The polkit pkexec bug
The Polkit pkexec bug [[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)]]
starts from an array bounds error w.r.t. argv and
builds on that. The out-of-bounds part of the problem is something we
can look at with the codeql range analysis library.
pkexecs main() function in polkit/src/programs/pkexec.c has the structure
#+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
Main ideas:
- Use simple range analysis on argc.
- Limit rhs / lhs of expressions to those involving argc.
Versions to check:
- All Polkit versions from 2009 onwards are vulnerable; first version in May
2009 (commit c8c3d83, “Add a pkexec(1) command”).
- we can get /a/ database [[https://lgtm.com/projects/g/freedesktop/polkit/ci/#ql][from lgtm]], the current one <2022-02-11 Fri> is
=...srcVersion_a6bedfd...=
but this one is already past the polkit patch:
#+BEGIN_SRC text
commit a6bedfd09b7bba753de7a107dc471da0db801858 (origin/master, origin/HEAD, master)
Author: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Thu Jan 27 10:16:32 2022 +0000
jsauthority: port to mozjs-91
commit a2bf5c9c83b6ae46cbd5c779d3055bff81ded683
Author: Jan Rybar <jrybar@redhat.com>
Date: Tue Jan 25 17:21:46 2022 +0000
pkexec: local privilege escalation (CVE-2021-4034)
#+END_SRC
And we can see that the problem is fixed:
#+BEGIN_SRC text
commit a2bf5c9c83b6ae46cbd5c779d3055bff81ded683
Author: Jan Rybar <jrybar@redhat.com>
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;
+ if (argc < 1)
+ {
+ exit(126);
+ }
+
/* Disable remote file access from GIO. */
setenv ("GIO_USE_VFS", "local", 1);
#+END_SRC
- So we need the [[https://gitlab.freedesktop.org/polkit/polkit.git][source code]] and build our own databases, one pre-patch, one post.
The next section goes through the build steps, using a Docker container.
** Build polkit and codeql db
We need the build setup for polkit before we can get a codeql database.
Operating system options for building:
- macOS is worth a try, but this becomes tricky early on. Using =brew= to get
dependencies works to a point, but the =mozjs-78= dependency is a specific
version of spidermonkey and building /that/ is not practical.
#+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 is the native environment for polkit, but which one? The mozjs-78
dependency is a specific version of spidermonkey; also, polkit it not used by
all distributions:
- Debian uses PolicyKit, not polkit.
- Ubuntu:
- 18.04 is also missing mozjs78 (only mozjs52)
- 22.04 has mozjs78
Ubuntu 22.04 can be run in a number of ways, on hardware, a VM (vmware,
virtualbox, multipass, etc.), or a docker
container on another host. For this problem, we can use a Docker container and
include the codeql command-line tools as well.
The definition of the container is in the ./Dockerfiles, here is the build
sequence:
#+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
Note: when using docker desktop on windows and mac, memory and cpu limits must
be raised there. Once set, the container running sequence is simply
#+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
Building on 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
Copy the db to a permanent place on the host
#+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
# TODO
# Push container for reuse, see [[https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#pushing-container-images][documentation]]
# #+BEGIN_SRC sh
# docker login ghcr.io -u USERNAME
# docker push ghcr.io/OWNER/IMAGE_NAME:latest
# docker pull ghcr.io/OWNER/IMAGE_NAME
# #+END_SRC
Next up, setting up for query development.
** Query development setup
Queries can be explored via codeql cli by itself, or using the codeql cli + the
VS Code plugin. For both cases, install the cli (see the =grab()= function
above) and download or build the codeql databases.
In the following, we assume this directory strucuture for the databases:
#+BEGIN_SRC text
cd ~/local/polkit
tree -L 2 -n
.
├── 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
** The query
(WIP) The query is developed in [[./argv-out-of-bounds.ql]]
# TODO
# ** Running the query from the command line
# #+BEGIN_SRC sh
# # Run a query against the database, saving the results to the results/
# # subdirectory of the database directory for further processing.
# codeql database run-queries -j8 --ram=20000 -- $DB $SRCDIR/example.ql
# # Get general info about available results
# codeql bqrs info --format=text -- $DB/results/cpp-sample/example.bqrs
# # Format results using bqrs decode.
# codeql bqrs decode --output=cpp-simple.csv \
# --format=csv --entities=all -- \
# $DB/results/cpp-sample/example.bqrs
# #+END_SRC

11
argv-out-of-bounds.ql Normal file
View File

@@ -0,0 +1,11 @@
/**
* @name Argv index out-of-bounds
* @kind problem
* @id cpp/example/argv-out-of-bounds
*/
import cpp
from Parameter argc
where argc.getName() = "argc"
select argc, "Definition of argc"

View File

@@ -0,0 +1,8 @@
{"folders":[
{
"path": "."
},
{
"path": "../codeql-2.7.6/ql"
}
]}

6
qlpack.yml Normal file
View File

@@ -0,0 +1,6 @@
name: cpp-polkit-argv
version: 0.0.1
dependencies:
# This uses the latest version of the codeql/cpp-all library.
# You may want to change to a more precise semver string.
codeql/cpp-all: "*"