Question

For a homework assignment related to security, DNS cache poisoning, and Kaminsky attacks, I am building a Perl script that uses Nemesis to send packets to a local DNS server (this is all being done on a closed, host-only VMWare network). I have done everything up to automating the process of calling nemesis.

I am using Perl specifically to choose random DNS transaction IDs, add them to the DNS payload I've crafted earlier. Right now the payload isn't a DNS answer, but just a query so I can perfect the method of crafting the ID part of the payload and pushing it to nemesis with Perl.

My code currently is...

 #!/usr/bin/perl

use strict;
use warnings;

my $dnsId = int(rand(65535));

my $idString = sprintf("%x", $dnsId);

if(length($idString) == 1){$idString = "000".$idString}
elsif(length($idString) == 2){$idString = "00".$idString}
elsif(length($idString) == 3){$idString = "0".$idString}

my $payload = $idString."01000001000000000000037777770f646e737068697368696e676c61627303636f6d0000010001";

print(`echo "$payload" | nemesis udp -S10.1.3.1 -D10.1.3.100 -x53 -y33333 -P-`)

The issue that I am having is that, nemesis is reading the data as a string, which is of course, echo's doing. So what I need to do is pipe the data to nemesis as binary data, not ASCII.

I think I could use pack() to write a binary file and then use "cat /foo/bar/file | nemesis -..." to execute the payload, but this is not a optimal solution, as I don't want the extra IO time to be a factor in how many malicious DNS answers I can attempt before the (hypothetical, it will never arrive) authentic response is received.

Whats are some methods I could look into that would allow me to feed this data in binary format to nemesis?

Was it helpful?

Solution

First,

print(`...`);

simplifies to

system("...");

Since we no longer pipe out of nemesis, that means we can easily pipe in. (If you want to do both, use IPC::Run3 or IPC::Run.)

my @cmd = ('nemesis',
   'udp', '-S10.1.3.1', '-D10.1.3.100',
   '-x53', '-y33333', '-P-' );

open(my $pipe, '|-', @cmd)
   or die $!;
binmode($pipe);
print($pipe $payload);
close($pipe);

Of course, your code's $payload doesn't actually contain the payload, but the hex representation of it. You could pack 'H*' the whole thing, but I think the following is a better approach:

my $dnsId = int(rand(65536));

my $payload = pack('n H*',
    $dnsId, '010000010000'.  # 000000
    '0000000003777777'.      # 000010
    '0f646e7370686973'.      # 000020
    '68696e676c616273'.      # 000030
    '03636f6d00000100'.      # 000040
    '01');                   # 000050

Note that I changed 65535 to 65536 so make it possible to actually return 65535.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top