精华内容
下载资源
问答
  • 超硬核:深入讲解Perl安全之代码审计——perl脚本中存在的问题与存在的安全风险
    2021-08-16 15:45:33

    博主:鴻漸之翼
    个人介绍:男,搞底層的FW,喜歡發一點沒用的東西。

    介绍:

    程序设计语言通常不构成安全风险,风险是由程序员带来的。几乎每种语言都有某些缺陷,这些缺陷在某种程度上可能有助于创建不安全的软件,但软件的整体安全性仍然在很大程度上取决于开发者的安全意识。Perl也有安全“陷阱”,然而大多数Perl程序员并不了解这些陷阱。

    在本文中,我们将介绍一些被广泛误用和忽视的Perl特性。本文将展示perl语言不正确的使用方式,错误使用方式又是如何对运行程序的用户,及系统构成威胁。本文也会展示如何利用这些漏洞,以及如何修复或避免它们。

    基本用户输入漏洞

    Basic user input vulnerabilities

    Perl脚本中安全问题的一个主要来源是未正确验证(或未验证)的用户输入。任何时候你的程序可能会从一个不受信任的用户那里获取输入,即使是间接的,你都应该小心。例如,如果我们使用Perl编写CGI脚本,那么恶意用户可能会向您发送虚假输入。

    如果未经验证就使用,对此类应用程序的不当输入就可能会导致许多问题。在没有正确验证的情况下,使用用户提供的参数执行其他程序,使最常见的错误。

    system() 和exec()函数

    Perl语言以其“粘贴语言”而出名,它可以出色地调用其他程序来帮协助完成它的工作。通过收集一个程序的输出,以特定的方式重新格式化,并将其作为输入传递给其他程序,仔细地协调它们的活动,从而使一切都能顺利运行。
    执行外部程序或系统命令的一种方法是调用exec()函数。当Perl遇到exec()语句时,它会查看调用exec()时使用的参数,然后启动一个执行指定命令的新进程。Perl从不将控制权返回到调用exec()的原始进程。
    另一个类似的函数是system(),system()与exec()函数非常相像。唯一的区别是perl首先从父进程中派生一个子进程。父进程等待着子进程结束,然后继续执行程序的其他部分。
    下面我们将详细讨论system()与exec()的函数调用。

    给system()函数运行的是一个列表。
    system()抽象列表
    1.程序名称
    2.其余元素(作为传递参数传递给程序)
    如果只要一个参数,system()调用方式会有不同。这种情况下
    perl会扫描参数,查看是否含有shell字符。如果是则继续解释,perl将生成一个命令shell,如果perl不了解特殊的shell字符,perl会将字符串分解成单词,并调用更高效的C库调用execvp()

    假设我们有一个CGI表单,它要求输入用户名, 并显示一些包含该用户统计信息的文件。我们可以使用system()调用cat。

     system ("cat /usr/stats/$username"); 
    

    $username来自以下表单:

     $username = param ("username");
    

    用户填写表单时,例如;username=jdimov,然后提交表单。
    perl在字符串”cat /usr/stats/jdimov“中找不到任何元字符,它运行cat程序,然后返回脚本。这个脚本看起来无害,但实际上可能被恶意攻击者利用。问题在于,通过表单的‘username’字段中使用特殊的字符,攻击者可以通过shell执行任意命令。
    例如,假设攻击者发送字符串"jdimov; cat /etc/passwd"。
    perl将分号识别为元字符,并传递给shell

      cat /usr/stats/jdimov; cat /etc/passwd
    

    攻击者同时获得虚拟统计文件和密码文件。如果想具有破坏性,我们可以祭出“rm -rf”。
    前面提到过,system()接受一个参数列表,并将第一个元素作为命令执行,将其余元素作为参数传给它,我们只需要稍微更改脚本,以便执行我们的程序。

      system ("cat", "/usr/stats/$username");
    

    因此我们分别为程序指定每个参数,所以永远不会调用shell。所以使得rm -rf不管用,因为攻击字符串被解释为文件名。
    这种方法比单参数版本要好得多,因为它避免了使用shell,但仍然存在潜在的缺陷。特别是,我们需要担心username的值是否会被用来利用正在执行的程序(在本例中为“cat”)的弱点。例如,攻击者仍然可以通过将$username设置为字符串“…/…/etc/passwd”,利用我们重写的代码来显示系统密码文件。

    根据程序的不同,许多其他事情可能会出错。例如,一些应用程序将特殊字符序列解释为执行shell命令的请求。一个常见的问题是,某些版本的Unix“mail”实用程序,在看到~!上下文中的转义序列。因此,用户输入包含!rm -”在某些情况下可能会导致问题。
    就安全性而言,上面提到的 system()函数同样适用于exec()

    open()函数

    Perl中的open()函数用于打开文件。在最常见的形式中,它的使用方式如下:

     open (FILEHANDLE, "filename");
    

    像这样使用,“filename”以只读模式打开。如果“filename”的前缀带有“>”符号,则会打开该文件进行输出,如果该文件已经存在,则会覆盖该文件。如果它的前缀为“>>”,则可以进行追加。前缀“<”打开文件进行输入,但如果没有使用前缀,这也是默认模式。使用未经验证的用户输入作为文件名的一部分的一些问题应该已经很明显了。例如,反向目录遍历技巧在这里同样有效。
    这里还有其他担忧的地方。让我们修改脚本以使用open()而不是“cat”。会有类似于:

      open (STATFILE, "/usr/stats/$username");
    

    然后是一些从文件中读取并显示的代码。Perl文档告诉我们:
    如果文件名以“|”开头,则该文件名将被解释为将输出传输到的命令;如果文件名以“|”结尾,则该文件名将被解释为将输出传输到我们的命令。然后,用户可以在/usr/stats目录下运行任何命令,只需修复一个“|”。向后目录遍历允许用户在系统上执行任何程序。 解决此问题的一种方法是,始终使用“<”符号作为前缀,明确指定要打开该文件进行输入:

       open (STATFILE, "</usr/stats/$username");
    

    有时我们确实希望调用外部程序。例如,假设我们希望更改脚本,使其读取旧的纯文本文件/usr/stats/username,但在向用户显示之前将其通过HTML过滤器。比方说,我们有一个方便的实用工具,就为了这个目的。一种方法是这样做:

     open (HTML, "/usr/bin/txt2html /usr/stats/$username|");
     print while <HTML>;
    

    不幸的是,程序仍然是通shell。我们可以使用另一种形式的open()调用来避免生成shell:

      open (HTML, "-|") 
           or exec ("/usr/bin/txt2html", "/usr/stats/$username");
         print while <HTML>;
    

    当我们将管道打开到“-”时,无论是用于读取(“-|”)还是用于写入(“|-”),Perl都会分叉当前进程,并将子进程的PID返回给父进程,将0返回给子进程。“or”语句用来判定父子进程。如果我们在父进程(open()的返回值为非零),则继续执行print()语句。否则,我们就是子进程,所以我们执行txt2html程序,使用exec()和多个参数来避免通过shell传递任何内容。发生的情况是,子进程将txt2html生成的输出打印到STDOUT,然后安静地小时,同时父进程从STDIN读取结果。同样的技术也可用于管道输出到外部程序:

         open (PROGRAM, "|-") 
           or exec ("/usr/bin/progname", "$userinput");
         print PROGRAM, "This is piped to /usr/bin/progname";
    

    当需要管道时,这些形式的open()应该总是优先于直接管道open(),因为它们不穿过shell。现在假设我们将统计数据文件转换为格式良好的HTML页面,为了方便起见,我们决定将它们存储在显示它们的Perl脚本所在的目录中。
    那么我们的open()语句可能如下所示:

     open (STATFILE, "<$username.html");
    

    当用户传递给username=jdimov时,脚本显示jdimov.html。
    这里仍然有可能被攻击。与C和C++不同,Perl不使用null字节来终止字符串。因此,字符串 “jdimov\0blah"在大多数C库调用仅仅解释为"jdimov” ,但在Perl中仍然是 “jdimov\0blah”。
    当Perl将包含null的字符串传递给用C编写的内容时,问题就出现了。UNIX内核和大多数UNIX shell都是纯C编写的。Perl本身主要也是用C编写的。

     statscript.pl?username=statscript.pl%00
    

    如果该脚本与我们的html文件位于同一目录中,那么我们可以使用此输入来欺骗这个脚本。在这种情况下,可能不会对安全造成太大威胁,但对其他程序肯定会造成威胁,因为它允许攻击者分析源代码中的其他可利用弱点。

    Backticks

    在Perl中,读取外部程序输出的另一种方法是将命令包含在反标记中。因此,如果我们想将stats文件的内容存储在标量$stats中,我们可以执行以下操作:

      $stats = `cat /usr/stats/$username`;
    

    这是通过shell的。任何一行命令只要涉及到用户输入的脚本
    都会面临讨论过的所有安全问题。
    有几种不同的方法可以使shell不解释可能的元字符,但最安全的方法是不使用反勾号。
    相反,打开一个STDIN的管道,然后fork并执行外部程序,就像我们使用open()所做的操作。

    eval()和/e regex修饰符

    eval()函数可以在运行时执行一段Perl代码,返回最后一条经过计算的语句的值。这种功能通常用于配置文件之类的东西,这些文件可以写成perl代码。除非您完全信任要传递给eval()的代码源,否则不要执行eval$userinput之类的操作。这也适用于正则表达式中的/e修饰符,该修饰符使Perl在处理表达式之前对其进行解释。

    黑名单过滤用户输入

    本节讨论的大多数问题的一种常见方法是过滤掉不需要的元字符和其他有问题的数据。例如,我们可以过滤掉所有句点,以避免向后遍历目录。同样,每当我们看到无效字符时,也可能失败。
    这种策略被称为“黑名单”。实际上是,如果某件事没有被明确禁止,那么它一定是好的。一个更好的策略是“白名单”,它规定,如果某件事情没有明确允许,那么它必须被禁止。
    黑名单最重要的问题是很难保持完整和更新。您可能忘记过滤某个字符,或者您的程序可能必须切换到具有不同元字符集的不同shell。

    与其过滤掉不需要的元字符和其他危险的输入,不如只过滤合法的输入。例如,如果用户输入包含字母、数字、点或@符号(用户电子邮件地址中可能包含的字符)以外的任何内容,则以下代码段将停止执行安全关键操作:

      unless ($useraddress =~ /^([-\@\w.]+)$/) {
           print "Security error.\n";
           exit (1);
         }
    

    基本思想不是试图编写一个要防范的特殊值列表,而是提出一个可以安全接受的值列表。当然,可接受输入值的选择会因应用程序而异。选择可接受的值时,应当尽量减少其造成损害的可能性。

    避开Shell

    当然,我们应该尽量少使用shell。然而,这种技术使用得更广。如果调用具有特殊序列的编辑器,可以确保不允许使用这些序列。一般通过使用Perl模块,可以避免使用外部程序执行函数。这里可以参考CPAN(Perl的归档网络)

    安全问题的其他来源

    不安全的环境变量

    用户输入确实是Perl语言的安全隐患之一,但是我们在编写perl程序时还需要考虑到其他因素。在shell下或由web服务器运行的脚本的一个常见弱点是不安全的环境变量,最常见的是路径变量。当你仅通过指定外部应用程序或实用程序的相对路径从代码中访问该外部应用程序或实用程序时,你会使整个程序及其运行系统的安全性受到影响。假设你有这样一个system()调用:

     system ("txt2html", "/usr/stats/jdimov");
    

    为了使调用起作用,你假设txt2html文件位于PATH变量中某个位置包含的目录中。但是,如果发生这种情况,使攻击者改变你的路径,指向其他恶意程序的路径,则使你的系统安全将不再得到保证。
    为了防止这种情况发生,每个需要远程安全意识的程序都应该从以下内容开始:

        #!/usr/bin/perl -wT
         require 5.001;
         use strict;
         $ENV{PATH} = join ':' => split (" ", << '__EOPATH__');
           /usr/bin
           /bin
           /maybe/something/else
         __EOPATH__
    

    如果程序依赖于其他环境变量,则在使用前还应明确重新定义这些变量。另一个危险的变量(这一个更特定于Perl)是@INC数组变量,它非常类似于PATH,只是它指定Perl应该在何处查找要包含在程序中的模块。@INC的问题与PATH的问题几乎相同有人可能会将您的Perl指向一个与您所期望的模块具有相同名称和执行相同操作的模块,但它也会在后台执行颠覆性操作。因此,@INC不应该比PATH更受信任,应该在包含任何外部模块之前完全重新定义。

    setuid脚本

    通常,Perl程序以执行它的用户的权限运行。通过创建脚本setuid,可以将其有效用户ID设置为能够访问实际用户不访问的资源的用户ID(即,包含程序的文件的所有者ID)。例如,passwd程序使用setuid获取对系统密码文件的写入权限,从而允许用户更改自己的密码。由于通过CGI接口执行的程序是以运行web服务器的用户的权限运行的(通常是用户“nobody”,其权限非常有限),CGI程序员经常试图使用setuid技术让他们的脚本执行他们无法执行的技巧。这可能有用,但也可能非常危险。首先,如果攻击者找到了利用脚本弱点的方法,他们不仅可以访问系统,还可以使用该脚本的有效UID(通常是“根”UID)的权限访问系统。

    为了避免这种情况,Perl程序应在任何文件操作之前将有效UID和GID设置为进程的真实UID和GID:

    \begin{verbatim}
    
         $> = $< # set effective user ID to real UID.
         $) = $( # set effective group ID to real GID.
    

    CGI脚本应该始终以尽可能低的权限运行。
    请注意,在setuid脚本中小心操作并不总能解决问题。某些操作系统的内核中存在bug,这使得setuid脚本本身就不安全。出于这个原因和其他原因,Perl在运行setuid或setgid脚本时会自动切换到特殊的安全模式(污染模式)

    rand()函数

    在确定性机器上生成随机数是一个非常重要的问题。在安全关键型应用程序中,随机数被广泛用于从密码生成到密码学等许多重要任务。为此,生成的数字必须尽可能接近真正的随机数字,这使得攻击者很难(但决不是不可能)预测算法生成的未来数字。Perl rand()函数只调用标准C库中相应的rand(3)函数。这个例行程序不是很安全。函数的作用是:根据称为种子的初始值生成一系列伪随机数。给定相同的种子,使用rand()的程序的两个不同实例将产生相同的随机值。在许多C实现中,以及5.004之前的所有Perl版本中,如果未明确指定种子,则将根据系统计时器的当前值计算种子,该值不是随机的。任何一个有自尊心的破解者都可以在给定的时间点上获得一些关于rand()生成的值的信息,从而准确地预测rand()接下来将生成的数字序列,从而获得危害系统所必需的内容。

    为了解决rand问题(),其中一个方案式使用Linux系统内置随机数生成器/dev/random and /dev/urandom
    这样得到的随机数字比rand()更好,但与其他函数一样,他们都有缺点。这两个设备的区别在于/dev/random当它的随机池没有随机数字时会停止提供随机数字。这时候,/dev/urandom 用户能使用破译生成的密码数字。

    竞态条件Race Conditions

    Race Conditions通常与缓冲区溢出是老手黑客的惯用手段。

    unless (-e "/tmp/a_temporary_file") {
           open (FH, ">/tmp/a_temporary_file");
         }
    

    如果不仔细看,我们会认为这是一个合法程序,不会造成任何伤害。我们首先检查tmp临时文件是否存在,如果不存在,则使用Perl创建。
    此程序问题在于,我们打开文件,检查是正确的。当然完全有可能这个文件的状态发生改变。假设文件不存在,可以让攻击者有机可乘,例如执行命令:

     ln -s /tmp/a_temporary_file /etc/an_important_config_file
    

    现在,我们做的临时文件,实际上是为了配置重要文件。因为我们相信临时文件不存在。因为echeck提示这个临时文件不存在,所以我们继续打开它进行写入。结果,我们配置的文件被删除。
    有些情况就像这样,攻击者可以抢占两个操作并且更改某些东西,这种情况被称为Race condition竞态条件。
    这意味着只使用一个系统调用来检查一个文件并同时创建文件,而不给处理器切换另一个进程的机会。这并不代表不可能。
    下面程序使用sysopen并且指定只写模式。这样即使我们的文件被伪造,我们也不会在打开文件进行写入时杀死它。

    unless (-e "/tmp/a_temporary_file") {
           #open (FH, ">/tmp/a_temporary_file"); 
           sysopen (FH, "/tmp/a_temporary_file", O_WRONLY);  
         }
    

    关于Perl语言的缓冲区溢出

    一般来说,Perl脚本不易受到缓冲区溢出的影响,因为Perl会在需要时动态扩展其数据结构。Perl跟踪每个字符串的大小和分配长度。在每次写入字符串之前,Perl确保有足够的可用空间,并在必要时为该字符串分配更多空间。
    然而,在一些较旧的Perl实现中存在一些已知的缓冲区溢出情况。值得注意的是,5.003版可以利用缓冲区溢出进行攻击。从早于5.004的Perl发行版构建的所有版本的suidperl(一个设计用于解决某些内核setuid脚本中的竞争条件的程序)都是可利用的(CERT Advisory CA–97.17)。

    总结

    在研究Perl的这些方面并查看一些特征性示例时,我们的目标是培养一种直觉,帮助我们第一眼看到Perl脚本中的安全问题,避免在程序中犯类似的错误。

    参考

    The Perl Security man page.
    Rain Forest Puppy, Perl CGI problems, Phrack Magazine, Vol. 9, Issue 55, File 07.
    CGI Programming with Perl, 2nd Edition. O’Reilly and Associates. July 2000.
    Matt Bishop, Michael Dilger. Checking for Race Conditions in File Accesses. Computing Systems 9(2), Spring 1996, pp. 131-152.
    cgSecurity
    the ITS4 Software Security Scanner.
    The SANS institute’s list of top-ten most-critical internet security threats.
    chinaUnix-zhang2428847702的ChinaUnix博客Perl脚本安全问题研究2013.07.24
    The World Wide Web Security FAQ. Chapter 7 – Safe Scripting in Perl.

    更多相关内容
  • Perl脚本的调试方法

    2019-09-18 21:46:38
    ActivePerlPerl语言的Windows版本,Perl是一种很自由而且功能很强大的编程语言,主要被用作 Web 编程、数据库处理、XML 处理以及系统管理,而且Perl 相当快捷实用。 什么是Dzsoft perl ? Dzsoft...

    Q&A

    什么是ActivePerl?

    ActivePerl是Perl语言的Windows版本,Perl是一种很自由而且功能很强大的编程语言,主要被用作 Web 编程、数据库处理、XML 处理以及系统管理,而且Perl 相当快捷实用。

    什么是Dzsoft perl ?
    Dzsoft perl editor是Perl/CGI 脚本编写、编辑和调试工具。它有着舒适而直观的用户界面,适合于初学者和高级程序员。它简单得有些奇怪,但是它真的是一款强大的工具。它有调试功能,一个舒适的带语法加亮的编辑器,一个语法检查功能可以找到你脚本里的错误,还有许多其他功能用来方便Perl的开发。

    dzsoft可以和active perl关联,就可以在编辑器里直接调试程序了。

    ——————————————————

    Perl调试器的用法:
    缺省的Perl调试器就是perl解释器本身,另外还有图形界面的调试器。因为我们在开发
    程序时一般都使用telnet访问服务器,所以这里主要介绍一下缺省的命令行调试器的用法。用
    -d 命令行选项启动Perl解释器,例如
    perl -d test.pl 即进入Perl调试器的交互界面。
    调试命令列表如下:(所有命令都在调试提示符下顶格输入,命令大小写有关)
    h:显示调试器的帮助信息。
    |h:以分页形式显示调试器的帮助信息。
    h h:显示一个压缩的帮助信息。
    h 调试命令:显示某个调试命令的帮助。
    p 表达式:显示变量或表达式的值,不显示复杂变量嵌入的结构和数据。
    x 表达式:显示变量或表达式的值,对较为复杂的变量,以一种可读形式显示嵌入的结构
    和数据。
    V 包名 变量名列表:显示指定包内的所有(或部分)变量的值。(缺省的包名为 main)
    X 变量名列表:显示当前包内所有(或部分)变量的值。
    注:V、X命令中的变量名列表以空格分隔且变量名前应去掉$、@或%
    T:程序的调用栈回退一级。
    s 表达式:单步执行,进入子函数。(step into)如果提供一个表达式并且表达式中包
    括函数调用,则单步进入该函数内。
    n 表达式:单步执行,越过子函数。(step over)
    c 行号/函数名:执行到某一行或某一个函数。
    l:显示未执行的一窗(一屏)文件内容。
    l min-max:显示第min到第max行的文件内容。
    l 行号:显示指定行的内容。
    l 函数名:显示指定函数的一窗(一屏)文件内容。
    w 行号:显示某行周围一窗(一屏)文件内容。
    f 文件名:切换到另一个文件。
    /模式:在当前文件中向前(文件尾)查找匹配的字符串。
    ?模式:在当前文件中向后(文件头)查找匹配的字符串。
    L:显示所有断点和附加操作。
    S 模式:显示匹配(或不匹配,在模式前加!)的函数名。
    t:切换跟踪模式。
    t 表达式:跟踪执行表达式过程。
    b 行号 条件:在某一行设置一个断点,当程序执行到该行并且条件满足时,产生中断。
    b 函数名 条件:在某函数上设置一个断点,当程序执行到该函数并且条件满足时,产生
    中断。
    b load 文件名:在某个文件的第一个可执行语句上设置一个断点。
    d 行号:删除某一行的断点。
    D:删除所有断点。
    a 行号 命令:给程序的某一行加一个附加操作。在执行该行语句前先执行附加的操作。
    A:删除所有已安装的附加操作。
    W 表达式:增加一个监视项。
    W:删除所有监视项。
    O 选项名?:查询调试器可选项的值。
    O 选项名=选项值:设置调试器可选项的值。
    lt Perl语句:设置一个操作显示调试提示符前执行的操作。
    ltlt Perl语句:增加一个显示调试提示符前执行的操作。
    gt Perl语句:设置一个离开调试提示符(转入运行态)时执行的操作。
    gtgt Perl语句:增加一个离开调试提示符(转入运行态)时执行的操作。
    { 调试命令:设置一个操作显示调试提示符前执行的操作。
    {{ 调试命令:设置一个操作显示调试提示符前执行的操作。
    注:上述Perl语句和调试命令均可输入多行,行尾以/转义。
    !number:重新执行以前第number次执行的调试命令。
    !-number:重新执行现在以前number次执行的调试命令。
    !模式:重新执行以前执行过的与模式匹配的调试命令。
    !!命令:不退出调试器执行一个shell命令。
    H-number:显示以前执行的number条调试命令。如果省略number,则显示所有执行过的
    调试命令。
    R:重新启动正在调试的程序。
    q或^D:退出调试器。
    |调试命令:将调试命令的输出分页显示。
    ||调试命令:类似|调试命令,适于有大量输出的调试命令,例如:|V main。
    = 别名 值:给某个调试命令一个别名,例如:= quit q。
    所有未识别的命令:当作插入的一条Perl语句执行。(使用eval)
    Perl调试器的功能还有很多,可以设置很多选项来定制调试器的环境,它本身也是用
    Perl开发的,并且Perl发布中还有接口让你能开发其它的Perl调试器。如果要用Perl开发大
    的项目,有必要详细了解这些细节。使用调试器和设置调试器选项的例子请参考Perl发布中
    关于perldebug的文档。

     

     

    如何调试perl脚本

    perl是一门非常强大的文本处理语言,之前在写perl脚本时,基本上就用Notepad++和print解决了代码编辑和调试的问题。Notepad++作为编辑器其实是一个相当不错的选择了,对perl的代码高亮做得相当漂亮,喜欢的话还能自己扩展;但是对于调试这一块,虽然也用这种土办法写出上千行的能工作的脚本,但老是用print查看结果总不是个办法。

    研究了一下,发现两个不错的工具:

    Komodo IDE

    这是一个由ActiveState发布的针对动态语言的跨平台的集成开发环境。

    所谓跨平台,其支持所谓Mac,Linux,Windows;

    所谓集成开发环境,其支持代码编辑与调试

    所谓动态语言,其除了支持perl,还支持狂多其他动态语言,如python,Ruby,PHP等等。

    image

    熟悉Visual Studio的同学可能会觉得很面熟。

    详细说明可以参考其官方网站:https://www.activestate.com/komodo/

    下载地址是:https://www.activestate.com/activeperl_pro_studio/downloads/

    这的确是一个非常强大的工具,但是295$的价钱实在拒人于千里。21天的试用期到了,你的脚本还没完成,怎么办?

    一般来说,每一个成功的商业软件背后,都会有一个好用(至少是可用)的免费软件。对于调试perl,我们至少还是另外一个选择:

    Notepad++ & ptkdb

    N++是个Windows下比较好用也比较有名的编辑器了,这里不再赘述,不熟悉的同学可以参考这里

    当然,您要喜欢Komodo IDE的风格,它们提供了一个免费的Komodo Edit.

    编辑器有了,调试器的任务就由ptkdb承担了:

    ptkdb is a free/open source debugger for Perl with graphical user interface (GUI) based on Perk/Tk.
    ptkdb is able to run on almost any operating system.

    免费,跨平台,有GUI,应该是可以满足我们的要求了。

    image  <image

    当然,其界面美观度和可操控性都没有Komodo IDE来的好,但是知足吧,有这么一个免费的工具用,已经很不错了。

     

     下面介绍一下如何配打造这套"土IDE"

    1. 安装perl
      对于windows下的用户,可以从activestate网站下载最新的perl安装包:https://www.activestate.com/activeperl/,注意安装的时候路径名不要太长,也不能有空格。
       
    2. 安装tk
      tk是一个图形界面库,是由tcl引到perl中来的,ptkdb依赖于此GUI库显示界面。可以直接在cmd窗口:
      ppm install tk
    3. 安装ptkdb
      安装命令为:
      ppm install devel::ptkdb
      如果用此命令安装失败的话,我们需要手动下载并将模块解压到:C:\Perl\Lib\Devel,当然,请把C:\Perl替换为你的安装路径。

    4. 与Notepad++的集成
      至此,如果你想调试某个script的话,需要:
      perl -d:ptkdb test.pl
      但既然我们在Notepad++中开发脚本,而Notepad++提供了与外部工具集成的机制,我们就可以非常方便的执行一个菜单命令来调试当前的脚本:
      image
      输入命令:
      Perl.exe -d:ptkdb "$(FULL_CURRENT_PATH)"

      然后save为一个run菜单命令,一切就ok了。

    突然间有自己写个perl IDE的冲动~~~

    转载于:https://my.oschina.net/alphajay/blog/52172

    展开全文
  • 注意:如果只需要perl代码,则可以跳到本文的结尾。... 我将向您展示如何使用Perl脚本执行此操作。 你需要什么 任何最新版本的perl(5.06或更高版本都可以)和一台用于运行脚本的服务器。 最好使用...

    注意:如果只需要perl代码,则可以跳到本文的结尾。

    介绍

    许多网站都有您可以用来下载文件的表格或链接。 您单击一个表单按钮或单击一个链接,一两分钟后,您的Web浏览器中会弹出一个文件下载对话框,并提示您输入一些说明,例如“打开”或“保存”。 我将向您展示如何使用Perl脚本执行此操作。

    你需要什么

    任何最新版本的perl(5.06或更高版本都可以)和一台用于运行脚本的服务器。 最好使用允许您将文件存储在Web根目录之上的服务器,但这不是必需的。 稍微了解一下HTML会有所帮助,但这不是必需的。 通常,您将脚本上载到cgi-bin文件夹中,并将文件权限设置为755。服务器上载脚本的文件夹和权限可能会有所不同。

    Perl代码

    几乎所有作为CGI进程运行的perl脚本都需要以shebang行开头。 最常见的shebang行是:

    #!/usr/bin/perl
    它只是告诉服务器在哪里可以找到perl。 您的服务器所需的shebang行可能有所不同。 大多数网络主机会将这些信息发布在其网站的某个位置。 为了获得良好的perl编码实践和CGI安全性,我们将在shebang行上添加一个开关:-T。 注意:它必须是大写的T。
    #!/usr/bin/perl -T
    T代表“异味”模式。 作为脚本的程序员,这实际上是为了防止您犯一个可怕的错误,并允许CGI表单的用户将数据发送到服务器,而该数据可能以不安全的方式使用。 作为CGI进程运行的所有perl脚本都应使用-T开关,因此我将其包括在内。 模组

    模块有点像可以在perl程序中使用的单独的perl程序。 许多人编写的模块已成为其他perl程序员一直使用的标准。 我们将使用以下模块:

    
    use strict;
    use warnings;
    use CGI;
    # Uncomment the next line only for debugging the script.
    #use CGI::Carp qw/fatalsToBrowser/; 
    前两个实际上不是模块,它们是实用程序。 它们会影响perl本身的功能。 在本文中,我不会对其进行解释。 您需要相信我,它们在几乎所有perl程序中都非常重要。 “ CGI”模块是将为我们完成大部分工作的模块:处理表单数据,打印http标头等。 “ CGI :: Carp”模块确实用于调试,如果有问题,可以帮助您使脚本运行。 如果有任何致命错误导致脚本失败,它将在屏幕上显示一条错误消息。 这些错误也将在服务器错误日志中打印出来。

    程序的后两行建立了一些重要参数:

    
    $CGI::POST_MAX = 1024;
    $CGI::DISABLE_UPLOADS = 1; 
    “ POST_MAX”以字节为单位设置将被视为过多数据的最大限制,并导致脚本返回错误。 我将此限制设置为较低(1 kb),因为此脚本需要发送给它的数据很少。 第二行告诉脚本不接受文件上传。 有道理,因为我们要下载文件,而不是上传文件。 这样可以防止用户尝试使用更改后的格式将文件发送到您的脚本。 可以保存所有表单并更改HTML代码,并且用户可以将所需的任何内容发送到脚本,这取决于您是否要在服务器端进行。 用户所做的一切完全不受您的控制。 设置路径和选项
    
    ####################################
    #### User Configuration Section ####
    #################################### 
    # The path to where the downloadable files are. 
    # Preferably this should be above the web root folder.
    my $path_to_files = '/home/user/downloads/'; 
    # The path to the error log file
    my $error_log     = '/home/user/downloads/logs/errors.txt'; 
    # Option to log errors: 1 = yes, 0 = no
    my $log           = 1; 
    # To prevent hot-linking to your script
    my $url = 'http://www.yoursite.com';
    ########################################
    #### End User Configuration Section ####
    ######################################## 
    $ path_to_files是存储要下载文件的目录。 我建议您将它们存储在无法通过Web访问的文件夹中。 通常可以通过将它们放在与根Web文件夹平行的文件夹(public_html或www)中或上方的文件夹中来完成。

    $ error_log是errors.txt文件的路径,该文件记录了脚本生成的错误。

    $ log打开或关闭错误日志。

    $ url应该是您网站的名称,包括“

    http://”部分。 创建CGI对象
    my $q = CGI->new;
    $ q是我们将用于执行CGI模块的各种方法的对象。 我喜欢将其视为管家。 您告诉管家您想要什么,他知道如何完成,您不必担心细节。 我们的“管家”,$ q,将知道如何处理我们给他的“命令”。

    实际上,CGI模块具有许多您可以赋予“管家”的“命令”。 我们将使用其中一些。 学习使用CGI模块几乎就像学习小型编程语言一样。 但是美丽之处在于您只需要知道命令的功能,而不是命令的方式即可。 就像真正的男管家一样,您必须相信他知道他在做什么,并且可以高效,高效地完成工作,而无需顾虑。 我建议您花些时间阅读CGI模块文档,即使您不太了解CGI模块文档,至少也应该熟悉基本的表单处理方法。 我留给你。

    安全检查站

    当将脚本作为CGI运行时,请不要低估对安全性的需求。 我们将使用三个“检查点”来检测任何可疑活动。 第一个是要检查发送到脚本的数据量。 我们将cgi_error()命令传递给值得信赖的男管家“ $ q”,他将返回响应$ error。 “ 413”表示已超过我们为$ CGI :: POST_MAX设置的限制,因此我们将检查该响应。 注意:在整篇文章中,我交替使用命令和方法来表示同一件事。

    
    if (my $error = $q->cgi_error()){
       if ($error =~ /^413\b/o) {
          error('Maximum data limit exceeded.');
       }
       else {
          error('An unknown error has occured.'); 
       }
    } 
    接下来,我们检查是否有人尝试将文件上传到脚本。 为了发送文件,必须在CGI表单的“实体”属性中使用“多部分/表单数据”。
    
    if ($ENV{'CONTENT_TYPE'} =~ m|^multipart/form-data|io ) {
       error('Invalid Content-Type : multipart/form-data.')
    } 
    接下来,我们检查使用脚本的请求是否来自您的网站。
    if ($ENV{'HTTP_REFERER'} && $ENV{'HTTP_REFERER'} !~ m|^\Q$url|io) {
       error('Access forbidden.')
    }
    获取文件名

    我将使用Vars方法将发送到脚本的所有参数转换为哈希值。 再次,我们调用“ $ q”进行实际工作。

    my %IN = $q->Vars;
    现在,我们确保有一个名为“ file”的参数。
    my $file = $IN{'file'} or error('No file selected.');
    验证,验证,验证

    您说的还不够,必须验证发送到CGI脚本的所有数据。 如果我们只允许将任何内容发送到脚本,则有人可以发送以下内容:/ foo / bar并根据您附加的路径,脚本会乖乖地去查找foo目录并下载bar文件。 当然,人们可以尝试做一些更糟糕的事情,但这不是有关如何使用前门入侵网站的文章。 为了防止用户摆脱这种危险的特技,我们需要验证发送到脚本的数据。

    
    if ($file =~ /^(\w+[\w.-]+\.\w+)$/) {
       $file = $1;
    }
    else {
       error('Invalid characters in filename.');
    }     
    该代码中看起来很神秘的部分($ file =〜/^(\w+[\w.-]+\.\w+)$/)被称为正则表达式(regexp)。 通常,正则表达式是用于验证/过滤表单数据的内容。 正则表达式已经超出了本文的范围。 如果您有兴趣了解该正则表达式,则必须阅读一些正则表达式教程。 请参阅文章末尾的在线资源。 基本上,它正在检查数据是否是这样的:frog.gif,puppy-dog.jpg或meatloaf.txt。 它以基本文件名格式filename.ext检查受限制的字符集“ a-zA-Z0-9_-。”,并拒绝其他任何无效字符。

    上面的代码也“保留”了数据。 由于数据将用于打开服务器上的文件,因此我们必须取消对该文件的污染,以满足–T开关的要求,即我们没有做任何不安全的事情。 取消污染数据的唯一方法是使用正则表达式。 正则表达式中的括号将模式匹配存储在内存中,我们使用$ 1获得该值。 然后,我们将值分配回变量$ file,现在将用于打开文件的数据位于脚本的内部,并且–T开关将认为它可以安全使用。 由您决定验证/过滤足以完成任务。 例如,如果您在regexp /(.*)/中使用了此模式,则-T开关不会抱怨,但是数据将像在表单中输入或通过超链接一样发送到脚本中。 那将是一件愚蠢的事。

    如果数据未通过验证例程,则会将一条消息发送到错误子例程,并向用户发出警报。

    准备下载
    download($file) or error('An unknown error has occured.');
    如果文件下载失败,则会将一条消息发送到错误子例程,并向用户发出警报。 download()子例程
    
    sub download {
       my $file = $_[0] or return(0); 
       # Uncomment the next line only for debugging the script 
       #open(my $DLFILE, '<', "$path_to_files/$file") or die "Can't open file '$path_to_files/$file' : $!"; 
       # Comment the next line if you uncomment the above line 
       open(my $DLFILE, '<', "$path_to_files/$file") or return(0); 
       # this prints the download headers with the file size included
       # so you get a progress bar in the dialog box that displays during file downloads. 
       print $q->header(-type            => 'application/x-download',
                        -attachment      => $file,
                        -Content_length  => -s "$path_to_files/$file",
       ); 
       binmode $DLFILE;
       print while <$DLFILE>;
       undef ($DLFILE);
       return(1);
    } 
    子例程的第一行获取文件名或将0(零)返回给调用方以指示失败。 有两行打开文件,一行用于调试目的,一行用于在一切正常运行时运行脚本。 代码的下一部分将显示使Web浏览器下载文件而不是尝试显示文件的标头。
    
       print $q->header(-type            => 'application/x-download',
                        -attachment      => $file,
                        -Content_length  => -s "$path_to_files/$file",
       ); 
    header()方法中的“ type”选项是导致下载的特定标题。 的

    “附件”选项定义要下载的文件的名称。 您可以给文件指定任何名称,而不必是实际的文件名。 如果您有理由隐藏文件的真实名称,或者需要为下载的文件提供真实名称以外的其他名称,则这可能很有用。 “ Content-length”选项使用–s文件测试操作符来获取文件的大小。 这允许文件下载对话框显示文件大小和进度条,并估计完成文件下载所需的时间。

    子例程的最后四行完成了下载过程。

    
       binmode $DLFILE;
       print while <$DLFILE>;
       undef ($DLFILE);
       return(1); 
    binmode()函数告诉perl以“二进制”模式传输文件。 使用二进制模式将在接收端损坏文件的可能性很小。 但是通常使用它没有问题,在某些情况下有必要。 如果在使用binmode时遇到问题,请删除或注释掉该行。 有关更多详细信息,请参见binmode函数文档。 “打印”行实际上是将文件从服务器传输到客户端的行。 “ undef”关闭文件,因为我使用了间接文件句柄。 我们在子例程末尾返回1(一)以指示成功。 子程序

    “错误”子例程非常简单。 它使用一些html生成方法来打印基本的html文档,该文档显示了我们发送给它的错误消息,存储在$ _ [0]中。 CGI模块文档中讨论了每种方法。 如果您打开了错误日志记录,则也会调用“ log_error”函数。

    
    sub error {
       print $q->header(-type=>'text/html'),
             $q->start_html(-title=>'Error'),
             $q->h3("Error: $_[0]"),
             $q->end_html;
       log_error($_[0]) if $log;
       exit(0);
    } 
    接下来是“ log_error”子例程。 可以检测到脚本检测到的每个错误,因此您可以查看站点的访问者如何滥用脚本。 这是值得跟踪的好信息。 可能矫over过正,但我​​坚信跟踪错误,因为它们可以帮助您编写更安全的脚本并向您发出警告,让您注意僵尸程序或试图滥用该脚本的人。 它将错误和一些其他信息附加到文件中。 我个人喜欢记录发送到脚本的名称/值对,以查看用户是否更改了表单或查询字符串。 这些值将在$ params中,格式如下:“ name =” value ::: name = value ::: name = value”。 “ scalar localtime()”为您带来方便,因此您可以轻松读取错误的日期/时间。 “时间”以纪元秒为单位记录日期/时间,这是记录日期/时间的标准方法,因此计算机程序和脚本可以理解它。 最终由您决定如何处理此信息。 我建议您不时检查一次错误日志。 您可以将其删除,脚本将创建一个新的脚本。 或者完全在脚本的“用户配置”部分中关闭错误日志记录。
    
    sub log_error {
       my $error = $_[0]; 
       # Uncomment the next line only for debugging the script
       #open (my $log, ">>", $error_log) or die "Can't open error log: $!"; 
       # Comment the next line if you uncomment the above line
       open (my $log, ">>", $error_log) or return(0); 
       flock $log,2;
       my $params = join(':::', map{"$_=$IN{$_}"} keys %IN) || 'no params';
       print $log '"', join('","',time, 
                          scalar localtime(),
                          $ENV{'REMOTE_ADDR'},
                          $ENV{'SERVER_NAME'},
                          $ENV{'HTTP_HOST'},
                          $ENV{'HTTP_REFERER'},
                          $ENV{'HTTP_USER_AGENT'},
                          $ENV{'SCRIPT_NAME'},
                          $ENV{'REQUEST_METHOD'},
                          $params,
                          $error),
                          "\"\n";
    } 
    介面

    剩下要做的唯一决定就是如何允许您网站的访问者访问下载脚本。 您可以使用超链接或HTML表单或两者的某种组合。 您可以让另一个脚本(甚至相同的脚本)生成该接口。 基本概念是将下载文件的名称传递给下载脚本。 使用超链接的示例:

    <a href=”cgi-bin/download.pl?file=frog.jpg”>Download the Frog Image</a>
    我将由您自己来发现创建下载脚本接口的其他方法。 结论

    这是一个非常基本的脚本。 您可以向脚本添加更多功能,例如,添加一个计数器文件,该计数器文件跟踪每个文件的下载次数。 您可以添加身份验证,以便您的用户必须登录才能下载文件。 您可以将脚本绑定到数据库,而不是将文件存储在服务器上。

    凯文(又名KevinADC)

    本文受《

    创用CC许可 资源 Perldoc网站所有在线perl文档。 CGI.pm CGI模块文档(在perldoc上)。 搜索CPAN综合Perl存档网络。 巨大的Perl模块存储库

    和更多。

    CGI安全性CGI安全性入门。 完整的脚本
    
    #!/usr/bin/perl -T 
    ## Load pragmas and modules
    use strict;
    use warnings;
    use CGI;
    # Uncomment the next line only for debugging the script.
    #use CGI::Carp qw/fatalsToBrowser/; 
    # The next two lines are very important. Do not modify them
    # if you do not understand what they do.
    $CGI::POST_MAX = 1024;
    $CGI::DISABLE_UPLOADS = 1;   
    ####################################
    #### User Configuration Section ####
    #################################### 
    # The path to where the downloadable files are. 
    # Prefereably this should be above the web root folder.
    my $path_to_files = '/home/user/downloads/'; 
    # The path to the error log file
    my $error_log     = '/home/user/downloads/logs/errors.txt'; 
    # Option to log errors: 1 = yes, 0 = no
    my $log           = 1; 
    # To prevent hot-linking to your script
    my $url = 'http://www.yoursite.com'; 
    ####################################
    ## End User Configuration Section ##
    #################################### 
    # Edit below here at your own risk 
    my $q = CGI->new; 
    ######################################
    ## This section checks for a number ##
    ## of possible errors or suspicious ##
    ## activity.                        ##
    ###################################### 
    # check to see if data limit is exceeded
    if (my $error = $q->cgi_error()){
       if ($error =~ /^413\b/o) {
          error('Maximum data limit exceeded.');
       }
       else {
          error('An unknown error has occured.'); 
       }
    } 
    # Check to see if the content-type is acceptable.
    # multipart/form-data indicates someone is trying
    # to upload data to the script with a hacked form.
    # $CGI_DISABLE_UPLOADS prevents uploads. This routine
    # is to catch the attempt and log it. 
    if ($ENV{'CONTENT_TYPE'} =~ m|^multipart/form-data|io ) {
       error('Invalid Content-Type : multipart/form-data.')
    }        
    # Check if the request came from your website, if not
    # it indicates remote access or hot linking.
    if ($ENV{'HTTP_REFERER'} && $ENV{'HTTP_REFERER'} !~ m|^\Q$url|io) {
       error('Access forbidden.')
    } 
    ################################
    ## End error checking section ##
    ################################ 
    # Get the data sent to the script.
    my %IN = $q->Vars; 
    # Parse the "file" paramater sent to the script.
    my $file = $IN{'file'} or error('No file selected.'); 
    # Here we untaint the filename and make sure there are no characters like '/' 
    # in the name that could be used to download files from any folder on the website.
    if ($file =~ /^(\w+[\w.-]+\.\w+)$/o) {
       $file = $1;
    }
    else {
       error('Invalid characters in filename.');
    }     
    # Check if the download succeeded
    download($file) or error('An unknown error has occured.');  
    #################
    ## SUBROUTINES ##
    ################# 
    # download the file
    sub download {
       my $file = $_[0] or return(0); 
       # Uncomment the next line only for debugging the script 
       #open(my $DLFILE, '<', "$path_to_files/$file") or die "Can't open file '$path_to_files/$file' : $!"; 
       # Comment the next line if you uncomment the above line 
       open(my $DLFILE, '<', "$path_to_files/$file") or return(0); 
       # This prints the download headers with the file size included
       # so you get a progress bar in the dialog box that displays during file downlaods. 
       print $q->header(-type            => 'application/x-download',
                        -attachment      => $file,
                        'Content-length' => -s "$path_to_files/$file",
       ); 
       binmode $DLFILE;
       print while <$DLFILE>;
       undef ($DLFILE);
       return(1);
    } 
    # This is a very generic error page. You should make a better one.
    sub error {
       print $q->header(-type=>'text/html'),
             $q->start_html(-title=>'Error'),
             $q->h3("Error: $_[0]"),
             $q->end_html;
       log_error($_[0]) if $log;
       exit(0);
    } 
    # Log the error to a file
    sub log_error {
       my $error = $_[0]; 
       # Uncomment the next line only for debugging the script
       #open (my $log, ">>", $error_log) or die "Can't open error log: $!"; 
       # Comment the next line if you uncomment the above line
       open (my $log, ">>", $error_log) or return(0); 
       flock $log,2;
       my $params = join(':::', map{"$_=$IN{$_}"} keys %IN) || 'no params';
       print $log '"', join('","',time, 
                          scalar localtime(),
                          $ENV{'REMOTE_ADDR'},
                          $ENV{'SERVER_NAME'},
                          $ENV{'HTTP_HOST'},
                          $ENV{'HTTP_REFERER'},
                          $ENV{'HTTP_USER_AGENT'},
                          $ENV{'SCRIPT_NAME'},
                          $ENV{'REQUEST_METHOD'},
                          $params,
                          $error),
                          "\"\n";
    }

    From: https://bytes.com/topic/perl/insights/857373-how-make-file-download-script-perl

    展开全文
  • perl登录各种网站的原理与实现tkorays(tkorays@...所以,下面介绍下使用perl登录网站的原理,以及实现。原理如果你了解一些http原理的话,这就很好理解了。使用浏览器打开网页无非就是:你发送请求,然后服务器响应...

    perl登录各种网站的原理与实现

    tkorays(tkorays@hotmail.com)

    小孩子才践行大道理,大人只会讲。

    写脚本抓取某个页面内容很简单,但是往往事情没那么简单。有些页面必须是要登录才能查看的,比如你想抓取选课系统中自己的成绩?所以,下面介绍下使用perl登录网站的原理,以及实现。

    原理

    如果你了解一些http原理的话,这就很好理解了。使用浏览器打开网页无非就是:你发送请求,然后服务器响应,给你所需要的页面内容。当然这些请求和相应都是有一定规律的。

    先说浏览器发送请求。

    请求常用有POST和GET两种,撇去细节不谈,两者有个很大的区别就是POST传递的参数是不显示在url中,而GET方式传递的参数会在url中显示。而我们登录有表单提交,经常要用POST和GET。比如我在开源中国搜索apache:

    20a47eb7b838f7b7470656c47ce9c41b.png

    这个表单是GET方式的,所以url中会有参数。

    那么,是否浏览器就发送了这么多数据给服务器了呢,答案当然是,否。如上图中,点开头消息,请求头如下:

    9c726f9e284ce4e5502511611e1ea84b.png

    其实还发送了这些数据,所以如果你要自己用c/c++等实现,不要忘记发送必要的数据哦。(提示,每个数据使用\r\n分割的)如果你使用perl,有现成的库,你不需要关注太多细节的,只需要知道,可能须有cookie!

    因此,请求你只需要关注,请求的参数以及可能需要的cookie。

    接下来说相应。

    同样,浏览器返回的html网页不止是你查看源代码看到的那些,还包括响应头。

    7bafae71070ebdba124c3ed7399941d6.png

    相应头和请求头差不多,主要高速浏览器该怎么处理这些相应。注意上面的Content-Type没,后面的text/html表示返回的数据是html格式的。(返回javascript时,content-type是application/x-javascript)。当然并不是所有的相应都有响应头,而且大多时候,你也不需要关注它。这里我只是凑字数说说,完全可以忽略。返回的页面,你完全只需要获取头后面的东西(反正你也知道返回的是html还是javascript,何必还判断呢)。

    cookies是保存在浏览器端的一些小数据,可以用于保存一些信息。它其实就是一些键值对。很多时候,服务器会生成一些数据给浏览器,这些在之后的通信过程中是很重要的。所幸的是,perl有现成的库供我们管理cookies,如果你要一步步实现,就头大了。

    对了,还要注意的是url编码问题,有时候会出现。

    实现

    说了原理当然要说实现了,不然我就是欺骗读者的感情了。

    perl中使用到的主要包有LWP,会用到它的UserAgent、Cookies、Response等类。这些类有不明白的地方可以查看cpan。

    这里我们需要模拟一个浏览器的行为,所以要创建一个UserAgent对象。

    my $ua = LWP::UserAgent->new;

    $ua->agent("Mozilla/5.0 (Windows NT 6.1; rv:30.0) Gecko/20100101 Firefox/30.0");

    这样,请求头里面的浏览器就变成了火狐,服务器会以为我们是使用火狐呢。

    不能忘记cookies哦。

    my $cookie_jar = HTTP::Cookies->new(

    file=>'lwp_cookies.txt',

    autosave=>1,

    ignore_discard=>1);

    $ua->cookie_jar($cookie_jar);

    之后调用UserAgent的post和get方法,想干什么就干甚么。

    如果你看的不是很明白,下面给出一个登录人人并发状态的例子,好好领悟吧。有注释哦:

    #!/usr/bin/perl

    # Copyright 2014 tkorays. All rights reserved.

    # author tkorays

    # email tkorays@hotmail.com

    use strict;

    use warnings;

    use LWP;

    use LWP::Simple;

    use LWP::UserAgent;

    use HTTP::Cookies;

    use HTTP::Headers;

    use HTTP::Response;

    use Encode;

    use URI::Escape;

    use URI::URL;

    my $email = '***@**.com';

    my $password = '***';

    my $domain = 'renren.com';

    my $hostid='';

    my $requestToken='';

    my $rtk='';

    my $channel='renren';

    my $ua = LWP::UserAgent->new;

    $ua->agent("Mozilla/5.0 (Windows NT 6.1; rv:30.0) Gecko/20100101 Firefox/30.0");

    my $cookie_jar = HTTP::Cookies->new(

    file=>'lwp_cookies.txt',

    autosave=>1,

    ignore_discard=>1);

    $ua->cookie_jar($cookie_jar);

    my $login_url = 'http://www.renren.com/PLogin.do';

    # 这里面没有判断是否需要验证码,聪明的你学完后肯定知道怎么搞定的

    # 人人是post登陆的,第一个参数是登陆的地址,第二个参数是一个匿名hash

    my $res = $ua->post($login_url,{

    'email'=>$email,

    'password'=>$password,

    'domain'=>$domain});

    my $homepage;

    # 判断响应头里面的location,确定是否登陆成功

    if($res->header('Location') eq 'http://www.renren.com/Home.do'){

    print 'login ok...',"\n";

    $homepage = $ua->get('http://www.renren.com/home');

    }else{

    exit;

    }

    # 作为福利,下面还是贴上,发状态的吧,后面就不注释了

    #####################################

    if($homepage->is_success){

    my $pagect = $homepage->content;

    $pagect =~ /id\s:\s"(\d+)"/g;

    $hostid = $1;

    $pagect =~ /requestToken\s:\s'(.+)'/g;

    $requestToken = $1;

    $pagect =~ /_rtk\s:\s'(.+)'/;

    $rtk = $1;

    }else{

    exit;

    }

    my $purl = 'http://shell.renren.com/'.$hostid.'/status';

    my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime();

    $year +=1900;

    $mon++;

    my $postret = $ua->post($purl,{

    'content'=>"renren test,by perl script,author:tkorays,date:$year-$mon-$day $hour:$min:$sec.",

    'hostid'=>$hostid,

    'requestToken'=>$requestToken,

    '_rtk'=>$rtk,

    'channel'=>$channel});

    if($postret->is_success){

    print 'send ok...',"\n";

    }else{

    print 'fuck!';

    }

    有验证码怎么办?UserAgent的get、方法获取啊。

    给个简单的例子吧:

    my $res = $ua->get($url.'/GenImg');

    if(!$res->is_success){

    return 0;

    }

    open(FILE_HANDLE,'>img.jpg');

    binmode FILE_HANDLE;

    print FILE_HANDLE $res->content;

    close FILE_HANDLE;

    上面的代码把验证码存为图片。所以验证码问题就解决了。

    GO

    问题都解决了,你就赶快行动?

    展开全文
  • windows下perl的安装和脚本的运行

    千次阅读 2017-09-02 15:30:00
    下载perl编译器。下载地址:http://pan.baidu.com/s/1i3GLKAp 下载后的文件如下图所示。 perl的安装。 直接双击运行下载的文件,首先会出现perl版本等等信息的介绍,不要理,直接next就会出现...
  • 无论从哪里看,我都找到使用Perl和LWP从安全站点获取网页的理想解决方案。 经过许多痛苦和磨难之后,我终于编写了一个脚本来自己完成登录过程的自动化。 一路,我注意到其他人也在努力解决类似的问题。 ...
  • 在电脑开启Apache服务后,如何让外部网络访问呢? 一:httpd.conf文件更改 路径:D:\ wamp1 \ bin \ apache \ apache2.4.9 \ conf \ httpd.conf(根据安装目录自行修改) 第一个地方 < Directory> ...
  • 在这篇文章中,我会展示如何用Perl脚本来创建和访问SQLite数据库。我演示的Perl代码片段是完整的,所以你可以很简单地修改并集成到你的项目中。访问SQLite的准备我会使用SQLite DBI Perl驱动来连接到SQLi...
  • Perl DBI连接MySQL数据库Perl中一个最酷的模块就是Perl数据库接口...由此,使用Perl就可以很容易地利用数据库和建立动态Web网页。当前,MySQL是广泛用于Web网站开发的数据库,它是一种免费、开源的SQL操作。本期...
  • perl + fastcgi + nginx搭建nginx + fastcgi是php下最流行的一套环境了,那perl会不会也有fastcgi呢,当然有,今天来搭建下nginx下perl的fastcgi.性能方面也不亚于php,但是现在web程序php的流行程度perl无法比拟了...
  • 朋友给了我一个课题,就是用perl实现一个网站监控的脚本。 这个脚本主要实现的功能就那么几点,每间隔一段时间获取网站的应答状态、网站的响应时间。 如果应答出错,通过邮件的形式将应答状态码发送过来。 首先先...
  • cgi脚本 在我最初创建自己的第一个商业网站的互联网时代,生活是美好的。 我安装了Apache,并创建了一些简单HTML页面,这些页面陈述了有关我的业务的一些重要内容,并提供了重要信息,例如产品概述以及如何与我...
  • Perl CGI编程

    2021-01-03 04:55:50
    Perl CGI编程 什么是CGI CGI 目前由NCSA维护,NCSA定义CGI如下: CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器如:HTTP服务器,提供同客户端HTML页面的接口。 网页浏览 为了更好的了解...
  • 脚本语言

    2021-04-30 03:36:16
    脚本语言的特点:需要编译。脚本语言的作用:在说脚本语言的作用前,我们先说说HTML(超文本标记语言)(结构化语言)语言的作用;HTML可以很方便的将文本,图形,表格,表单,超级链接等放入网页中;为了更灵活的控制...
  • 解决apache上访问 cgi脚本时总是在网页中显示出脚本的源代码而不是执行结果的问题
  • CGI PL PERL脚本 提权

    2019-10-09 01:05:45
    windows 2003 下,安装ActivePerl-5.16.2.1602-MSWin32-x86-296513 ...此时,网站支持HTTP访问CGI 或者 .pl脚本。 可以用来提取,.CGI .PL权限比较大,大于ASPX。 首先上传CGI 提权执行...
  • 使用PERL脚本生成PDF输出

    千次阅读 2010-12-17 11:40:00
    使用PERL脚本生成PDF输出 - [perl] 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://xufish.blogbus.com/logs/35754517.html<br /> 引言  文档的页面显示和打印效果...
  • 如果你想编写一些能够访问MySQL数据库的Perl脚本,就需要安装DBI模块,需要安装两组DBI模块,一组是负责提供各种DBI基本驱动程序的 DBI模块,另一组是负责提供各种MySQL专用驱动程序的DBD::mysql模块,如果你还想...
  • Nginx(二十)nginx配置perl

    2021-01-19 00:31:34
    nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。 nginx一般是把请求发fastcgi管理进程处理,fascgi管理进程选择cgi子进程处理结果并返回被...
  • 脚本及恶意网页病毒

    千次阅读 2021-06-19 21:40:13
    脚本及恶意网页病毒【实验目的】【实验环境】【实验预备知识点】【实验内容】【实验步骤】【实验思考题】 【实验目的】 1、了解脚本及恶意网页的运行环境,运行平台,语言基础及传播手段; 2、掌握脚本及恶意网页的...
  • 在win2003 IIS6.0设置时...然而,事实,“脚本资源访问”是暗藏危机的,它可能成为被人利用的漏洞,只是多数情况下该漏洞被利用的条件不能完全满足而已,也可以说是该漏洞被利用的可能性不太高罢了。脚本资源访问...
  • 将食谱导出为可打印的网页、RecipeML (XML) 和 Meal-Master 格式(此产品与 RecipeML 兼容) 通过电子邮件将食谱发送给朋友 可编辑、无限深度的类别层次结构 食谱可以是无限数量的类别 用户可以编辑他们提交的食谱 ...
  • 接到同事的需求,说是需要做个脚本,输出访问网页的速度。考虑到也就Perl比较熟,就上网搜了搜模块。 先用的是Benchmark,大体是先两个时间戳,然后相减: use Benchmark; my $timestamp1 = Benchmark->new; #...
  • 开始PerlBeginning Perl

    2019-11-15 17:57:40
    涵盖安装方法,核心语言元素(正则表达式,引用,模块等)以及基本的应用技术。 还介绍了如何访问和使用数据库以及编写CGI脚本以生成网页
  • 作者:陈曦日期:2012-6-30 11:18:06环境:[Mac 10.7.1 Lion Intel-based i3,支持64位指令 Python 2.7.1 gcc4.2.1]转载请注明出处Q1: 脚本的本质是什么?...Q2: 为什么写脚本不熟练的程序员...
  • php是脚本语言吗

    2021-03-24 00:26:35
    PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习,使用广泛,主要适用于Web开发领域。PHP 脚本主要用于以下三个领域:服务端...
  • 我在网上研究过,发现了几个有趣的Perl模块/框架,比如HTML:Mason,HTML :: Embperl,或MVC Catalyst框架等,它们可以让我在...例如,Apache 1.3.3版和Perl版本5.8.0(低于Catalyst的要求)我使用脚本检查所有已安装的Perl...
  • 【摘要】PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程...php不能访问mysql怎么办php不能访问mysql的解决方法:1、通过控制台进入mysql,执行S...
  • perl入门

    千次阅读 2015-10-24 09:49:42
    perl是一门免费及开源的脚本语言,由Larry Wall所创造,这门语言以实用,快速开发为主要目标,与当前流行的面向对象,结构化编程有些格格不入。但是这并妨碍perl被广泛流传和使用,世界范围内围绕Perl建立起了...
  • Perl is a very popular scripting language which is used to develop a wide variety of tools. One of it’s well know uses is web based CGI (Common Gateway Interface) applications which allow Perl ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,057
精华内容 13,622
关键字:

网页上不能访问perl脚本