Perl黑客编程.docx
- 文档编号:26372129
- 上传时间:2023-06-18
- 格式:DOCX
- 页数:42
- 大小:33.97KB
Perl黑客编程.docx
《Perl黑客编程.docx》由会员分享,可在线阅读,更多相关《Perl黑客编程.docx(42页珍藏版)》请在冰豆网上搜索。
Perl黑客编程
目录
一.Perl简介
二.Windows下的Perl环境搭建
三.基础知识
四.数组
五.条件与循环语句
六.用户数据获取
七.文件读写
八.子程序
九.LWP模块
十.套接字Socket
十一.编写攻击代码
(1)XSSexploit
(2)SQLInjectionExploit
(3)远程文件包含
(4)LFI2RCEExploit
(5)本地溢出
(6)远程溢出
十二.结论
一.Perl简介
Perl是PracticalExtractionandReportLanguage的编写,它是由LarryWall设计的,主要用于UNIX环境下编程,当然目前它也是只支持Windows系统的,本文主要也是讲在Windows下的Perl编程,并侧重于黑客安全方面。
Perl如脚本语言一般,无需经编译器来编译才能运行代码,应用起来也很简便,特别是用它来写exploit尤为流行。
据统计,目前世界上有70%的exploit是用Perl来编写的。
在国内,由安全焦点出版的《网络渗透技术》一书提到的主要编程语言中,主要有perl,c,asm三种,书中提到在阅读此书的预备知识中就要求熟悉C,Perl,Asm,由此可见,perl语言在国内安全方面的应用也是占有一席之地的。
在国外著名漏洞公布站点milw0rm中,我们也可以经常看到用perl编写的exploit,无论是在脚本攻击中,还是在系统漏利用中,特别是在溢出攻击中,都可以经常见到它的身影。
除此之外,有些安全人士也用它来编写Fuzzing工具,用于挖掘漏洞。
另外,本文讲述的只是Perl语言中的冰山一角,如果读者想深入学习该语言的话,建议学习一下官方文档或者其它编程书籍。
二.Windows下的Perl环境搭建
在开始Perl编程之旅之前,读者需要先下载两样工具:
ActivePerl和EditPlus。
ActivePerl是一款Perl解释器,可在AIX,HP-UX,Linux,MacOSX,Solaris和Windows等多操作系统平台下使用,使用起来也很简便,直接双击编写好的*.pl文件(perl的文件格式)(这种方法可能会在未看清楚输出结果就自动关闭了,但如果你只是为了生成某个文件,就可以直接使用这种方法,比如在本地溢出利用中用于构造可触发溢出的文件)或者在DOS下输入如下命令即可:
perlexample.pl
EditPlus 是 Windows 下的一个简便的 Internet 32 位文本编辑器、HTML 编辑器和程序设计员的编辑器,支持 HTML、CSS、PHP、ASP、Perl、C/C++、Java、JavaScript 和 VBScript 等多种语言的代码高亮显示,使用者也可根据自己需要到其官方网站下载语言包去支持其它语言(如汇编语言)的代码高亮,读者可也根据自己喜好选择其它编辑器,如Notepad++。
现在我们可新建一个example.pl:
print"HelloWorld!
\n";
然后打开DOS进入example.pl文件所在目录,输入命令:
perlexample.pl后,执行结果如下所示:
d:
\>perlexample.pl
HelloWorld!
三.基础知识
在Perl中,变量的定义是在变量名之前加上符号'$',完成后记得加分号';'例如:
$x=123;(十进制数,注意分号的使用,这跟C语言是相同的。
)
$y=0xff;(十六进制数)
$z=-32.2;(浮点数)
$string=“I’mriusksk.\n”;(对于包含空格的字符串要加双引号,是英文输入法中的双引号,而非中文的双引号。
如果无空格,那么不加引号也是可以的。
除此之外,单引号也是可以的,除非字符串中已经含有单引号,就像这一句就只能使用双引号了,但是使用单引号后,不能解释转义符,也就是说,如果使用了单引号,那么它就会把\n之类的转义符直接输出,而不是换行。
)
一些常见的转义符如下:
\n
NewLine
\r
Return
\t
Tab
\f
FormFeed
\b
Backspace
\v
VerticalTab
\e
Escape
\a
Alarm
\L
LowercaseAll
\l
LowercaseNext
\U
UppercaseAll
\u
UppercaseFirst
在perl中,"#"是不为解释器所解释的,它是作为注释符来使用的,比如将以下代码保存为riusksk.pl文件:
$name=“riusksk\n”;#myname
print$name;
那么运行后它会直接输出:
d:
\>perlriusksk.pl
riusksk
现在我们将上面的代码改成:
$hello=“Hello,”;
$name=“riusksk!
\n”;#myname
print“$hello”.”$name”;
输出结果如下:
d:
\>perlriusksk.pl
Hello,riusksk!
在这里点号“.”起到一个连接字符串的作用,在后面关于溢出exploit编写中,你就可以体会到它的方便之处了,而且增强了代码的易读性。
接下来,我们讲讲关于操作符方面的知识。
算术操作符主要有:
+(加)、-(减)、*(乘)、/(除)、**(乘幂)、%(取余)、-(单目负)。
整数比较操作符主要有:
<(小于)、>(大于)、==(等于)、<=(小于等于)、>=(大于等于)、!
=(不等于)、<=>(比较,返回1,0,或者-1)。
字符串比较操作符主要有:
lt(小于)、gt(大于)、eq(等于)、le(小于等于)、ge(大于等于)、ne(不等于)、cmp(比较,返回1,0,或者-1)。
下面我们实例操作一下,以巩固知识。
输入以下代码并保存为riusksk.pl:
$a=1+2;
$b=4-3;
$c=5*6;
$d=6/2;
$e=2>1;
$f=3!
=4;
$g=“A”eq“A”;
$h=“A”cmp”B”;
print“$a”.”\t”;
print“$b”.”\t”;
print“$c”.”\t”;
print“$d”.”\t”;
print“$e”.”\t”;
print“$f”.”\t”;
print“$g”.”\t”;
print“$h”.”\n”;
输出结果如下:
d:
\>perlriusksk.pl
31303111-1
四.数组
数组是用来存储列表的,与变量不同,它允许在perl程序中使用一序列值,可以为任意数值,也可为空,数组变量是以字符“@”开头的。
为了理解它,我们需要去实践操作一下。
先在riusksk.pl中输入以下代码:
@hello=(‘Hello’,’World’);
print@hello;
运行后输出结果如下:
d:
\>perlriusksk.pl
HelloWorld
在这里,我们可借助join()函数在HelloWorld之间加入空格,具体代码如下:
@hello=(‘Hello’,’World’);
printjoin(‘‘,@hello);
运行结果:
d:
\>perlriusksk.pl
HelloWorld
对于数组元素的读取可以通过下标来实现,首个元素的下标为0。
如果读取的是不存在的元素,那么它将返回NULL,但如果给超出数组大小的元素赋值,那么数组就会自动增长,原来没有的元素为NULL。
比如:
@hello=("hello","world");
print"$hello[0]"."\n";
print"$hello[1]"."\n";
print"$hello[2]"."\n";
输出结果:
d:
\>perlriusksk.pl
hello
world
d:
\>
下面我们再讲一个函数——split()函数,主要功能是以某种字符来分割句子以转存到数组中,然后从数组中提取数据以作为他用。
下面我们还是以实例进行讲解:
$sentence="Helloeveryone!
mynameisriusksk.";
@words=split("",$sentence);#这里""也可写成//(中间有空格),即以空格为间隔符
printjoin("",@words);
输出结果:
d:
\>perlriusksk.pl
Helloeveryone!
mynameisriusksk.
五.条件与循环语句
1.条件判断语句
经典的条件判断语句莫过于if—then语句了,它几乎存在于每一种编程语言中,它在perl中基本格式如下:
if(express1){
statement1
}
elsif(express2){
statement2
}
else{
statement3
}
例如:
$name=riusksk;
if($nameeq"riusksk"){
print"you'reriusksk.\n";
}
elsif($nameeq"quange"){
print"you'requange.\n";
}
else{
print"Idon'tknowyourname!
\n";
}
输出结果为:
d:
\>perlriusksk.pl
you’reriusksk.
2.循环语句
对于循环语句,我们这里主要下面四种循环语句:
while循环,until循环,for循环,foreach循环。
(1)while循环语句
格式:
while(express){
statemet
}
例如:
$x=1;
while($x<5){
$x++;
}
print$x;
输出结果为:
d:
\>perlriusksk.pl
5
(2)until循环语句
格式:
until(express){
statemet
}
例如:
$y=A;
until($ygeC){
$y++;
}
print$y;
输出结果:
d:
\>perlriusksk.pl
C
(3)for循环语句
格式:
for($i=1;$i<=5;$i++){
statement
}
例如:
for($i=1;$i<=5;$i++){
print“$i”.”\t”;
}
输出结果:
d:
\>perlriusksk.pl
12345
(4)foreach循环
格式:
foreach$num(@array){#num为数组@array中的元素
statement
}
例如:
@array=(10,20,30,40,50);
foreach$num(@array){
if($num==10){
$num=30;
}
}
printjoin("","@array");
输出结果:
d:
\>perlriusksk.pl
3020304050
六.用户数据获取
(1)STDIN
当编写exploit的时候,我们有时需要获取用户的输入数据,比如IP地址,以便使程序根据用户的意图来执行相应的工作。
对于这种情况,我们可以使用STDIN(标准输入)方法来获取用户的输入数据。
例如:
print"What'syourname?
\n";
$name=
chomp$name;#去除换行符,因为输入数据通过STDIN获取后会自动添加换行符\n
print"Hello,$name.Nicetomeetyou!
\n";
输出结果:
d:
\>perlriusksk.pl
What’syourname?
riusksk
Hello,riusksk.Nicetomeetyou!
(2)@ARGV
除以上方法之外,我们还可以使用@ARGV。
如同数组一般,@ARGV支持用户参数,这跟C语言中的argv,argc类似,在很多perlexploit中经常可以见到它。
比如我们在对目标主机进行溢出攻击时,经常可见到像下面的指令:
perlexploit.pl127.0.0.13424
127.0.0.1是目标主机的IP地址,3424是端口号。
下面我们举例讲解一下@ARGV的使用,以下代码将输入参数
if(@ARGV!
=2){
print“Usage:
perl$0
exit;
}
($IP,$Port)=@ARGV;
print“IPAddress:
$IP,Portis$Port.\n”;
输出结果:
d:
\>perlriusksk.pl
Usage:
perlriusksk.pl
d:
\>perlriusksk.pl127.0.0.11234
IPAddress:
127.0.0.1,Portis1234.
(3)GetOpt
这里我们再讲述另一种获取用户输入数据的方法,这是一种叫做GetOpt的perl模块。
请看下列代码:
useGetopt:
:
Std;#导入GetOptSTD模块,取消模块用no语句
getopts(":
a:
p:
",\%args);#定义两个标志-a和-p分别用来获取参数
if(defined$args{a}){#若已给标志-a中的参数赋值,则将参数值赋予变量$a
$a=$args{a};
}
if(defined$args{p}){
$p=$args{p};
}
if(!
defined$args{a}or!
defined$args{p}){#如果有一个参数未输入则输出以下语句并退出
print"Usage:
perl$0-a
exit;
}
print"IPAddress:
$a,Portis$p.\n";
输出结果:
d:
\>perlriusksk.pl
Usage:
perlriusksk.pl-a
d:
\>perlriusksk.pl–a127.0.0.1–p1234
IPAddress:
127.0.0.1,Portis1234.
以上三种方法以最后一种最为常用了,常用于编写exploit。
七.文件读写
在编写本地溢出exploit时经常要构造一个可触发溢出的文件,这里就需要对文件进行读写了。
要对某文件进行操作需要先打开文件,打开文件的语法如下:
open(fp,”filename”),其中fp为文件句柄,可以理解为文件的代号,filename是文件名,其路径可为相对路径,也可为绝对路径。
例如:
open(fp,”exploit.mp3”);
open(fp,”c:
/hacking/exploit.mp3);
如果我们想创建一个不存在的文件可以使用下列语句:
open(fp,”>>exploit.mp3”);
如果打开失败,我们可以结束程序,那么以上代码可更改为:
unless(open(fp,”exploit.mp3”)){
die(“openfilefail\n”);
}
成功打开文件之后,我们就可以对其进行读写了。
读取文件的语法为:
(1)$line=
从文件中读取一行数据并将其储存到变量$line中,而且文件指针会向后移动一行。
(2)@array=
读取文件的所有内容并将其储存到数组@array中,而且文件中的每一行(包含回车符)为@array中的一个元素。
写文件的语句如下:
print(fp,”hello\n”);
对文件操作完成后,需要关闭文件:
close(fp);
下面我们举个例子来进行文件读写操作:
if(open(fp1,">>exploit.txt")){
print("createfilesucessful!
\n");
}
else{
die("createfilefail!
\n");
}
printfp1("riusksk\n"."quange\n");
close(fp1);
unless(open(fp2,"exploit.txt")){
die("openfilefail\n");
}
@array=
print("thecontentofexploit.txt:
\n");
print@array;
close(fp2);
输出结果如下:
d:
\>perlriusksk.pl
Createfilesucessful!
Thecontentofexploit.txt:
riusksk
quange
八.子程序
(1)子程序的定义方法:
subfunction{
statement;
}
调用时可在子程序名前加&,或者先定义后直接以子程序名调用(省略&),也可先定义子程序名,再定义程序体。
(2)参数
格式:
&function($arg1,$arg2,$arg3);
subfunction{
my($arg1,$arg2,$arg3)=@array;
}
(3)局部变量
局部变量的定义方法有两种:
my和local,其中my定义的变量只存在于子程序中,而local定义的变量不存在于主程序中,但存在于子程序及该子程序调用的子程序当中。
例如:
my($name)=riusksk;
local($num)=1;
九.LWP模块
LWP("LibraryforWWWinPerl"的缩写)是一个由多个模块组成,主要用来获取网络数据的一个模块组。
LWP包含有许多模块,通过它我们就可编写perl脚本来访问外部的WEB服务器上的资源了,关于LWP各模块的更多信息可以访问以下地址获得:
http:
//search.cpan.org/~gaas/libwww-perl/
这里我们只讲LWP:
:
Simple和LWP:
:
UserAgent这两个模块。
(1)LWP:
:
Simple
LWP:
:
Simple是LWP的一个简单程序接口,它主要有以下函数:
■get($url)—获取指定URL地址的网页内容,如果没有发生错误,get函数返回此网页,
否则,返回undef。
■head($url)—获取指定URL地址的页面头信息,如果成功则返回($content_type,$document_length,$modified_time,$expires,$server)五个变量值,即依次为内容类型,文档长度,最后更新时间,过期时间和服务器名称。
■getprint($url)—获取并输出指定URL地址的网页内容,它返回一个状态号,比如成功将返回200,文件没有找到将返回404。
■getstore($url,$file)—获取指定URL地址的网页内容并保存在文件$file中,返回值为也是状态号。
例如:
useLWP:
:
Simple;
$a=getprint('');
print"\n";
print$a;
print"\n";
my($b,$c,$d,$e,$f)=head('');
print"$b"."\n"."$c"."\n"."$d"."\n"."$e"."\n"."$f";
getstore('
system('riusksk.jpg');#打开图片
sleep(5);#延时5秒
unlink('riusksk.jpg');#删除图片
输出结果如下:
D:
\软件>perlriusksk.pl
tle>XX一下,你就知道