Ver 0.1 ] Simple IDS in Perl
1. IDS 모티브로 구현된 , Ver 0.1 Perl IDS 프로그램입니다.
2. 소스코드를 분석해 보겠습니다.
#!/usr/bin/perl -w
use strict;
# 라이브러리 사용 선언
use Net::PcapUtils;
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use Data::HexDump;
use Sys::Syslog;
use DBI;
use Switch;
# db 연결 속성 설정
my $driver = "mysql";
my $database = "packets";
my $dsn = "DBI:$driver:database=$database";
my $userid = "root";
my $password="1234";
# db 연결
my $dbh= DBI->connect($dsn,$userid,$password) or die $DBI::errstr;
my $i=0;
my $portnum;
while(1){ #전체에 대한 루프 #
# 메뉴 선택 부분
print "+- - - - - - - - - - - - - - - - - - - - - - - - -+\n";
print "+ - = Simple IDS 입니다. 메뉴를 선택하세요 ! = - +\n";
print "+ = IDS] 실행 or VIEW] 패킷내용 검색 = + \n";
print "+- - - - - - - - - - - - - - - - - - - - - - - - -+\n" ."command\>";
chomp(my $orders=<STDIN>);
# IDS 선택시
if($orders =~ (/ids/i)){
# 패킷 조건 설정
print " 《《《 Network Sequrity Mode :: ver 0.1 》》》\n";
print " -+ Enter] input the Port Range :: ex] 80 + - \n";
print "command\>";
chomp($portnum=<STDIN>); print "> ok < $portnum : Network Monitering and analysis ! \n";
# 방화벽 추가 횟수 제한
my $k=0;
# 덤프 루프부
Net::PcapUtils::loop(\&process_pkt);
# 패킷 처리부
sub process_pkt {
my $ports=$portnum; # portnum 함수내 지정
my ($user_data,$hdr,$pkt)=@_;
my $eth=NetPacket::Ethernet->decode($pkt);
if($eth->{type} == 2048){
my $ip=NetPacket::IP->decode($eth->{data});
if($ip->{proto} == 1 || 2 || 6 || 17 ){
my $tcp=NetPacket::TCP->decode($ip->{data});
# protocol 문자열 변환
my $asciipro;
switch($ip->{proto}){
case "1" {$asciipro="icmp"}
case "2" {$asciipro="igmp"}
case "6" {$asciipro="tcp"}
case "17" {$asciipro="udp"}
else {$asciipro="Other"}
}
# 네트워크 내에 발생된 패킷 데이터베이스에 기록
my $sth= $dbh->prepare("INSERT INTO dump
(dest_mac,src_mac,dest_ip,src_ip,protocol,flag,block,seqnum,acknum,winsize,urg,ttl,sport,dport)
values
('$eth->{dest_mac}','$eth->{src_mac}','$ip->{dest_ip}','$ip->{src_ip}','$asciipro','$ip->{flags}',0,'$tcp->{seqnum}','$tcp->{acknum}','$tcp->{winsize}','$tcp->{urg}','$ip->{ttl}','$tcp->{src_port}','$tcp->{dest_port}')");
# 쿼리l 실행
$sth->execute() or die $DBI::errstr;
#종료
$sth->finish();
#dbms commit 명령
#$dbh->commit or die $DBI::errstr;
# 지정한 아이피 또는 포트에 대한 패킷 분석 부분
if($tcp->{src_port} eq $ports){ #지정한 포트와 인풋 포트가 같다면
print "+_+_+_+_+_+_+_ $ports 포트 패킷 발견 !! _+_+_+_+_+_+_+_+ \n";
print "[ 침입탐지 ] SysLog 에 저장 되었습니다. \n";
my $fireip = $ip->{dest_ip};
if($k<1){
# 탐지된 아이피 방화벽에 추가 후 방화벽 재시작
system("iptables -t filter -A INPUT -s $fireip -j DROP");
system('service iptables save');
sleep(1);
system('/etc/init.d/iptables restart');
# 탐지된 아이피 Sys log 저장
openlog(my $program,'cons,pid','user');
syslog("info",'Warning!! connect ip : \%s port: %s ',$ip->{dest_ip},$tcp->{dest_port});
sleep(1);
$k++;
}
}else{ # 지정한 포트와 인풋 포트가 같지 않으면
# 패킷 덤프하여 출력
print "\n\n$i $ip->{src_ip}($tcp->{src_port}) -> $ip->{dest_ip}($tcp->{dest_port})\n";
print HexDump $ip->{data};
$i++;}
}
}
}
}elsif($orders =~(/view/i)){ # VIEW 메뉴 선택시
while(1){ # 반복 실행
print "+ - -《《 IDS Log View 》》 - - +\n";
print " Port ] 검색시 port 입력, IP ] 검색시 IP 입력 !! Black] Black List 확인 exit] 종료시exit !! 예]port \n";
print "command\>";
chomp(my $search=<STDIN>);
# Port Search 부
if($search =~(/port/i)){
print "검색할 포트번호를 입력 하세요 !! \n";
print "command\>";
chomp(my $ptnum=<STDIN>);
my $sth = $dbh->prepare("select * from dump where sport = ?");
$sth->execute($ptnum) or die %DBI::Errstr;
# Port Search 검색 결과 출력
while(my @row = $sth->fetchrow_array()){
my($dest_mac,$src_mac,$dest_ip,$src_ip,$protocol,$flag,$block,$seqnum,$acknum,$winsize,$urg,$ttl,$sport,$dport)=@row;
print" MAC : $dest_mac, Ip : $dest_ip , protocol : $protocol , seqnum : $seqnum, acknum : $acknum, winsize : $winsize , urg : $urg, ttl : $ttl sport: $sport , Dest_port : $dport \n";
}
print "+- - - - - - - - - - - - - - - - - - - - - - - - -+\n";
print " 검색 결과 : " . $sth->rows . " 개 검색 되었습니다 \n";
# 차단 여부 설정부
print " 검색 결과 중, 차단할 포트가 있습니까? yes or no \n";
print "command\>";
chomp(my $que = <STDIN>);
if($que =~(/yes/i)){
print " 차단할 포트를 입력 하세요 ! \n";
print "command\>";
chomp(my $blockport = <STDIN>);
# 방화벽에 추가 후 방화벽 재시작
system("iptables -t filter -A INPUT -p tcp --sport $blockport -j DROP");
system('service iptables save');
system('/etc/init.d/iptables restart');
# db block 추가
my $query = "UPDATE dump SET block = 1 WHERE dport = $blockport;";
my $query_handling = $dbh->prepare($query);
$query_handling->execute();
}elsif($que=~(/no/i)){
last;}
$sth->finish();
# IP Search 부
}elsif($search =~ (/ip/i)){
print "검색할 아이피를 입력 하세요 !! \n";
print "command\>";
chomp(my $ipnum=<STDIN>);
my $sth = $dbh->prepare("select * from dump where dest_ip = ?");
$sth->execute($ipnum) or die %DBI::Errstr;
# IP Search 검색 결과 출력
while(my @row = $sth->fetchrow_array()){
my($dest_mac,$src_mac,$dest_ip,$src_ip,$protocol,$flag,$block,$seqnum,$acknum,$winsize,$urg,$ttl,$sport,$dport)=@row;
print" MAC : $dest_mac, Ip : $dest_ip , protocol : $protocol , seqnum : $seqnum, acknum : $acknum, winsize : $winsize , urg : $urg, ttl : $ttl sport : $sport dport : $dport \n";
}
print "+- - - - - - - - - - - - - - - - - - - - - - - - -+\n";
print " 검색 결과 : " . $sth->rows . " 개 검색 되었습니다 \n";
# 아이피 서치 후, 차단 여부 설정 부
print " 검색 결과 중, 차단할 아이피가 있습니까? yes or no \n";
print "command\>";
chomp(my $que2 = <STDIN>);
if($que2 =~(/yes/i)){
print " 차단할 아이피를 입력 하세요 ! \n";
print "command\>";
chomp(my $bip = <STDIN>);
# 방화벽에 추가 후 방화벽 재시작
system("iptables -t filter -A INPUT -s $bip -j DROP");
system('service iptables save');
system('/etc/init.d/iptables restart');
# db block 추가
my $query = "UPDATE dump SET block = 1 WHERE dest_ip = '$bip';";
my $query_handling = $dbh->prepare($query);
$query_handling->execute();
}elsif($que2=~(/no/i)){
last;}
$sth->finish();
# black list Search 부
}elsif($search =~(/black/i)){
my $sth = $dbh->prepare("select * from dump where block = 1");
$sth->execute() or die %DBI::Errstr;
# Black List 검색 결과 출력
while(my @row = $sth->fetchrow_array()){
my($dest_mac,$src_mac,$dest_ip,$src_ip,$protocol,$flag,$block,$seqnum,$acknum,$winsize,$urg,$ttl)=@row;
print" MAC : $dest_mac, Ip : $dest_ip , protocol : $protocol , seqnum : $seqnum, acknum : $acknum, winsize : $winsize , urg : $urg, ttl : $ttl \n";
}
print "+- - - - - - - - - - - - - - - - - - - - - - - - -+\n";
print " 검색 결과 : " . $sth->rows . " 개 검색 되었습니다 \n";
}elsif($search =~(/exit/i)){
last;}
} #while end
} #else end
} #전체 루프