Implement a simple Nids_perl through Perl

Source: Internet
Author: User
Tags ftp commands unpack vars ftp protocol

With the in-depth development of network security requirements, network-based intrusion detection technology has become an important and interesting research direction. Want to learn NIDs technology in addition to read some ready-made information and some open-source system source, the best way is to write a nids program, only then can really realize some nids realization needs and design beauty.

In essence, NIDs is just a network traffic analysis tool, through the analysis of network traffic to identify some known or unknown attack behavior, one of the simplest NIDs completed the main task is to grasp the package-> protocol decoding-> matching, known as Perl is a very powerful scripting language, In particular, its string processing capability can easily be implemented to match malicious features in network traffic. Perl, of course, is just a scripting language, and its execution efficiency is not allowed for a real mass-flow production environment, but the simplicity and power of Perl are great for achieving a simple nids, and I'll introduce a simple nids framework with Perl, We will implement it under Linux, similar on other operating systems.

One of the great features of Perl is its massive CPAN module library, many of the features you want to implement can be found in ready-made modules, all you have to do is install those modules, and the management and use of Perl modules and object-oriented features is not introduced here, please refer to the relevant information, For example, O ' Reilly published Advanced Perl programming. Before you write a network traffic analysis script in Perl, you need to install some of the underlying scratch and basic packet decoding modules, including the following:
Http://www.tcpdump.org/release/libpcap-0.8.1.tar.gz
Base of the bottom of the scratch bag library.

Http://www.cpan.org/authors/id/T/TI/TIMPOTTER/Net-Pcap-0.04.tar.gz
Libpcap's Perl interface.

Http://www.cpan.org/authors/id/T/TI/TIMPOTTER/Net-PcapUtils-0.01.tar.gz
The wrapper of the Net-pcap module, which wraps the Net-pcap function, makes it easier to call grab packets in Perl.

Http://www.cpan.org/authors/id/T/TI/TIMPOTTER/NetPacket-0.03.tar.gz
For basic IP/TCP/UDP, such as packet decoding module, stripping the various protocol headers, extract each field.

The following code demonstrates the simplest NIDs framework with a basic SMB and FTP protocol decoding module. This program realizes the simplest NIDs function, is oriented to the single package, does not care about the package status, does not have the advanced commercial NIDs product such as the flow reorganization, the package status and the Application layer protocol tracking and so on function. To improve the accuracy of the detection, and snort directly match the data area is different, this script implemented two application layer protocol: SMB, FTP Simple decoding, decoding is completely oriented to NIDs, the code is not carefully tested may have problems.

(a) perl-ids.pl to achieve grasp and detection analysis of the main program.

Copy Code code as follows:

#!/usr/bin/perl
#
# Comments/suggestions to stardust at xfocus Dot org
#
#
# $Id: perl-ids.pl,v 1.16 2004/03/04 21:51:12 Stardust Exp $
#
# Refer to all relevant modules
Use Net::P caputils;
Use Netpacket::ethernet QW (: Strip);
Use NETPACKET::TCP;
Use Netpacket::ip QW (:p rotos);
Use NETPACKET::SMB;
Use netpacket::ftp;
# define log file name
$workingdir = "./";
$attacklog = "Attack.log";
$monitorlog = "Monitor.log";
# running in the next process mode
Daemon ();
Sub Daemon {
Unless (fork) {
Sniffloop ();
Exit 0;
}
Exit 1;
}
# Grab Bag loop
Sub Sniffloop {
# Enter working directory
ChDir ("$workingdir");
# Open log File
Open (Attacklog, ">> $attacklog");
Open (Monitorlog, ">> $monitorlog");
# set file read-write to non-buffered mode
Select (Attacklog); $ + +; Select (Monitorlog); $ + +; Select (STDOUT); $ + +;
# set up the signal processing function, because the program runs in the background, the exit needs to use the signal processing function to do some cleanup work
$SIG {"INT"} = ' handleint ';
$SIG {"TERM"} = ' handleterm ';
# into the grab callback function
Net::P caputils::loop (&sniffit, Snaplen => 1800, Promisc => 1, FILTER => ' TCP or UDP ', DEV => ' eth0 ');
}
Sub Sniffit {
My ($args, $header, $packet) = @_;
# Decode IP Packets
$ip = Netpacket::ip->decode (Eth_strip ($packet));
# TCP protocol
if ($ip->{proto} = = ip_proto_tcp) {
# Decoding TCP Packets
$tcp = Netpacket::tcp->decode ($ip->{data});
# Check packages from the SMB client
if ($tcp->{dest_port} = = = 139) ($tcp->{dest_port} = = 445)) {
# If the destination port is 139 or 445 and is considered an SMB protocol packet, check accordingly
Smbclientcheck ($ip->{src_ip}, $tcp->{src_port}, $ip->{dest_ip}, $tcp->{dest_port}, $tcp->{data});
} elsif ($tcp->{dest_port} = = 21) {
# If the destination port is 21, consider the FTP protocol, do the corresponding check
Ftpclientcheck ($ip->{src_ip}, $tcp->{src_port}, $ip->{dest_ip}, $tcp->{dest_port}, $tcp->{data});
} else {}
# UDP protocol
} elsif ($ip->{proto} = = = Ip_proto_udp) {
} else {}
}
Sub Smbclientcheck {
My ($src _ip, $src _port, $dest _ip, $dst _port, $data) = @_;
# calling SMB decoding module decoding
$SMB = Netpacket::smb->decode ($data);
# If the decoding succeeds
if ($SMB->{valid}) {
# example detects a heap-breaking vulnerability caused by the ASN.1 decoding error of newly advertised eeye
# bid:9633,9635 cveid:can-2003-0818 nsfocusid:6000
# If the SMB command is session Setup AndX
if ($smb->{cmd} = = 0x73) {
# If you set the extended security negotiation bit, it means there's a security Blob in the package.
if ($SMB->{flags2} & F2_extsecurineg) {
# match the OID in the attack packet with the regular expression and the malformed data string that caused the error
# because it is not based on the principle of testing, coupled with the flexibility of ASN.1 coding, such detection will lead to false
if ($SMB->{bytecount} > 0) && ($smb->{bytes} =~ m/x06x06x2bx06x01x05x05x02.*[xa1x05x23x03x03x01x07 x84xffxffxff]/)) {
# log file
Logalert ($src _ip, $src _port, $dest _ip, $dst _port, "ASN.1 malform, encode attack!");
}
}
}
}
}
Sub Ftpclientcheck {
My ($src _ip, $src _port, $dest _ip, $dst _port, $data) = @_;
# Call FTP decoding module decoding
$ftp = Netpacket::ftp->decode ($data);
# If the decoding succeeds
if ($ftp->{valid}) {
# Sample detects newly announced Serv-u < 5.0.0.4 FTP server MDTM command overflow attacks
# bid:9751 nsfocusid:6078
# traverse the FTP commands decoded from the packet and their parameters
for (My $i = 1; $i <= $ftp->{cmdcount}; $i + +) {
My $cmd = "cmd". " $i ";
My $para = "para". $i ";
# If the ftp command is MDTM
if (UC ($ftp->{$cmd}) eq "MDTM") {
# matches an overflow parameter string with a regular expression, which shows the regular
# The strong expression, with this match can be detected from the principle of the malformed parameter string
if ($ftp->{$para} =~ m/d{14}[+-]s{5,}s+s{1,}/) {
Logalert ($src _ip, $src _port, $dest _ip, $dst _port, "Serv-u < v5.0.0.4 MDTM command long timezone string Overflow attack!");
}
}
}
}
}
# Record Attack alarms
Sub Logalert {
My ($src _ip, $src _port, $dest _ip, $dst _port, $message) = @_;
my $nowtime = localtime;
printf Attacklog ("%s%s:%s->%s:%s%s", $nowtime, $src _ip, $src _port, $dest _ip, $dst _port, $message);
printf ("%s%s:%s->%s:%s%s", $nowtime, $src _ip, $src _port, $dest _ip, $dst _port, $message);
}
# Record Monitoring information
Sub LogMonitor {
My ($src _ip, $src _port, $dest _ip, $dst _port, $message) = @_;
my $nowtime = localtime;
printf Monitorlog ("%s%s:%s->%s:%s%s", $nowtime, $src _ip, $src _port, $dest _ip, $dst _port, $message);
printf ("%s%s:%s->%s:%s%s", $nowtime, $src _ip, $src _port, $dest _ip, $dst _port, $message);
}
# int Signal Processing routines
Sub Handleint {
CleanUp ();
Exit (0);
}
# term Signal processing routines
Sub Handleterm {
CleanUp ();
Exit (0);
}
# clean up, the main job is to close the file handle
Sub CleanUp {
Close (Attacklog); Close (Monitorlog);
}

(ii) FTP.PM FTP protocol decoding module, the data packet to extract the FTP command and the corresponding parameters, this file needs to be copied to the Netpacket series module in the directory, usually in/usr/lib/perl5/site_perl/5.x.x/netpacket/

Copy Code code as follows:

#
# Netpacket::ftp-decode FTP Packets
#
# Comments/suggestions to stardust at xfocus Dot org
#
#
# $Id: ftp.pm,v 1.16 2004/03/03 l1:16:20 Stardust Exp $
#
Package netpacket::ftp;
Use strict;
Use VARs qw ($VERSION @ISA @EXPORT @EXPORT_OK%export_tags);
Use Netpacket;
My $myclass;
BEGIN {
$myclass = __package__;
$VERSION = "0.01";
}
Sub Version () {"$myclass v$version"}
BEGIN {
@ISA = QW (exporter netpacket);
# Items to export in callers namespace by default
# (move infrequently used names to @EXPORT_OK below)
@EXPORT = QW (
);
# Other items we are prepared to export if requested
@EXPORT_OK = QW (
);
# Tags:
%export_tags = (
All => [@EXPORT, @EXPORT_OK],
);
}
#
# Decode the packet
#
# FTP protocol text see Rfc959,http://www.ietf.org/rfc/rfc0959.txt
# Common FTP commands
My @ftp_cmds = QW (Abor ACCT ALLO appe cdup CWD DELE help LIST MKD MODE NLST
NOOP Pass PASV PORT PWD QUIT REIN REST RETR RMD rnfr rnto
SITE smnt STAT STOR stou stru syst TYPE USER xcup xcwd
Xpwd XRMD lprt lpsv ADAT AUTH CCC CONF ENC MIC Pbsz
FEAT OPTS eprt epsv LANG MDTM MLSD mlst SIZE digt CLNT
);
Sub Decode {
my $class = shift;
My ($data) = @_;
My $self = {};
my $cmdhead = 0;
my $cmdtail = 0;
My @parts = ();
my $cmdcount = 0;
my $returnindex = 0;
My $data _len = Length ($data);
# If the data length is too short, do not process
if ($data _len >= 4) {
# The number of FTP commands in a package
$self->{cmdcount} = 0;
# Search for carriage return, previously thought to be a command line, note that a package may contain multiple FTP commands
while (($returnindex = index ($data, "x0a", $cmdhead)) (>=0) ($returnindex < 0) && (($data _len-$cmdhead ) >= 4)) {
# Adjust a command line string tail pointer
if ($returnindex < 0) {
$cmdtail = $data _len-1;
} else {
$cmdtail = $returnindex;
}
if ((My $cmdlen = ($cmdtail-$cmdhead + 1)) >= 4) {
# take out the command line string
My $cmdline = substr ($data, $cmdhead, $cmdlen);
# split the command name and its argument string from the command line
if (Splitcmd ($cmdline, @parts)) {
$self->{cmdcount}++;
My $cmdindex = "cmd". " $self->{cmdcount} ";
My $paraindex = "para". $self->{cmdcount} ";
# Log to the object to return to the main program
$self->{$cmdindex} = $parts [0];
$self->{$paraindex} = $parts [1];
}
}
# Adjust the command line string header pointer
$cmdhead = $cmdtail + 1;
}
# If the number of commands is greater than 0, the decoding is valid
if ($self->{cmdcount} = = 0) {
$self->{valid} = 0;
} else {
$self->{valid} = 1;
}
} else {
$self->{valid} = 0;
}
# return Object
Bless ($self, $class);
return $self;
}
Sub Splitcmd {
My ($cmdline, $parts) = @_;
# Remove carriage return at end of line
Chomp ($cmdline);
# using regular expressions to extract command names and parameters, since efficiency is not the main problem to be considered "without scruple" to use regular expressions, because convenient
if ($cmdline =~ m/^s* ([a-za-z]{3,4}) s+ (. *)/) {
My $valid _cmd = 0;
# Check if the extracted command name is a known legitimate FTP command
For (my $i =0; $i < @ftp_cmds; $i + +) {
if ($ftp _cmds[$i] eq UC ($) {
$valid _cmd = 1;
Last
}
}
# If a valid command is returned to the calling function
if ($valid _cmd) {
${$parts}[0] = $;
${$parts}[1] = $;
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
#
# Module Initialisation
#
1;
# autoloaded methods go on the end token (&& pod) below
__end__

(iii) smb.pm a simple decoding module for the SMB header structure, which needs to be copied to the directory where the Netpacket series modules are located, usually in/usr/lib/perl5/site_perl/5.x.x/netpacket/

Copy Code code as follows:

#
# Netpacket::smb-decode SMB Packets
#
# Comments/suggestions to stardust at xfocus Dot org
#
#
# $Id: smb.pm,v 1.16 2004/02/23 12:25:17 Stardust Exp $
#
Package NETPACKET::SMB;
Use strict;
Use VARs qw ($VERSION @ISA @EXPORT @EXPORT_OK%export_tags);
Use Netpacket;
My $myclass;
# SMB Flags
Use constant F2_LONGNAMEALLW => 0x0001;
Use constant F2_extattribute => 0x0002;
Use constant f2_securitysign => 0x0004;
Use constant f2_longnameused => 0x0040;
Use constant F2_extsecurineg => 0x0800;
Use constant F2_dontresoldfs => 0x1000;
Use constant F2_execonlyread => 0x2000;
Use constant F2_errorcodtype => 0x4000;
Use constant f2_unicodstring => 0x8000;
Use constant F_lockandread => 0x01;
Use constant f_rcvbuffpost => 0x02;
Use constant F_CASESENSITV => 0x08;
Use constant F_canonicpath => 0x10;
Use constant f_oplocksrequ => 0x20;
Use constant F_NOTIFYONOPN => 0x40;
Use constant f_requerespon => 0x80;
BEGIN {
$myclass = __package__;
$VERSION = "0.01";
}
Sub Version () {"$myclass v$version"}
BEGIN {
@ISA = QW (exporter netpacket);
# Items to export in callers namespace by default
# (move infrequently used names to @EXPORT_OK below)
@EXPORT = QW (f2_longnameallw f2_extattribute f2_securitysign
f2_longnameused F2_extsecurineg F2_dontresoldfs
F2_execonlyread F2_errorcodtype f2_unicodstring
F_lockandread F_rcvbuffpost F_CASESENSITV
F_canonicpath f_oplocksrequ F_NOTIFYONOPN
F_requerespon
);
# Other items we are prepared to export if requested
@EXPORT_OK = QW (smb_strip
);
# Tags:
%export_tags = (
All => [@EXPORT, @EXPORT_OK],
Strip => [QW (Smb_strip)],
);
}
#
# Strip header from packet and return to the data contained in it
#
Undef &smb_strip;
*smb_strip = &strip;
# functions to strip SMB headers
Sub Strip {
My ($data) = @_;
My $smb _obj = Netpacket::smb->decode ($data);
return $SMB _obj->{data};
}
#
# Decode the packet
#
Sub Decode {
my $class = shift;
My ($data) = @_;
My $self = {};
My $data _len = 0;
My $temp = "";
$data _len = Length ($data);
# If the data area length is less than 39 bytes (4+32+3), it is not considered to be a decoded SMB package
if ($data _len < 39) {
$self->{valid} = 0;
} else {
# take SMB's flag string
My $smb _mark = substr ($data, 4,4);
# does it conform to the sign string
if ($smb _mark ne "xffx53x4dx42") {
$self->{valid} = 0;
} else {
$self->{valid} = 1;
# Decode SMB Packet
if (defined ($data)) {
# Decoding the 32-byte long SMB header structure with the Perl unpack function, the header structure can be
# Reference Http://www.cs.uml.edu/~bill/cs592/cifs.chm
# Thanks to Shi (scz at nsfocus dot com) Reminders of field byte order in SMB header structure
($self->{nbt_type}, $self->{nbt_flag}, $self->{nbt_len},
$self->{mark}, $self->{cmd}, $self->{status},
$self->{flags}, $self->{flags2}, $self->{ext},
$self->{ext2}, $self->{ext3}, $self->{tid},
$self->{pid}, $self->{uid}, $self->{mid},
$self->{data}) = Unpack ("ccna4cvcvvvvvvvva*", $data);
($self->{wordcount}, $temp) = Unpack ("ca*", $self->{data});
if ((+ 1 + $self->{wordcount} * 2) <= ($data _len-2)) {
# decode WordCount bytes and bytecount byte data under SMB structure
My $wordbytes = $self->{wordcount} * 2;
($self->{wordcount}, $self->{words}, $self->{bytecount}, $self->{bytes}) = Unpack ("C".) A "." $wordbytes "." Va* ", $self->{data});
} else {
($self->{wordcount}, $self->{words}) = Unpack ("ca*", $self->{data});
$self->{bytecount} =-1; $self->{bytes} = "";
}
}
}
}
# return Object
Bless ($self, $class);
return $self;
}
#
# Module Initialisation
#
1;
# autoloaded methods go on the end token (&& pod) below
__end__

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.