Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Perl脚本输入/应答终端提示?_Perl_Terminal_Prompt_Interactive_Non Interactive - Fatal编程技术网

如何从Perl脚本输入/应答终端提示?

如何从Perl脚本输入/应答终端提示?,perl,terminal,prompt,interactive,non-interactive,Perl,Terminal,Prompt,Interactive,Non Interactive,我试图破解一个被遗忘的luks分区密码。我生成了一个组合列表,现在我正试图从Perl脚本中解密该卷 问题是要从脚本本身输入提示,因为:system('cryptsetup'、('open'、'dev/sdd1'、'crypt vol'、'--type=luks')只是吐出输入/dev/sdd1的密码,然后等待我手动输入它 我怎样才能做到这一点 非常感谢你的帮助 *这是我的卷,我没有完全忘记密码,所以我创建了组合列表,只要我记得一些细节。这就像是超过6k的可能性,所以打破它应该是可行的。不要,使用

我试图破解一个被遗忘的luks分区密码。我生成了一个组合列表,现在我正试图从Perl脚本中解密该卷

问题是要从脚本本身输入提示,因为:
system('cryptsetup'、('open'、'dev/sdd1'、'crypt vol'、'--type=luks')
只是吐出
输入/dev/sdd1的密码,然后等待我手动输入它

我怎样才能做到这一点

非常感谢你的帮助


*这是我的卷,我没有完全忘记密码,所以我创建了组合列表,只要我记得一些细节。这就像是超过6k的可能性,所以打破它应该是可行的。

不要,使用带有密码设置的“密钥文件”。密钥文件可以是STDIN

因此:


<强>我实际上喜欢使用STDIN,所以如果有人点击这个页面,考虑是否可以在您的情况下使用STDIN。<强> < /P> 但是我想发布我自己的答案,它使用Expect Perl模块,因为:

  • 我使用了它,并且它至少在Linux上被证明是有效的(尽管评论中的问题提到该模块在Windows上运行时有问题)
  • 由于问题的标题没有提到
    cryptsetup
    (它可以接受STDIN上的密码),因此Expect模块在这里就像一个通用解决方案,应该适用于其他工具
我的解决方案如下。我没有太多地阅读文档,因此可能有更好的方法来做到这一点。对我来说,掌握对象实例化的概念和expect/send方法就足够了

您可以创建一个实例,就像您刚刚在终端中启动了一个程序一样:

my $exp = Expect->new('progName', ($arg1, $arg2, $etc));
然后可以通过
expect
(等待/确认程序向用户的输出)和
send
(允许用户“键入”)方法与之交互

expect
可以在标量上下文或列表上下文中调用(我使用的是列表上下文),它接受一个字符串或regexp,该字符串或regexp表示期望的输出以及输出时间。如果在指定时间内未出现预期输出,则会抛出错误:

                       #sec to wait for  #use regexp (don't match exactly) #regexp to match against
my @out = $exp->expect(10,               '-re',                            'smth');
send
只接受输入

$exp->send('some chars');
就是这样,只需创建一个脚本,就可以像人类用户一样工作。


为了防止有人使用它,我将发布我针对cryptsetup的完整特定解决方案(我已经在一个虚拟卷上测试了它,它能够装载,并且我已经在一个真正的卷上运行了它,尝试了6k组合,没有任何明显的问题):

*我忘了在这里关闭文件描述符,因此应该在适当的地方添加
close($fd)

use strict;
use warnings;
use feature 'say';


# I installed Expect with its deps locally in my situation, so I had to change @INC
BEGIN {
  unshift(@INC, './perl-mods/lib/perl5/');
  unshift(@INC, './perl-mods/lib/perl5/x86_64-linux-thread-multi/');
}

use Expect;

my $devName = '/dev/sdb3';
my $combinationsFileName = 'combs.txt';
open(my $fd, '<', $combinationsFileName);
my $lineCount = 0;

while (<$fd>) {
  my $pass = $_;
  chomp($_);
  say $_ . ' ' . ++$lineCount;

  my $exp = Expect->new('cryptsetup', ('open', $devName, 'crypt-vol')) or die 'err 1';
  my @out = $exp->expect(10, '-re', 'Enter passphrase') or die 'err 2';
  $exp->send($pass);
  @out = $exp->expect(10, '-re', 'No key available') or die 'err 3';

  #if cryptsetup returned an error code
  if ($out[1]) {
    die $out[1] . ' ' . $pass;
  }
}
使用严格;
使用警告;
使用特征“说”;
#在我的情况下,我在本地安装了Expect及其DEP,因此我不得不更改@INC
开始{
取消移位(@INC'./perl mods/lib/perl5/);
取消移位(@INC'./perl mods/lib/perl5/x86_64-linux-thread-multi/);
}
使用Expect;
my$devName='/dev/sdb3';
my$combinationsFileName='combs.txt';

open(my$fd,'这是同一个问题吗?忘记perl。使用
expect
,它是用来处理从
/dev/tty
读取的交互式程序。也许可以使用perl模块?@Jens我已经用perl expect模块创建了一些东西。似乎正在运行,现在我最多要等20个小时(我估计),然后根据结果,我将发布一些内容,或者是答案(如果有效)或者是更新问题。@TLP是的,我现在正在做。唯一可能的问题可能是我在每个while循环中创建了一个新的expect实例,因为
crypsetup
在第二个或第三个atemt以代码512退出以输入密码
$exp->send('some chars');
use strict;
use warnings;
use feature 'say';


# I installed Expect with its deps locally in my situation, so I had to change @INC
BEGIN {
  unshift(@INC, './perl-mods/lib/perl5/');
  unshift(@INC, './perl-mods/lib/perl5/x86_64-linux-thread-multi/');
}

use Expect;

my $devName = '/dev/sdb3';
my $combinationsFileName = 'combs.txt';
open(my $fd, '<', $combinationsFileName);
my $lineCount = 0;

while (<$fd>) {
  my $pass = $_;
  chomp($_);
  say $_ . ' ' . ++$lineCount;

  my $exp = Expect->new('cryptsetup', ('open', $devName, 'crypt-vol')) or die 'err 1';
  my @out = $exp->expect(10, '-re', 'Enter passphrase') or die 'err 2';
  $exp->send($pass);
  @out = $exp->expect(10, '-re', 'No key available') or die 'err 3';

  #if cryptsetup returned an error code
  if ($out[1]) {
    die $out[1] . ' ' . $pass;
  }
}