Linux Local Privilege Escalation via SUID /proc/pid/mem Write
blog.zx2c4.com
blog.zx2c4.com
But this strategy for me begs an important question: why the <bleep> is it even possible to write directly to memory over an fd? I get that "everything is a file", sure, but you've already got ptrace for insane use cases that require trashing another other process's memory (i.e. a dev toolchain).
I've been twiddling bits in C(++) almost every day for over a decade and I've never once felt the need for such a feature, except when theorizing about exploits. Alas.
Maybe i will get it when it's not 4am
Appearing in the Linux kernel makes me reconsider my avoidance of it[2]. A quick google throws up a discussion with Linus in 2003[3] which can be summarised as: don't blame the tool, blame the programmer and as a tool goto has a place.
[1] XKCD comic on the subject http://xkcd.com/292/
[2] On my infrequent visits to C++ land, I generally live in Python land where goto doesn't exist.
But please, for the love of god, can we not make this discussion thread an extended conversation on the merits or horrors of goto? Pretty please?
You still should not use gotos for regular control flow. And jumping backwards with goto is bad practice in most cases.
Note that these gotos are always local jumps (that is, they are in the same code block), at the same indentation level, and they are forward jumps (so the control flow is much the same as for a conditional). They are easy to understand and audit, and not similar to the goto examples that Dijkstra criticised for making code hard to reason about.
The commit message (10 months ago) when the vulnerability has been introduced is quite interesting:
"With recent changes there is no longer a security hazard with writing to /proc/pid/mem. Remove the #ifdef."
I'm wondering how long it will take in a proprietary software without any good commit messages to discover such bug...
[1] https://news.ycombinator.com/item?id=3472618 [2] https://news.ycombinator.com/item?id=3473068
Really? Every single distro I've tested has su compiled with PIE.
> 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!
I tested on Ubuntu 10.04 LTS, likely to be installed on many servers, and 11.04. On these two versions `su` has not been compiled with PIE.
Edit: just to make things clear: in these Ubuntu versions su is compiled without PIE, but are not vulnerable because they have kernels < 2.6.39.
$ uname -a
Linux sekhmet 3.2.1-1-ARCH #1 SMP PREEMPT Fri Jan 13 06:50:31 CET 2012 x86_64 Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz GenuineIntel GNU/Linux
$ ./mempodipper
===============================
= Mempodipper =
= by zx2c4 =
= Jan 21, 2012 =
===============================
[+] Waiting for transferred fd in parent.
[+] Executing child from child fork.
[+] Opening parent mem /proc/3196/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.
zsh: segmentation fault ./mempodipperHad to change 'exit@plt' to '<exit@plt' where it searches for the relevant function and change the program run from /bin/su to /bin/mount.
And made a separate branch for /bin/mount: http://git.zx2c4.com/CVE-2012-0056/commit/?h=mount
In the features list they state:
/proc/pid filedescriptor/memory protection
But I'm unaware how they implemented that.EDIT: sorry, misread the parent.
I don't think I'll use an extra distribution. But something like a hardened LAMP/LAPP stack for shared hosting out of the box in a distribution would be great (I think in terms of easy chrooting of users and php, secure permissions, etc.pp) However, I guess everyone has different needs and there is no one size that fits for all.
1: http://en.wikipedia.org/wiki/Grsecurity
$ ls -l /bin/su
-rws--x--x 1 root root 52144 Mar 5 2011 /bin/su
Doesn't this effectively stop the exploit? It still works when I insert the <exit@plt> function address, but I don't think it's possible to trace this without root rights, which kind of defeats the purpose.And I suspect doing so is fairly uncommon in production environments anyway.
[+] Executing child from child fork.
[+] Opening parent mem /proc/11045/mem in child.
[+] Sending fd 3 to parent.
[+] Waiting for transferred fd in parent.
I waited 2-3 minutes.<edit> Argh, I need 2.6.39, sorry.
....
[+] Executing su with shellcode.
[1] 18663 segmentation fault ./a.out