将二进制数据从perl变量管道化为命令

时间:2013-02-26 05:47:44

标签: perl security dns packet-injection

对于与安全性,DNS缓存中毒和Kaminsky攻击相关的家庭作业,我正在构建一个使用Nemesis将数据包发送到本地DNS服务器的Perl脚本(这一切都是在关闭的情况下完成的,仅限主机的VMWare网络)。我已经做了一切,以自动化调用克星的过程。

我正在使用Perl专门选择随机DNS事务ID,将它们添加到我之前制作的DNS有效负载中。现在有效载荷不是DNS答案,而只是一个查询,所以我可以完善制作有效载荷ID部分的方法,并用Perl将其推送到克星。

我的代码目前是......

 #!/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-`)

我遇到的问题是,复仇者正在将数据作为字符串读取,这当然是回声。所以我需要做的是将数据作为二进制数据而不是ASCII传递给nemesis。

我想我可以使用pack()编写二进制文件,然后使用" cat / foo / bar / file |克星-..."执行有效载荷,但这不是一个最佳的解决方案,因为我不希望额外的IO时间成为我可以在(假设,它永远不会到达)真实响应之前可以尝试多少恶意DNS答案的因素收到了。

我可以研究哪些方法可以让我以二进制格式将这些数据提供给克星?

1 个答案:

答案 0 :(得分:4)

首先,

print(`...`);

简化为

system("...");

由于我们不再管道nemesis,这意味着我们可以轻松管道输入。(如果您想同时执行这两项工作,请使用IPC::Run3IPC::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);

当然,您的代码$payload实际上并不包含有效负载,而是包含它的十六进制表示形式。你可以pack 'H*'整个事情,但我认为以下是一个更好的方法:

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

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

请注意,我已将65535更改为65536,因此可以实际返回65535