用PERL实现一个简单的NIDS(3)

时间:2005-12-20 来源: 作者: 点击:
用PERL实现一个简单的NIDS FTP.pm FTP协议解码模块,抽取数据包里的FTP命令及相应的参数,此文件需要拷贝到NetPacket系列模块所在的目录,通常是在/usr/lib/perl5/site_perl/5.x.x/NetPacket/ -------- 8 ------------ # # NetPacket::FTP - Decode FTP packets # # Com
  用PERL实现一个简单的NIDS
    FTP.pm
FTP协议解码模块,抽取数据包里的FTP命令及相应的参数,此文件需要拷贝到NetPacket系列模块所在的目录,通常是在/usr/lib/perl5/site_perl/5.x.x/NetPacket/
-------- 8< ------------
#
# 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 into 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协议文本参看RFC959,http://www.ietf.org/rfc/rfc0959.txt

# 常见的FTP命令
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 XMKD
XPWD XRMD LPRT LPSV ADAT AUTH CCC CONF ENC MIC PBSZ PROT
FEAT OPTS EPRT EPSV LANG MDTM MLSD MLST SIZE DIGT CLNT MACB
);

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 ($data_len >= 4) {
# 一个包里的FTP命令个数
$self->{cmdcount} = 0;
# 搜索回车,之前认为是一个命令行,需要注意的是一个包里可能包含多个FTP命令
while ( (($returnindex = index ($data,"\x0a",$cmdhead)) >=0)    (($returnindex < 0) && (($data_len - $cmdhead) >= 4))) {
# 调整一个命令行串尾指针
if ($returnindex < 0) {
$cmdtail = $data_len -1;
} else {
$cmdtail = $returnindex;
}

if ((my $cmdlen = ($cmdtail - $cmdhead + 1)) >= 4) {
# 取出命令行串
my $cmdline = substr($data,$cmdhead,$cmdlen);
# 从命令行里拆分出命令名和它的参数串
if (splitcmd($cmdline,\@parts)) {
$self->{cmdcount}++;
my $cmdindex = "cmd"."$self->{cmdcount}";
my $paraindex = "para"."$self->{cmdcount}";
# 记录到要返回到主程序的对象
$self->{$cmdindex} = $parts[0];
$self->{$paraindex} = $parts[1];
}
}
# 调整命令行串头指针
$cmdhead = $cmdtail + 1;
}

# 如果命令个数大于0,则说明解码是有效的
if ($self->{cmdcount} == 0) {
$self->{valid} = 0;
} else {
$self->{valid} = 1;
}

} else {
$self->{valid} = 0;
}

# 返回对象

bless($self, $class);
return $self;
}

sub splitcmd {
my ($cmdline,$parts) = @_;

# 去除行尾的回车
chomp($cmdline);
# 用正则表达式抽取出命令名字和参数,既然效率不是考虑的主要问题就“毫无顾忌”地使用正则表达式,因为方便
if ($cmdline =~ m/^\s*([a-zA-Z]{3,4})\s+(.*)/) {
my $valid_cmd = 0;
# 检查抽出来的命令名字是否是一个已知的合法FTP命令
for (my $i=0;$i<@ftp_cmds;$i++) {
if ($ftp_cmds[$i] eq uc($1)) {
$valid_cmd = 1;
last;
}
}
# 如果是合法的命令则返回给调用函数
if ($valid_cmd) {
${$parts}[0] = $1;
${$parts}[1] = $2;
return 1;
} else {
return 0;
}

} else {
return 0;
}
}

#
# Module initialisation
#

1;

# autoloaded methods go after the END token (&& pod) below

__END__
------------- 8< ------------

------分隔线----------------------------
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
推荐内容
  • NIDS和HIDS比较

    NIDS和HIDS比较 目前,在安全市场上,最普遍的两种入侵检测产品是基于网络的网络入侵...

  • HIDS逐渐的成为主流

    HIDS逐渐的成为主流 当前的网络IDS系统可以分为基于网络数据包分析的系统(NIDS)和基...

  • IDS术语(1)

    IDS术语 DOCSHOW.NET A. Cliff by A. Cliff last updated July 3, 2001 Translated by...

  • 安装入侵检测系统后的注意事项

    安装入侵检测系统后的注意事项 在经过数月的评估、测试、购置等工作,部署好入侵检测...

  • 如何构建一个IDS

    如何构建一个IDS 通常来说,一个企业或机构准备进军此领域时,往往选择从基于网络的ID...

  • 什么是入侵检测

    什么是入侵检测 入侵检测是 防火墙 的合理补充,帮助系统对付网络攻击,扩展了系统管...