Gheek.net

November 13, 2008

Cisco IPS support for rancid

Filed under: Cisco, perl, rancid — Tags: , , , — lancevermilion @ 1:43 pm

In order to get rancid to collect the config from an IPS module you will need to make sure you have the correct login creds in the rancid users “.cloginrc”, add the type of ips to “rancid-fe” and you also need to create the “ipsrancid” script.

Sample addition for your “.cloginrc”. Make sure this is above anything else so no other wildcards in the “.cloginrc” get caught.

add autoenable ips-primary 1
add user ips-primary rancid
add password ips-primary <>
add method ips-primary ssh

Changes required for “rancid-fe”.

'ips' => 'ipsrancid',

Create the “ipsrancid” script as “<rancid_home>/bin/ipsrancid”. Make sure you “chmod 755 <rancid_home>/bin/ipsrancid” and “chown <rancid_user>:<rancid_user_group> <rancid_home>/bin/ipsrancid”.

#!/usr/bin/perl
##
## Copyright (C) 1997-2004 by Terrapin Communications, Inc.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed
## without fee for non-commerical purposes provided that this license
## remains intact and unmodified with any RANCID distribution.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
##
## Except where noted otherwise, rancid was written by and is maintained by
## Henry Kilmer, John Heasley, Andrew Partan, Pete Whiting, and Austin Schutz.
##
#
# hacked version of Hank's rancid - this one tries to deal with Hitachi's.
#
# Modified again by Lance Vermilion (11/13/08)
# Modified from htrancid by Jeremy M. Guthrie
# Created on 5/4/2007
#
# This is meant to try handle Cisco's IPS V5.X line and on
#
# RANCID - Really Awesome New Cisco confIg Differ
#
# usage: ipsrancid [-d] [-l] [-f filename | $host]
use Getopt::Std;
getopts('dfl');
$log = $opt_l;
$debug = $opt_d;
$file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
$timeo = 90; # clogin timeout in seconds

my(@commandtable, %commands, @commands);# command lists
my(%filter_pwds); # password filtering mode

# This routine is used to print out the router configuration
sub ProcessHistory {

($new_hist_tag,$new_command,$command_string, @string) = (@_);
if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
&& defined %history) {
print eval "$command \%history";
undef %history;
}
if (($new_hist_tag) && ($new_command) && ($command_string)) {
if ($history{$command_string}) {
$history{$command_string} = "$history{$command_string}@string";
} else {
$history{$command_string} = "@string";
}
} elsif (($new_hist_tag) && ($new_command)) {
$history{++$#history} = "@string";
} else {
print "@string";
}
$hist_tag = $new_hist_tag;
$command = $new_command;
1;
}

sub numerically { $a $b; }

# This is a sort routine that will sort numerically on the
# keys of a hash as if it were a normal array.
sub keynsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort numerically keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# keys of a hash as if it were a normal array.
sub keysort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort keys(%lines)) {
$sorted_lines[$i] = $lines{$key};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# values of a hash as if it were a normal array.
sub valsort{
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
$sorted_lines[$i] = $key;
$i++;
}
@sorted_lines;
}

# This is a numerical sort routine (ascending).
sub numsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $num (sort {$a $b} keys %lines) {
$sorted_lines[$i] = $lines{$num};
$i++;
}
@sorted_lines;
}

# This is a sort routine that will sort on the
# ip address when the ip address is anywhere in
# the strings.
sub ipsort {
local(%lines) = @_;
local($i) = 0;
local(@sorted_lines);
foreach $addr (sort sortbyipaddr keys %lines) {
$sorted_lines[$i] = $lines{$addr};
$i++;
}
@sorted_lines;
}

# These two routines will sort based upon IP addresses
sub ipaddrval {
my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
$a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
}
sub sortbyipaddr {
&ipaddrval($a) &ipaddrval($b);
}

# This routine parses "show config"
sub ShowConfig {
print STDERR " In ShowConfig: $_" if ($debug);

$firstexit=0;

while () {
tr/15//d;
tr/20//d;

#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;
$skipprocess=0;

#sometimes an 'exit' appears at the top of the config, we don't want them
if ( (/^exit/) && ( ! $firstexit ) ) {
$firstexit=1;
$skipprocess=1;
}

#remove spaces left over from lame spinning progress thingy
if ( /^\s+! ------------------------------/ ) {
s/^\s+!/!/g
}

if (/^(read-only-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 \n"); next;
}
if (/^(read-write-community) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 \n"); next;
}
if (/^(trap-community-name) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 \n"); next;
}
if (/^(ntp-keys \d+ md5-key) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 \n"); next;
}
if (/^(password) / && $filter_pwds >= 1) {
ProcessHistory("","","","!$1 \n"); next;
}

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowConfig Data: $_" if ($debug);
ProcessHistory("","","","$_");
}
}
}
$clean_run=1;
print STDERR " Exiting ShowConfig: $_" if ($debug);
return(0);
}

# This routine parses single command's that return no required info
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
ProcessHistory("","","","!\n!IPS Show Version Start\n");

while () {
tr/15//d;

$skipprocess=0;

if ( /^Sensor up-time/ ) { $skipprocess=1; }
if ( ( /using.*bytes of available/i ) ) { $skipprocess=1; }

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowVersion Data: $_" if ($debug);
ProcessHistory("","","","! $_");
}
}
}
ProcessHistory("","","","!\n!IPS Show Version End\n");
print STDERR " Exiting ShowVersion: $_" if ($debug);
return(0)
}

# This routine parses single command's that return no required info
sub ShowUsersAll {
print STDERR " In ShowUsersAll: $_" if ($debug);
ProcessHistory("","","","!\n!IPS User Database Start\n");

while () {
tr/15//d;

$skipprocess=0;

s/^ CLI ID //g;
s/^ //g;
s/^\* +[0-9]+ +//g;

last if (/^$prompt/);
next if (/^(\s*|\s*$cmd\s*)$/);
if ( ! /^$prompt/) {
if ( ! $skipprocess ) {
print STDOUT " ShowUsersAll Data: $_" if ($debug);
ProcessHistory("","","","!$_");
}
}
}
ProcessHistory("","","","!\n!IPS User Database End\n!\n!\n");
print STDERR " Exiting ShowUsersAll: $_" if ($debug);
return(0)
}

# dummy function
sub DoNothing {print STDOUT;}

# Main
@commandtable = (
{'show version' => 'ShowVersion'},
{'show users all' => 'ShowUsersAll'},
{'show configuration' => 'ShowConfig'}
);
# Use an array to preserve the order of the commands and a hash for mapping
# commands to the subroutine and track commands that have been completed.
@commands = map(keys(%$_), @commandtable);
%commands = map(%$_, @commandtable);

$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);

open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
select(OUTPUT);
# make OUTPUT unbuffered if debugging
if ($debug) { $| = 1; }

# The IPS doesn't like the TERM of network so we must change it
if ( $ENV{TERM} eq 'network' ) {
$ENV{TERM} = 'vt100';
}
if ($file) {
print STDERR "opening file $host\n" if ($debug);
print STDOUT "opening file $host\n" if ($log);
open(INPUT,"<$host") || die "open failed for $host: $!\n";
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
if (defined($ENV{NOPIPE})) {
system "clogin -t $timeo -c \"$cisco_cmds\" $host $host.raw 2>&1" || die "clogin failed for $host: $!\n";
open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
} else {
open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "clogin failed for $host: $!\n";
}
}
# Change the TERM back to network
if ( $ENV{TERM} eq 'vt100' ) {
$ENV{TERM} = 'network';
}

# determine password filtering mode
if ($ENV{"FILTER_PWDS"} =~ /no/i) {
$filter_pwds = 0;
} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
$filter_pwds = 2;
} else {
$filter_pwds = 1;
}

ProcessHistory("","","","!RANCID-CONTENT-TYPE: ipsrancid\n!\n");
TOP: while() {
tr/15//d;

#strip out the stupid spinning running-config progress thingy
s/Generating current config: \.*[\|\/\-\\]//gi;

if (/^.*logout$/) {
$clean_run=1;
last;
}
if (/^Error:/) {
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
while (/($cmds_regexp)/) {
$cmd = $1;
if (!defined($prompt)) {
$prompt = ($_ =~ /^([^#]+#)/)[0];
$prompt =~ s/([][}{)(\\])/\\$1/g;
print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
}
print STDERR ("IPS COMMAND:$_") if ($debug);
if (! defined($commands{$cmd})) {
print STDERR "$host: found unexpected command - \"$cmd\"\n";
$clean_run = 0;
last TOP;
}
$rval = };
delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last TOP;
}
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
# Flush History
ProcessHistory("","","","");
# Cleanup
close(INPUT);
close(OUTPUT);

if (defined($ENV{NOPIPE})) {
unlink("$host.raw") if (! $debug);
}

# check for completeness
if (scalar(%commands) || !$clean_run ) {
if (scalar(%commands)) {
printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
}
if (!$clean_run ) {
print STDOUT "$host: End of run not found\n";
print STDERR "$host: End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
unlink "$host.new" if (! $debug);
}

October 28, 2008

Show live mysql queries

Filed under: mysql, perl — Tags: , , , — lancevermilion @ 1:10 pm

Original code found at “http://iank.org/querysniffer/&#8221;. I have stripped much of it and inserted a log of code from “http://www.perlmonks.org/?node_id=170648&#8221; to make it a little nicer. I also added a lot of stuff via variables now.

Reference “http://www.redferni.uklinux.net/mysql/MySQL-Protocol.html&#8221; for more info on reading the pcap info.

The code will return something like this. Keep in mind the question mark has a value that is passed in with the command. I do not know how to strip out the binary around it so I choose to exclude it so I can at least get the SQL commands executed. For me this told me that the application was doing a nice SQL statement to start with then doing a not so friendly one after. I was able to go back to the developer and ask him to chase this down.

SELECT * FROM sys_log  WHERE  field1 = ?  AND  timestamp >= ? AND timestamp <= ? ORDER BY timestamp DESC LIMIT 20000
INSERT INTO log_entry (timestamp,log_type,source,description) VALUES (?, ?, ?, ?)
SELECT * FROM sys_log  WHERE  field1 = ? ORDER BY timestamp DESC LIMIT 20000
INSERT INTO log_entry (timestamp,log_type,source,description) VALUES (?, ?, ?, ?)

You will need libpcap-devel, libpcap, and perl modules (Net::Pcap, Net::PcapUtils, NetPacket::Ethernet, NetPacket::IP, NetPacket::TCP, Socket). Make sure you run “perl -c” on the script.

#!/usr/bin/perl -w
use strict;
use Net::Pcap;
use Net::PcapUtils;
use NetPacket::Ethernet qw(:strip);
use NetPacket::IP qw(:strip);
use NetPacket::Ethernet;
use NetPacket::TCP;
use Socket;
use constant MYSQL_PORT => 3306;

#   Script Version
my $ver = 0.11;

#   Remove the numbers for the command type codes you
#   do not want to see.
#   Beware binary data is not filtered just yet so you
#   might end up screwing up ascii display to your terminal
#   if the right set of binary characters pass through your screen.
#use constant COM_QUERY_TYPES => qw( 2 3 5 6 11 16 22 23 24 25 );
use constant COM_QUERY_TYPES => qw( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 );
my @COM_QUERY_TYPES = (COM_QUERY_TYPES);

#   If you do not want to filter lines that only contain binary data
#   then change the value to 0;
my $filterbinary = 1;

#   MySQL Command codes
my %cmdcode = (
  0 => 'SLEEP',
  1 => 'QUIT',
  2 => 'INIT_DB',
  3 => 'QUERY',
  4 => 'FIELD_LIST',
  5 => 'CREATE_DB',
  6 => 'DROP_DB',
  7 => 'REFRESH',
  8 => 'SHUTDOWN',
  9 => 'STATISTICS',
  10 => 'PROCESS_INFO',
  11 => 'CONNECT',
  12 => 'PROCESS_KILL',
  13 => 'DEBUG',
  14 => 'PING',
  15 => 'TIME',
  16 => 'DELAYED_INSERT',
  17 => 'CHANGE_USER',
  18 => 'BINLOG_DUMP',
  19 => 'TABLE_DUMP',
  20 => 'CONNECT_OUT',
  21 => 'REGISTER_SLAVE',
  22 => 'PREPARE',
  23 => 'EXECUTE',
  24 => 'LONG_DATA',
  25 => 'CLOSE_STMT',
  26 => 'RESET_STMT',
  27 => 'SET_OPTION',
);

my $err;

#   Use network device passed in program arguments or if no
#   argument is passed, determine an appropriate network
#   device for packet sniffing using the
#   Net::Pcap::lookupdev method

my $dev = $ARGV[0];
unless (defined $dev) {
    $dev = Net::Pcap::lookupdev(\$err);
    if (defined $err) {
        die 'Unable to determine network device for monitoring - ', $err;
    }
}

#   Specify the MTU you want to use on teh interface
my $mtu = 1500;

#   Source/Destination filter
my $filter_string = "(dst 127.0.0.1)";

#   Do not print these SQL query commands when displaying SQL queries;
#   Change $do_not_print to = ''; if you do not want to filter the printing
#   of the stuff listed below
my $do_not_print = "^SET NAMES|^SET character|^SHOW VARIABLE|^SHOW COLLATION|^SET autocommit|^SET sql_mode";

#   Number of packets to capture
#   Zero or a negative number means capture packets indefinitely
#   (or until an error occurs if the $to_ms argument of
#   the open_live method is set to 0)
#   100 = 100 packets to capture
my $count = -1;

#   Optimize the capture filter
#   0 = false (will not optimize)
#   1 = true  (will optimize)
my $optimize = 0;



#                             #
# DO NOT EDIT BELOW THIS LINE #
#                             #




#   Look up network address information about network
#   device using Net::Pcap::lookupnet - This also acts as a
#   check on bogus network device arguments that may be
#   passed to the program as an argument.
#
#   Note: The address and netmask are returned as integers
#         so you will need to convert them


my ($address, $netmask);
if (Net::Pcap::lookupnet($dev, \$address, \$netmask, \$err)) {
    die 'Unable to look up device information for ', $dev, ' - ', $err;
}
#   Convert the integer returned for the addresses to decimal ip addr format
my $Address = inet_ntoa(pack "N", $address);
my $Netmask = inet_ntoa(pack "N", $netmask);

#   Create packet capture object on device

my $object;
$object = Net::Pcap::open_live($dev, $mtu, 0, 0, \$err);
unless (defined $object) {
    die 'Unable to create packet capture on device ', $dev, ' - ', $err;
}

#   Compile and set packet filter for packet capture
#   object - For the capture of TCP packets with the SYN
#   header flag set directed at the external interface of
#   the local host, the packet filter of '(dst IP) && (tcp
#   [13] & 2 != 0)' is used where IP is the IP address of
#   the external interface of the machine.  For
#   illustrative purposes, the IP address of 127.0.0.1 is
#   used in this example.

my $filter_compiled;
Net::Pcap::compile(
    $object,
    \$filter_compiled,
    "$filter_string",
    $optimize,
    $netmask
) && die 'Unable to compile packet capture filter';
Net::Pcap::setfilter($object, $filter_compiled) &&
    die 'Unable to set packet capture filter';

my $mysqlport = MYSQL_PORT;

# Print the header before the output is displayed
print "+------------------------------------------------+\n";
print "|   MySQL Live SQL command monitor (Ver. $ver)   |\n";
print "+------------------------------------------------+\n";
print "| Filter params:
|   Interface: $dev
|   IP Address: $Address
|   NetMask: $Netmask
|   MTU: $mtu
|   Src/Dst Filter: $filter_string
|   Read # of Packets: $count
|   SQL Command Types: @COM_QUERY_TYPES
|   MySQL Port: $mysqlport
";
print "+------------------------------------------------+\n";

#   Set callback function and initiate packet capture loop
Net::Pcap::loop($object, $count, \&process_packets, '' ) ||
    die 'Unable to perform packet capture';

Net::Pcap::close($object);


sub process_packets {
  my ($user_data, $header, $packet) = @_;

  ## Strip the ethernet and IP headers
  my $tcp_obj = NetPacket::TCP->decode(ip_strip(eth_strip($packet)));

  ## Strip ethernet encapsulation of captured packet
  my $tcp_obj1 = NetPacket::Ethernet::strip($packet);

  ## Decode contents of TCP/IP packet contained within
  ## captured ethernet packet
  my $ip = NetPacket::IP->decode($tcp_obj1);
  my $tcp = NetPacket::TCP->decode($ip->{'data'});

  ## If dest_port (mysql port), grab the payload and parse it
  if ($tcp_obj->{dest_port} == MYSQL_PORT)
  {
     my $data = $tcp_obj->{data};
     return unless $data;

     my $len = unpack('C3',$data);
     return unless $len > 0;

     my $type = unpack('C',substr($data,4));
     foreach (@COM_QUERY_TYPES)
     {
       if ($type == $_)
       {
          my $Data = substr($data,5);
          if ( $do_not_print ne '' )
          {
            printf ( "SQL_CMD from %s to %s: \n  %s: %s\n\n", "$ip->{'src_ip'}", "$ip->{'dest_ip'}", "$cmdcode{$type}", "$Data" ) if $Data !~ /$do_not_print/;
          }
          else
          {
            printf ( "SQL_CMD from %s to %s: \n  %s: %s\n\n", "$ip->{'src_ip'}", "$ip->{'dest_ip'}", "$cmdcode{$type}", "$Data" );
          }
      }
    }
  }
}


#
#   POD info for perldoc
#

=head1 NAME

mysqlsniff.pl: MySQL query sniffer

=head1 VERSION

 0.11 Lance V added support for all command types.
      Added filtering
      Added exit after n packets
      Added Compiled packet filter
      Added many features from http://www.perlmonks.org/?node_id=170648
 0.10

=head1 USAGE

    mysqlsniff.pl [interface]

interface is optional, defaulting to the interface returned by
Net::Pcap::lookupdev()

Note: PCAP will require root/sudo access.

=head1 DESCRIPTION

mysqlsniff.pl is a query sniffer for mysql.  It sniffs the network with
pcap, extracts queries from mysql packets, and prints them on standard
output.

=head1 PROTOCOL

see: L
COM_QUERY packets look like this:

    0f 00 00 00
    03
    "show databases"

The first three bytes are length, the fourth is the packet number for
this transaction.  I'm ignoring the packet number and only looking at
the length, to make sure it's nonzero before continuing.

The fifth byte is the command type.  QUERY is 03.  (A complete list
can be found in mysql header files).

The rest (in the case of QUERY packets) is the query string.

=head1 AUTHOR

 Lance Vermilion 
 Ian Kilgore 

=head1 COPYRIGHT & LICENSE

Copyright 2007 iContact, all rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=head1 TODO

1. Fix the binary + ascii output generated with the EXECUTE query. it should only show ascii ouput and filter the binary output.

2. Find out why the CLOSE_STMT does not show any statment for closing.

3. Inspect the errors that are returned convert them to human readable.

=head1 SEE ALSO

L

=cut

February 15, 2008

Solarwinds_report_pl

Filed under: perl, solarwinds — Tags: , — lancevermilion @ 3:32 pm

This creates a report form information that solarwinds has. Perfect for management that needs bits of information on what is going on. Unfortunately at the time I wrote this Solarwinds didn’t support anything like this.

Make sure you use the sample input file from “Solarwinds_sample_wanstatusinput“.

This script is called by Solarwinds_report.sh

Solarwinds_report.sh
#!/usr/bin/perl -w

#
# Use the DateTime perl module
#
use DateTime;
#
# Set the timezone to Phoenix time and create an object that hold the current time
#
my $dt = DateTime->now(time_zone => 'America/Phoenix' );

#
# Subtract 1 day from today (as this is suppose to run only on mondays)
#
$dt->subtract( days => 1 );
my $YESTERDAY = $dt->mdy('/');

#
# Subtract 6 day from sunday to represent last monday
#
$dt->subtract( days => 6 );
my $LASTWEEKYESTERDAY = $dt->mdy('/');

#
# print the html required to document everything.
#
print'


Weekely Network Operations Status Report

     P.breakhere {page-break-before: always}



Weekly Network Operations Status Report

' . "\n"; # # while we read everything into this script preform a variety of tasks # while () { # # Match lines that start with Circuit: follow by a space and anything till the end of the line. # print '

'. $2 . '

' . "\n" if ( /^(Circuit:)\s(.*$)/ ); # # Match lines that start with Provider follow by anything # until Type: followed a space and anything till the end of the line. # print '' . $1 . ' ' . $2 . "
\n" if ( /^(Provider.*Type:)\s(.*$)/ ); # # Match lines that start with Speed: follow by a space and anything till the end of the line. # print '' . $1 . ' ' . $2 . "
\n" if ( /^(Speed:)\s(.*$)/ ); # # Match lines that start with Primary follow by anything # until : followed a space and anything till the end of the line. # print '' . $1 . ' ' . $2 . "
\n" if ( /^(Primary.*:)\s(.*$)/ ); # # Match lines that start with Summary: follow by a space and anything till the end of the line. # print '' . $1 . ' ' . "
\n$2\n
\n" if ( /^(Summary:)\s(.*$)/ ); # # Match lines that start with N: follow by a space and anything till the end of the line. # $NODENUM = $1 if ( /^N:\s(\d+).*$/ ); # # Match lines that start with I: follow by a space and anything till the end of the line. # $INTERFACENUM = $1 if ( /^I:\s(\d+).*$/ ); if ( /^(I:)\s(\d+)/ ) { print "\n
\n"; print '' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print '
Utilization statistics
From: ' . "$LASTWEEKYESTERDAY" . ' To: ' . "$YESTERDAY" . '
Response Time Statistics
From: ' . "$LASTWEEKYESTERDAY" . ' To: ' . "$YESTERDAY" . '
Utilization GraphResponse Time Graph
' . "\n"; print '
' . "\n"; print '
' . "\n"; print 'Issues:
' . "\n"; print '' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print ' ' . "\n"; print '
N/A
' . "\n"; print '

' . "\n"; } #next if ( /^(Summary:)\s(.*$)/ ); } print ' ' . "\n";

sampleswitchmap_ThisSite_pm.txt

Filed under: perl, switchmap — Tags: , — lancevermilion @ 3:26 pm

This is a sample of “ThisSite.pm” for Switchmap when using my other add-ons.

package ThisSite;

#
# This package defines site-specific constants used by the SwitchMap
# programs.
#

# Set $GetSwitchListFromHpOpenView to 1 (true) if you have HP OpenView
# Network Node Manager (NNM) running on a machine at your site, and
# you want SwitchMap to get the list of your switches from OpenView.
# This is a good thing to do if you can, because as you add/remove
# switches from your network, SwitchMap automatically adjusts.  If you
# leave $GetSwitchListFromHpOpenView set to 0 (false), SwitchMap will
# use the static @LocalSwitches array defined below.
$GetSwitchListFromHpOpenView = 0;

# Set $GetMacIpAddrFromHpOpenView to 1 (true) if you have HP OpenView
# Network Node Manager (NNM) running on a machine at your site, and
# you want SwitchMap to get the MAC-to-IP mapping tables from
# OpenView.  This is a good thing to do if you have OpenView and you
# have OpenView configured to manage all your hosts on all your
# networks.  Otherwise, leave $GetMacIpAddrFromHpOpenView set to 0
# (false) and SwitchMap will get the data from the MacList file (see
# the README file for an explanation of the MacList file)
$GetMacIpAddrFromHpOpenView = 0;

# Set $GetSnmpCommunitiesFromHpOpenView to 1 (true) if you have HP
# OpenView Network Node Manager (NNM) running on a machine at your
# site, and you want SwitchMap to get SNMP community strings from
# OpenView.  If you have OpenView and you have configured OpenView
# with SNMP community strings, setting this variable to true lets you
# avoid maintaining 2 lists of SNMP community strings.  Otherwise,
# leave $GetSnmpCommunitiesFromHpOpenView set to 0 (false) and see the
# comment that describes the $Community variable below.
$GetSnmpCommunitiesFromHpOpenView = 0;

# If you have HP OpenView Network Node Manager at this site (any of
# the previous 3 variables are set to true), then this program will
# get information from NNM.  To do so, this program needs to know the
# DNS name of the machine that is running HP OpenView NNM.  If the
# SwitchMap programs are running on the same machine as HP OpenView
# NNM, set $OpenViewHost to 'localhost'.  If HP Openview NNM is
# running on another machine, put the name here, and this program will
# ssh to the machine.  For this to work, you have to have ssh access
# to the machine defined by $OpenViewHost such that the user that runs
# the SwitchMap scripts is able to ssh to $OpenViewHost without
# supplying a password.  If the previous 3 variables are set to 0
# above, then it doesn't matter what value $OpenViewHost has.
$OpenViewHost = 'nnm.your.domain';

# If you have HP OpenView Network Node Manager at this site and NNM is
# running on another host, then this is the ssh key to use to get the
# switch lists and MAC data and the SNMP community strings file.
# SwitchMap will use this string as the argument of the "-i" option
# when SwitchMap does ssh or scp commands to get data from the remote
# host.
$SshKeyOption = '';

# If you do not have HP OpenView Network Node Manager at this site
# ($Has_HP_OpenView = 0 above), then you'll need to run GetArp.pl
# periodically to get IP and MAC data from your CSSes/routers. The
# @routers array list the devices that the GetArp program will query.
@routers = ('router1' , 'router2');

# File protection to be applied to all output files.  This value is
# used in "chmod" calls, and is usually specified in octal (in Perl,
# scalar integers specified with a leading zero are octal, not
# decimal).  The default given here is fine for most sites.
$FileProtectionModes = 0644;   # 0644 = "-rw-r-r--"

# @LocalSwitches provides a static list of switches when you have
# $GetSwitchListFromHpOpenView set to 0.  If you have
# $GetSwitchListFromHpOpenView set to 1, SwitchMap ignores the
# contents of @LocalSwitches.  This list is used by ScanSwitch.pl
# and SwitchMap.pl.
@LocalSwitches = ('switch1' , 'switch2');

@LocalSwitchesFilter = ('switch1,Gi5/2:Gi5/1:Gi1/13:Gi1/36:Gi1/35:Gi1/14:Gi1/47:Gi1/48:Gi1/1:Gi1/2:Gi4/5:Gi4/14:Gi4/8:Gi4/6:Gi3/10:Gi3/8:Gi4/11:Gi4/13:Fa9/18:Fa9/17:Gi3/16:Gi4/10:Gi4/9:Gi4/15:Gi3/12:Gi4/4:Gi3/13:Gi3/15:Gi3/9:Gi4/16',
                  'switch2,Gi5/2:Gi5/1:Gi1/14:Gi1/13:Gi1/35:Gi1/36:Gi1/2:Gi1/1:Gi1/47:Gi1/48:Gi3/3:Gi4/8:Gi4/6:Gi4/3:Gi3/8:Gi3/7:Gi3/6:Gi3/4:Gi3/15:Gi4/10:Gi4/9:Gi4/15:Gi3/12:Gi4/4:Gi3/13:Gi3/16:Gi3/9:Gi4/16'
                  );

# If you have HP OpenView and you've set $GetSwitchListFromHpOpenView
# to 1, it may match some switches that you don't want to appear in
# the port lists.  For example, at my site we have a network connection
# to a Catalyst that we monitor with HP OpenView even though we
# don't have administrative control of the switch.  So when SwitchMap
# finds all the Catlaysts known to HP OpenView, it finds the switch
# along with all our other switches.  By putting that switch in the
# @SkipTheseSwitches list, we can make SwitchMap skip that switch.
@SkipTheseSwitches = ('ithaka-router');

# If you use the same community string for all your switches, leave
# $CmstrFile as an empty string and set the $Community variable found
# below.  If you use different community strings on different
# switches, set $CmstrFile to the full pathname of a file that defines
# the strings.  The format of the file is intentionally identical to
# that of the netmon.cmstr file used by HP OpenView NNM, so that sites
# that have NNM can simply use their existing NNM file.  The file must
# contain one community string per line, in double quotes.  Duplicates
# are ignored, as are lines that start with '#'.  On each line of the
# file, everything after the second double-quote character is ignored.
# If you have HP OpenView, set $CmstrFile to the full path name of the
# netmon.cmstr file, including the 'netmon.cmstr' at the end, and this
# program will try to open the file on the HP OpenView machine defined
# by $OpenViewHost above.  Specify the real full path name, without
# using any environment variables like OV_CONF.  If you don't have HP
# OpenView, set $CmstrFile to the full pathname of a file.  For each
# switch, this program will try the community strings defined in the
# file, one after the other.
$CmstrFile = '';

# If you use the same SNMP community string in all your switches, set
# $Community to that value.  If your switches have different community
# strings, set the $CmstrFile variable above.  When that variable is
# set to a non-empty value, SwitchMap ignores the value of the
# $Community variable.  Note: the SwitchMap programs do only "get"
# SNMP requests - no SNMP "set" requests are done.
$Community = 'SOME_COMMUNITY';

# Your DNS domain.  A typical switch in our network is "abc.ucar.edu",
# so we set this to '.ucar.edu'.
$DnsDomain = 'abc.com';

# The $WorkingDirectory variable is the full path to the working
# directory (where the code is).  This is where the program finds some
# Perl modules.
$WorkingDirectory = '.';

# The $CgiDir variable is the directory that the FindOffice.pl
# program was copied to when the SwitchMap program was installed.
# Specify the directory relative to the root directory configured into
# the web server.  The web server has to be configured to allow
# scripts that live in this directory to be executed.  On my Linux
# system running an Apache web server, the CGI directory is
# /usr/web/nets/cgi/, so I edited the /etc/apache file and added a
# line that says
#
#   ScriptAlias /nets/cgi /usr/web/nets/cgi/
#
$CgiDir = '/srv/www/cgi-bin';

# Set $HasFinder to 1 if the "finder.py" CGI program is installed on
# your web server.  Setting it to 1 will cause SwitchMap to include a
# link to the page when it creates the portlists index page.  The
# "finder.py" program accepts an IP or MAC address from the user and
# dynamically walks through network devices to find a given address.
# It then displays the switch information related to the address
# (switch, port, port label).  The program is not portable to sites
# other than NCAR, so you're not likely to have it, so you should
# probably leave $HasFinder set to 0.
$HasFinder = 0;

# Set HasConfRooms to 1 if you have a static webpage named
# conference-rooms.html that describes your site's conference rooms.
# Setting it to 1 will cause SwitchMap to include a link to the page
# when it creates the portlists index page.  NCAR has such a page.
# You're not likely to have it, so you should probably leave
# $HasConfRooms set to 0.
$HasConfRooms = 0;

# The $WebPageTrailer variable contains a site-specific trailer on
# each web page.
$WebPageTrailer = <<wpt;
Address comments or questions about this Web page to
SOMEADMIN\@$DnsDomain.
WPT # The $ExtraHelpText string contains extra site-specific text that is # written to the help file. The help file explains how the search # function is used. At my site, I initialize this variable with text # that explains how we use the "name" fields in Cisco switches at our # site. You can safely leave this empty. $ExtraHelpText = ''; # The number of days past which a port is considered "unused". $UnusedAfter = 60; # days # The campus name $Campus = "HQ"; # # EVERYTHING BELOW THIS IS USED FOR ARCHIVESETUP.PL and jimmenu # # If you want to archive the output that switchmap generates then # set this to 1, otherwise set it to 0. $Archive = 1; # If you decide to archive the output that switchmap generates then # choose how many archives you want. By default archive is expected # to run once every hour to keep a very accurate list of hosts. # The default number is 23 because using the 24 hour clock you start # counting at 00 hundred hours and end at 23 hundred hours. $ArchiveQuantity = 23; # Point this to your cgi-bin directory that is # used for switchmap we want to know the absolute # location of the cgi directory $Webaccess_cgifile = '../../../cgi-bin/FindOfficeHQ.pl'; $Absoluteloc_cgifile = "$CgiDir/FindOfficeHQ.pl"; # Point this to your switchmap web directory # directory. (ex. /var/www/html/switchmap) $Webdir = '/srv/www/htdocs/switchmap/HQ'; # # Stuff below here is strictly for Jimmenu # # If you want to see a detailed menu for each archive that is created # then set this to 1. The Desktop/Server Distribution has the detailed # menu enabled. To enable the detailed menu for archives set this to 1. # # NOTE: When setting this to 1, if you do 24 hours worth of archives, # the menu will take about 2-3 seconds per page to load since it # is loaded each time the page is changed. # # Sample menu in ascii below # # Switchmap | HQ - Phoenix, AZ # |_ Desktop/Server Distribution # |_ Archive # |_12 AM # |_ Search the portlist # |_ Switches # |_ Modules # |_ Ports # | |_ Unused Ports # | |_ Emergency Ports # | |_ Gigabit Ports per Vlan # |_ Vlans # |_ Statistics # # |_12 AM # $ArchiveMenuDetail = 1; # This is pointing to the location of which # jimmenu is installed. If your switchmap # web directory is "/var/www/html/switchmap", # then define below as /switchmap. $Webaccess_webdir_root = '/switchmap'; $Webaccess_webdir = '/switchmap/HQ'; 1;

February 14, 2008

cssSSL-PROXY-usage_pl.txt

Filed under: Cisco, perl — Tags: , , , , — lancevermilion @ 2:54 pm
#!/usr/bin/perl -w
#Author: Lance Vermilion
#Purpose: Parse the css config and find how many ssl-servers
#         are not defined under a owner and thus can be used
#         for any owner that matches the requirements of that
#         cert.
##############################################################
$ipcount = 0;
$printip = 0;
$printnoip = 0;
$ssl = "";
$vip = "";
$ip = "";


#
# Check to see if the file exists
#
if ( ! -s "/apps/rancid/lanwan_configs/$ARGV[0].txt" )
{
  die "Can NOT open /apps/rancid/lanwan_configs/$ARGV[0].txt\n"
}


#
# Load in the css config
#
my @array = `cat /apps/rancid/lanwan_configs/$ARGV[0].txt`;

#
# Walk through the config to build the IP list from ssl-proxy-list
#
foreach (@array)
{
  if ($_ =~ /^\s+ssl-server \d+ vip address (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ )
  {
    push(@array1, $1);
  }
}

print "#" x 30 . "\n";
print " $ARGV[0]\n";
print "#" x 30 . "\n";
#
# Walk through the IP list we just built and use that to search with
#
foreach (@array1)
{
$ip = $_;
    $vipcount = 0;
    $sslcount = 0;
    $ipcount++;

  #
  # Walk through the config and pair up ssl-server and owner vips
  #
  foreach (@array)
  {
    #
    # Remove spaces at the end of each line
    #
    s/\s+$//g;

    #
    # Check for the ssl-server vip address
    #
    if ( $_ =~ /^\s+ssl-server \d+ vip address $ip$/ )
    {
      $sslcount++;
      chomp($ssl = $_);
      #print "\n$ssl ($sslcount)\n";
    }

    #
    # Check for the owner/content vip address
    #
    if ( $_ =~ /^\s+vip address $ip$/ )
    {
      $vipcount++;
      chomp($vip = $_);
      #print "$vip ($vipcount)\n";
    }
  }

  #
  # Make sure we have defined sslcount and vipcount
  # aka we have at least defined them as 0.
  #
  if ($sslcount && $vipcount)
  {
    #
    # Check if we have matched the ssl-server vip address
    # and the owner/content vip address
    #
    if ( $sslcount > 0 && $vipcount > 0 )
    {
      print "$ip has: ssl-server [$sslcount], vip [$vipcount]\n";
      $printip++ if ( $sslcount > 0 && $vipcount > 0 );
    }
  }
  else
  {
    print "$ip *WARN* has: ssl-server [$sslcount], vip [$vipcount]\n" if ($ipcount > 0);
    $printnoip++ if ( $ipcount > 0);
  }
}

print "#" x 30;
print "\nTotal SSL-SERVER VIPs: $ipcount\nSSL-SERVER with VIPs: $printip\nSSL-SERVER with No VIPs: $printnoip\n";
print "#" x 30;
print "\n";

cssintparse_pl.txt

Filed under: Cisco, perl — Tags: , , — lancevermilion @ 2:53 pm

A little script to parse Cisco CSS interfaces and make them look nice and easy to read.

#!/usr/bin/perl -w
#Author: Lance Vermilion scripts(a)gheek.net
#Similar Shell Command: egrep "^service| ip add|^keepalive| ip add|^ssl\-proxy\-list|[0-9] vip|^circuit| ip add|^group| vip add| content|^owner" /usr/local/rancid/var/networking/configs/hq-css-01.abc.com
#Purpose: To search for IP addresses in a CSS config.
#####################################################

open(FH, "/usr/local/rancid/var/networking/configs/$ARGV[0]");
while ()
{
  if ( /^(keepalive|service|owner|group|circuit|ssl-proxy-list)\s(.*)/ )
  {
    if ( $inttype && $int ) {
      print "$inttype,$int,NO_IP_FOUND\n" if ! $found_ip && $inttype =~ /(keepalive|service|circuit)/;
      if ( $content ) {
      print "$inttype,$int,$content,NO_VIP_FOUND\n" if ! $found_ovip && $inttype eq 'owner';
      }
      print "$inttype,$int,NO_CONTENT_FOUND,NO_VIP_FOUND\n" if ! $found_ovip && ! $found_content && $inttype eq 'owner';
      print "$inttype,$int,NO_VIP_FOUND\n" if ! $found_gvip && $inttype eq 'group';
      print "$inttype,$int,NO_VIP_FOUND\n" if ! $found_svip && $inttype eq 'ssl-proxy-list';
    }
    $found_ip = "";
    $found_content = "";
    $found_ovip = "";
    $found_gvip = "";
    $found_svip = "";
    $found_int = 1;
    $inttype = $1;
    $int = $2;
    $int =~ s/\s+$//g;
  } # END INT CHECK
  if ( /^\!BootFlash:\s+ip\saddress\s(.*)/ )
  {
    print "$ARGV[0],$1\n";
  }
  if ( $found_int )
  {
    chomp;

    if ( $inttype eq 'ssl-proxy-list' )
    {
      if ( /^\s+ssl-server\s(\d+)\svip address\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*/ )
      {
        print  "$inttype,$int,$1,$2\n";
        #$found_int = "0";
        $found_svip = 1;
      } # END VIP CHECK
    } # END GROUP CHECK

    if ( $inttype =~ /(service|keepalive|circuit)/ )
    {
      if ( /^\s+ip address\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+.*/ )
      {
        print "$inttype,$int,$1\n";
        $found_int = "0";
        $found_ip = "1";
        $int = '';
        $inttype = '';
        next;
      } # END IP CHECK
    } # END SERVICE/KEEPALIVE CHECK

    if ( $inttype eq 'owner' )
    {
      if ( /^\s\scontent\s(.*)/ )
      {
        $content = $1;
        $content =~ s/\s+$//g;
        $found_content = 1;
      } # END CONTENT FOUND

      if ( $found_content )
      {
        if ( /^\s\s\s\svip\saddress\s(.*)/ )
        {
          $found_ovip = 1;
          print  "$inttype,$int,$content,$1\n";
          $content = '';
          next;
        } # END VIP CHECK
      } # END CONTENT
    } # END OWNER CHECK

    if ( $inttype eq 'group' )
    {
      if ( /^\s+vip address\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*/ )
      {
        print  "$inttype,$int,$1\n";
        $found_int = "0";
        $found_gvip = 1;
        $int = '';
        $inttype = '';
        next;
      } # END VIP CHECK
    } # END GROUP CHECK

  } # END FOUND INT

} # END WHILE LOOP

cpg2xml_pl.txt

Filed under: perl, xml — Tags: , , , — lancevermilion @ 2:51 pm

This may not be perfect as I didn’t work on it all that long. Hopefully it helps someone.

#!/usr/bin/perl -w
#Author: Lance Vermilion
#Purpose: Convert Coppermine directory/pictures into
#         a xml document just like picasa makes.
####################################################

#
# Define some variables
#
my $ablumname="Test";
my $localpath='/var/www/vhosts/gheek.net/httpdocs';
my $webpath='/cpg/albums/uploads/WinchesterMansion';
my @filesnormal;
my @files;


#
# We need to get a list of all the normal_[abc].jpg files
#
opendir(DIR, $localpath . $webpath);
@filesnormal = grep(/normal_.*\.jpg$/i,readdir(DIR));
closedir(DIR);

#
# Need to figure out how many pictures there are.
#
my $maxcount = scalar(@filesnormal);

foreach $file (@filesnormal) {
   $file =~ s/normal_//g;
   print "$file\n";
   push(@files, $file);
}

print "
  
- 
    $ablumname
    $maxcount
    
  - 
\n";

$maxcount--;
for ( $count=0; $count<=$maxcount; $count++ )
{
  print '    - ' . "\n";
  print "        true\n" if $count eq 1;
  print "        false\n"  if $count eq 1;
  print "        true\n"  if $count gt 1;
  print "        false\n" if $count gt 1;
  print "        true\n" if $maxcount eq $count;
  print "        false\n" if $maxcount gt $count;
  print "        true\n" if $maxcount gt $count;
  print "        false\n" if $maxcount eq $count;
  print "        \n" if $count eq 1;
  print "        \n" if $count gt 1;
  print "        normal_$files[0]\n";
  print "        $files[0]\n";
  print "        normal_$files[$count+1]\n" if $maxcount gt $count;
  print "        \n" if $maxcount eq $count;
  print "        thumb_$files[$count+1]\n" if $maxcount gt $count;;
  print "        \n" if $maxcount eq $count;
  print "        \n" if $count eq 1;
  print "        \n" if $count gt 1;
  print "        normal_$files[$maxcount-1]\n";
  print "        thumb_$files[$maxcount-1]\n";
  print "        400\n";
  print "        300\n";
  print "        thumb_$files[$count]\n";
  print "        100\n";
  print "        75\n";
  print "        normal_$files[$count]\n";
  print "        " . ($count + 1) . "\n";
  print "        $webpath/normal_$files[$count]\n";
  print "        itemNameOnly UNDEFINED (9)\n";
  print "        normal_$files[$count]\n";
  print "        itemSize UNDEFINED (9)\n";
  print '      ' . "\n";
}
  print '    ' . "\n";
  print '  
';

cisco_passwd_decrypt_pl.txt

Filed under: Cisco, perl — Tags: , , , — lancevermilion @ 2:49 pm
#!/usr/bin/perl -w
# $Id: cisco.passwords.html 3722 2006-07-28 03:53:26Z fyodor $
#
# Credits for orginal code and description hobbit@avian.org,
# SPHiXe, .mudge et al. and for John Bashinski 
# for Cisco IOS password encryption facts.
#
# Use for any malice or illegal purposes strictly prohibited!
#
#
# Usage: perl cisco_passwd_decrypt.pl some_encrypted_password
#

@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41,
          0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c,
          0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );

                $dp = "";
                ($s, $e) = ($ARGV[0] =~ /^(..)(.+)/o);
                for ($i = 0; $i < length($e); $i+=2) {
                    $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++];
                }
        print "+------------------------------------------------------+\n";
        print "| Decrypting an encrypted password from a Cisco device |\n";
        print "+------------------------------------------------------+\n";
        print "$dp\n";
        print "+------------------------------------------------------+\n";
# eof

cisco_passwd_decrypt_cfg_pl.txt

Filed under: Cisco, perl — Tags: , , , — lancevermilion @ 2:47 pm
#!/usr/bin/perl -w
# $Id: cisco.passwords.html 3722 2006-07-28 03:53:26Z fyodor $
#
# Credits for orginal code and description hobbit@avian.org,
# SPHiXe, .mudge et al. and for John Bashinski 
# for Cisco IOS password encryption facts.
#
# Use for any malice or illegal purposes strictly prohibited!
#
# Usage: cat some_cisco_config | perl cisco_passwd_decrypt_cfg.pl
#

@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41,
          0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c,
          0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );

while () {
        if (/(password|md5|key)\s+7\s+([\da-f]+)/io) {
            if (!(length($2) & 1)) {
                $ep = $2; $dp = "";
                ($s, $e) = ($2 =~ /^(..)(.+)/o);
                for ($i = 0; $i < length($e); $i+=2) {
                    $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++];
                }
                s/7\s+$ep/$dp/;
            }
        }
        print;
}
# eof

cisco_passwd_decrypt_bulk_pl.txt

Filed under: Cisco, perl — Tags: , , , — lancevermilion @ 2:45 pm
#!/usr/bin/perl -w
# $Id: cisco.passwords.html 3722 2006-07-28 03:53:26Z fyodor $
#
# Credits for orginal code and description hobbit@avian.org,
# SPHiXe, .mudge et al. and for John Bashinski 
# for Cisco IOS password encryption facts.
#
# Use for any malice or illegal purposes strictly prohibited!
#
# Usage: cat some_file_with_only_encrypted_passwds | perl cisco_passwd_decrypt_bulk.pl
#


@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41,
          0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c,
          0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );

        print "+------------------------------------------------------+\n";
        print "| Decrypting an encrypted password from a Cisco device |\n";
        print "+------------------------------------------------------+\n";
while () {
                $dp = "";
                ($s, $e) = ($_ =~ /^(..)(.+)/o);
                for ($i = 0; $i < length($e); $i+=2) {
                    $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++];
                }
        print "$dp\n";
}
        print "+------------------------------------------------------+\n";
# eof
Older Posts »

Create a free website or blog at WordPress.com.