【问题标题】:Perl - Trouble with my unzip system call for zip file crackPerl - 我的解压缩系统调用 zip 文件破解时遇到问题
【发布时间】:2015-03-07 06:30:28
【问题描述】:

我是一名大三学生,目前正在上一门脚本语言课程,该课程旨在让我们在一个学期内学习中级 bash、perl 和 python。由于这门课程是加速的,我们可以快速浏览主题,如果我们有问题,我们的教授也支持使用论坛来补充我们的学习。

我目前正在处理我们的第一个任务。要求是使用提供的词表“linux.words”和基本的蛮力攻击创建一个非常简单的字典攻击。暴力破解需要补偿 4 个字母字符串的任意组合。

我使用 print 语句来检查我的逻辑是否合理,而且看起来确实如此。如果您对如何改进我的逻辑有任何建议,我会在这里学习,我会全力以赴。

这是在 Ubuntu v12.04 上,以防万一。

我尝试用像独角兽这样的直词替换调用中的标量,它运行良好,显然是错误的密码,并且它正确返回。我在终端和脚本本身都这样做了。在将我推荐给论坛之前,我的教授已经检查了 15 分钟,然后说它看起来不错。他怀疑由于我使用 Notepad++ 编写代码,可能存在隐藏字符。我使用 vim 直接在终端中重写了代码,它给出了与上面相同的错误。下面粘贴的代码来自vim。

我的实际问题是我的系统调用给我带来了问题。它返回用于解压缩显示用法和其他帮助材料的帮助函数。

这是我的代码。

#!/usr/bin/perl 

use strict;
use warnings;

#Prototypes
sub brute();
sub dict();
sub AddSlashes($);

### ADD SLASHES ###

sub AddSlashes($)
{

    my $text = shift;
    $text =~ s/\\/\\\\/g;
    $text =~ s/'/\\'/g;
    $text =~ s/"/\\"/g;
    $text =~ s/\\0/\\\\0/g;
    return $text;

}

### BRUTEFORCE ATTACK ###
sub brute()
{

    print "Bruteforce Attack...\n";
    print "Press any key to continue.\n";
    if (<>)
    {

        #INCEPTION START
        my @larr1 = ('a'..'z'); #LEVEL 1 +
        foreach (@larr1)
        {
        my $layer1 = $_; #LEVEL 1 -

            my @larr2 = ('a'..'z'); #LEVEL 2 +
            foreach (@larr2)
            {
            my $layer2 = $_; # LEVEL 2 -

                my@larr3 = ('a'..'z'); #LEVEL 3 +
                foreach (@larr3)
                {
                my $layer3 = $_; #LEVEL 3 -

                    my@larr4 = ('a'..'z'); #LEVEL 4 +
                    foreach (@larr4)
                    {
                    my $layer4 = $_;
                    my $pass = ("$layer1$layer2$layer3$layer4"); 
                    print ($pass); #LEVEL 4 -
                    }

                }

            }

        }

    }

}

### DICTIONARY ATTACK ###
sub dict()
{

    print "Dictionary Attack...\n"; #Prompt User
    print "Provide wordlist: ";
    my $uInput = "";
    chomp($uInput = <>); #User provides wordlist
    (open IN, $uInput) #Bring in wordlist
        or die "Cannot open $uInput, $!"; #If we cannot open file, alert

    my @dict = <IN>; #Throw the wordlist into an array

    foreach (@dict)
    {

        print $_; #Debug, shows what word we are on
        #next; #Debug
        my $pass = AddSlashes($_); #To store the $_ value for later use

        #Check pass call
        my $status = system("unzip -qq -o -P $pass secret_file_dict.zip > /dev/null 2>&1"); #Return unzip system call set to var

        #Catch the correct password
        if ($status == 0)
        {

            print ("Return of unzip is ", $status, " and pass is ", $pass, "\n"); #Print out value of return as well as pass
            last;

        }

    }
}
### MAIN ###
dict();


exit (0);

这是我的错误

See "unzip -hh" or unzip.txt for more help.  Examples:
  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip
  unzip -p foo | more  => send contents of foo.zip via pipe into program more
  unzip -fo foo ReadMe => quietly replace existing ReadMe if archive file newer
aerify
UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP.

Usage: unzip [-Z] [-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]
  Default action is to extract files in list, except those in xlist, to exdir;
  file[.zip] may be a wildcard.  -Z => ZipInfo mode ("unzip -Z" for usage).

  -p  extract files to pipe, no messages     -l  list files (short format)
  -f  freshen existing files, create none    -t  test compressed archive data
  -u  update files, create if necessary      -z  display archive comment only
  -v  list verbosely/show version info       -T  timestamp archive to latest
  -x  exclude files that follow (in xlist)   -d  extract files into exdir
modifiers:
  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)
  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files
  -j  junk paths (do not make directories)   -aa treat ALL files as text
  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields
  -C  match filenames case-insensitively     -L  make (some) names lowercase
  -X  restore UID/GID info                   -V  retain VMS version numbers
  -K  keep setuid/setgid/tacky permissions   -M  pipe through "more" pager
  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives
  -I CHARSET  specify a character encoding for UNIX and other archives

See "unzip -hh" or unzip.txt for more help.  Examples:
  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip
  unzip -p foo | more  => send contents of foo.zip via pipe into program more
  unzip -fo foo ReadMe => quietly replace existing ReadMe if archive file newer
aerifying

显然不完整。主要我将切换 brute();对于字典();根据需要进行测试。一旦我让系统调用工作,我会把它扔到暴力部分。

如果您需要我详细说明我的问题,请告诉我。我在这里专注于学习,所以请在您回复我的任何内容中添加 idiot proof cmets。

【问题讨论】:

  • 这可能意味着您在脚本中使用unzip 的方式有问题。您是否尝试过手动输入解压缩命令?有用吗?
  • 我尝试用 unicorn 之类的随机单词(显然密码错误)替换标量,它运行正常并返回错误密码。我在终端和代码本身都这样做了。似乎在系统调用或解压缩调用中使用标量是特定的。
  • 这些是同一个作业问题吗? stackoverflow.com/questions/28894589/…
  • 我建议先生成命令,打印内容,然后执行。像这样的东西:my $unzip_command = "unzip -qq -o -P $pass secret_file_dict.zip &gt; /dev/null 2&gt;&amp;1"; print $unzip_command . "\n"; system( $unzip_command );
  • 我认为问题在于您使用的是-P(大写p)与-p(小写p)。 Unzip 只能识别小写版本,并且在大写选项上抛出错误。

标签: perl dictionary scripting


【解决方案1】:

第一:不要使用 PERL 的原型。他们不会做你或你的教授希望他们做的事。

第二:不要编写AddSlashes之类的自制转义例程。 Perl 有quotemeta。使用它。

您的问题不在于特定的编程语言。你的教授在你的问题上花了多少时间,你上了多少门课与问题无关。关注实际问题,而不是所有无关的“东西”。

比如,sub brute的意义何在?你没有在这个脚本中调用它,它与你的问题无关,所以不要发布它。将您的问题缩小到最小的相关部分。

不要在dict 的正文中提示输入单词表文件。将功能分成小块,以便在每种情况下您都可以专注于手头的问题。您的dict_attack 子例程应该期望接收文件句柄或对单词数组的引用。为了保持低内存占用,我们假设它是一个文件句柄(因此您不必将整个单词表保存在内存中)。

所以,您的 main 看起来像:

sub main {
    # obtain name of wordlist file
    # open wordlist file
    # if success, call dict_attack with filehandle
    # dict_attack returns password on success
}

现在,您可以关注dict_attack

#!/usr/bin/perl

use strict;
use warnings;

main();

sub dict_attack {
    my $dict_fh = shift;

    while (my $word = <$dict_fh>) {
        $word =~ s/\A\s+//;
        $word =~ s/\s+\z//;

        print "Trying $word\n";

        my $pass = quotemeta( $word );
        my $cmd = "unzip -qq -o -P $pass test.zip";
        my $status = system $cmd;
        if ($status == 0) {
            return $word;
        }
    }

    return;
}

sub main {
    my $words = join("\n", qw(one two three four five));
    open my $fh, '<', \$words or die $!;
    if (my $pass = dict_attack($fh)) {
        print "Password is '$pass'\n";
    }
    else {
        print "Not found\n";
    }
    return;
}

输出:

C:\...> perl y.pl
尝试一个
尝试两个
尝试三个
尝试四
尝试五
密码是“五”

【讨论】:

  • 当我进行更改以提示并接受外部 zip 文件时,我无法让您的代码部分正常工作,但是在我使用 quotemeta 并将标量与模式匹配的那一刻,我的工作完美无缺。非常感谢@SinanUnur
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多