#!/usr/bin/perl ##### Предполагается: # 1.  Убедимся, что мы создаем совершенно новую директорию #      для монтирования  с тем, чтобы избежать проблем с безопасностью, #      если кто-либо еще из пользователей вошел в систему # 2.  Использовать функции Perl для выполнения множества системных вызовов # 3.  Автоматически определяем жесткие и гибкие диски и выполняем действия #     только над  не-примонтированными устройствами ##### use strict; use Expect; use Crypt::Blowfish; #----------------------------------------------- my $Junk;   ### Настроимся на ведомый диск первичного контроллера IDE. my $Drive = "hdb";   ### Выполним множество случайных действий,   ### а в завершение возьмем последнюю строку /etc/passwd   ### в предположении, что на компьютере был добавлен один пользователь my $time = time(); my $Ran = rand($time); my $Ran = rand(10000000000000); my $LastLine = `tail -n 1 /etc/passwd`; chomp $LastLine; $LastLine = substr ($LastLine,0,30); my $Blowfish_Key = $LastLine . $Ran . $time; $Blowfish_Key = substr ($Blowfish_Key,0,20); while (length ($Blowfish_Key) < 56)   {   $Blowfish_Key .= $Ran = rand($time);   } $Blowfish_Key = substr ($Blowfish_Key,0,56);   ### Случайный ключ готов, создаем объект Blowfish Encryption. my $Blowfish_Cipher = new Crypt::Blowfish $Blowfish_Key; #------------------------------------ system "clear"; print "This will wipe out the hard drive on Drive /dev/$Drive\n"; print "Press enter to continue\n"; my $R = ;   ### Получить список смонтированных разделов my @Mounted = `df`; @Mounted = grep($_ =~ /\/dev\/hdb/, @Mounted);   ### Размонтируем смонтированные разделы foreach my $Mount (@Mounted)   {   my ($Partition,$Junk) = split(/\s+/, $Mount,2);   print "Unmounting $Partition\n";   my $Result = system ("umount $Partition");   if ($Result > 0)     {     print "ERROR, unable to umount $Partition, aborting Script, Error = $Result\n";     exit;     }   }   ### Запуск скрипта Expect, который эмулирует выполнение команд вручную my $Fdisk = Expect->spawn("/sbin/fdisk /dev/$Drive");   ### Из вывода fdisk'ом таблицы разделов получаем их список print $Fdisk "p\n"; my $match=$Fdisk->expect(30,"Device Boot    Start"); my $Temp = $Fdisk->exp_after(); my @Temp = split(/\n/, $Temp);   ## Выделяем строки с информацией о разделах my @Partitions = grep($_ =~ /^\/dev\//, @Temp);   ## Для каждой такой строки -- удаляем раздел foreach my $Line (reverse @Partitions)   {     ## Получаем раздел /dev/hdb и его номер   my ($Part,$Junk) = split(/[\t ]/, $Line,2);   my $No = $Part;   $No =~ s/^\/dev\/$Drive//;   print "Deleting no $Drive $No\n";     ## Команда на удаление   print $Fdisk "d\n";   $match=$Fdisk->expect(30,"Partition number");     ## Указываем номер удаляемого раздела   print $Fdisk "$No\n";   $match=$Fdisk->expect(30,"Command (m for help):");   } $Fdisk->clear_accum();   ### Если разделы еще остались -- записываем изменения, если нет -- выходим if (@Partitions < 1) {print $Fdisk "q\n"; $Fdisk->expect(2,":");} else   {   print $Fdisk "w\n";   $Fdisk->expect(30,"Command (m for help):");   } #-------------------------------   ## Получаем геометрию жесткого диска my $Geometry = `/sbin/sfdisk -g /dev/$Drive`; my ($Junk, $Cyl, $Junk2, $Head, $Junk3, $Sector,@Junk) = split(/\s+/,$Geometry); if ($Cyl < 1)    {print "ERROR: Unable to figure out cylinders for drive. aborting\n"; exit;}   ### Новый скрипт Expect для эмуляции действий пользователя my $Fdisk = Expect->spawn("/sbin/fdisk /dev/$Drive");    #### Велим fdisk создать новый раздел print $Fdisk "n\n"; $Fdisk->expect(5,"primary");   ### Новый раздел будет первичным print $Fdisk "p\n"; $Fdisk->expect(5,":");   ### Какой раздел? Номер 1 print $Fdisk "1\n"; $Fdisk->expect(5,":");   ### От забора (цилиндра 1)... print $Fdisk "1\n"; $Fdisk->expect(5,":");   ### ...и до обеда (конца диска) print $Fdisk "$Cyl\n"; $Fdisk->expect(5,":");   ### Запишем и сохранимся print $Fdisk "w\n"; $Fdisk->expect(30,"Command (m for help):"); #------------------------------------------ ### Отформатируем раздел и смонтируем его my $Partition = "/dev/$Drive" . "1"; my $Result = system ("mkfs -t ext2 $Partition"); if ($Result > 0) {print "Error making partition, aborting.\n"; exit;}    ### Тут надо бы добавить всяких проверок... system "umount /tmp/WIPE_IT"; system "rm -rf /tmp/WIPE_IT"; system "mkdir -p /tmp/WIPE_IT"; system "chmod 700 /tmp/WIPE_IT";   ## Посмотрим, получилось ли смонтировать. my $Result = system ("mount $Partition /tmp/WIPE_IT"); if ($Result > 0) {print "Error mounting drive, aborting.\n"; exit;} system "chmod 700 /tmp/WIPE_IT"; #-------------------------------- ### Создаем файло и пишем до упора. my $Count = 0; my $Written_Size = 0;   ### Открываем новый файл. open(FILE,">>/tmp/WIPE_IT/Message.txt");    ### И если кому-то придет в голову проиграться с нашим винтом,    ### то пусть разомнутся с этой завлекушечкой, мы тоже любим играться. my $Ran = rand 259200000;   # эдак между сейчас и 10 лет тому назад... ($Ran, $Junk) = split(/\./, $Ran, 2);    ## Новая дата минус случайное число секунд... my $Date = `date --date '-$Ran seconds'`; print FILE "DATE CREATED $Date\n"; my $Ran = rand 50; ($Ran, $Junk) = split(/\./, $Ran, 2); $Ran = $Ran + 10; print FILE "This document is extremely secure. It is a violation to let any unauthorized persons read it. Known password holders need to apply Method $Ran in order to decrypt binary data.\n";   ### Случайное число плюс 25000 my $Ran = rand 25000; ($Ran, $Junk) = split(/\./, $Ran, 2); $Ran = $Ran + 25000;   ### Создаем массив случайных чисел для частого употребления. my @Blank =  (1..$Ran);   ### Превращаем его в строку. my $Blank = "@Blank";   ### Освободим массив для экономии памяти. @Blank = (); my $B_Length = length $Blank;   ### Получаем доступное место на разделе my @Temp = `df`; @Temp = grep($_ =~ /^$Partition/, @Temp); my $Line = $Temp[0]; my ($Junk,$Blocks,@Junk) = split(/\s+/, $Line,4);   ### Предполагаем, что блок равен 1k. my $Size = $Blocks*1000;   ## Если записанный файл меньше размера раздела   ## запишем еще немного. while ($Written_Size < $Size)   {   $Count++;         ### 9 раз из десяти печатаем пустые данные для ускорения процесса         ### а один раз печатаем цифровой мусор.      my $Ran = rand (10);      if ($Ran > 1)        {        print FILE $Blank;        $Written_Size = $Written_Size + $B_Length;        }      else        {          ## А здесь сделаем длинную (до 10000 байт) строку случайных символов.        my $Garbage = "";        my $Length = rand(10000);        ($Length, $Junk) = split(/\./, $Length, 2);        for (my $i = 0; $i < $Length; $i++)          {          my $Ran = rand 256;          ($Ran, $Junk) = split(/\./, $Ran, 2);          $Garbage .= chr $Ran;          }          ## Здесь зашифруем случайную строку по 8 байт за раз.        my $Temp = $Garbage;        my $Encrypted = "";        while (length $Temp > 0)          {          while (length $Temp < 8) {$Temp .= "\t";}          my $Temp2 = $Blowfish_Cipher->encrypt(substr($Temp,0,8));          $Encrypted .= $Temp2;          if (length $Temp > 8) {$Temp = substr($Temp,8);} else {$Temp = "";}          }          ### Запишем зашифрованные случайные данные в файл.        print FILE $Encrypted;        $Length = length $Encrypted;        $Written_Size = $Written_Size + $Length;        my $Rest = $Size - $Written_Size;        print "$Size - $Written_Size = $Rest to go\n";        }    ### Каждые 500 вызовов print начинаем новый файл.   if ($Count =~ /500$/)     {     close FILE;     open(FILE,">>/tmp/WIPE_IT/$Count");     }   } close FILE; #---------------------------------------------------- my $Result = system ("umount $Partition"); if ($Result > 0) {print "Error unmounting partition $Partition, aborting.\n"; exit; }   ### Отформатируем раздел. Это не сотрет данные,   ### а просто удалит их из каталога. my $Result = system ("mkfs -t ext2 $Partition"); if ($Result > 0) {print "Error making partition, aborting.\n"; exit;}