Perl в помощь начинающему аналитику

Perl в помощь начинающему аналитику

Троянец обращается по адресу: http://*****.cn/list

В ответ получает список файлов, подлежащих загрузке. На момент создания описания список выглядел следующим образом...

Картина знакомая всем, кто занимается созданием описаний вредоносных программ. Ситуация банальна: у вас есть список из нескольких десятков вредоносов. Вы закачиваете их при помощи своей любимой программы-даунлоадера (я в таких случаях использую wget) и оказываетесь в ситуации, когда у вас есть скачанные файлы и вам нужно узнать как они детектируются.

Дальше начинается проверка вашей мышки на прочность — правый клик — "Проверить на вирусы" — открыть отчет — скопировать детект, если он есть — отправить сампл в архив под паролем и детектом в качестве названия...

В какой-то момент это начинает надоедать. Можно ли автоматизировать это процесс? Не только можно, но и нужно. Обратимся за помощью к любимому мной языку Perl:

Данный скрипт вызывается командной строкой (или заранее приготовленным bat-файлом):

C:Perlbinperl D:testdetect. pl D:testsample D:testdetected

В данной строке:

C:Perlbinperl — путь к интерпретатору языка Perl. Если вы корректно инсталлировали перл с прописыванием в переменную окружения PATH, то полный путь можно не указывать;

D:testdetect. pl — путь и имя нашего скрипта;

D:testsample — параметр, передаваемый скрипту, в котором содержится путь к каталогу, в котором содержатся файлы, которые нужно сканировать;

D:testdetected — параметр, передаваемый скрипту, в котором содержится путь, куда будут перемещены детектируемые файлы.

Если в указываемых путях есть пробелы, то эти части следует указывать в кавычках. Например:

C:Perlbinperl "D:Мои документыdetect. pl" "D:testsample to detect" D:testdetected

Что ж, перейдем непосредственно к скрипту. В самом начале мы получаем первый параметр:

@ARGV — служебный массив, в котором хранятся параметры, передаваемые скрипту.

$ARGV[0] — первый элемент этого массива. В данном случае тут будет содержаться путь к каталогу, в котором содержатся файлы, которые нужно сканировать, то есть D:testsample.

If ( $ARGV[0] eq "" ) { die "Must specify path to the directory with samplesn";

}

Тут происходит проверка, есть ли этот параметр. Если его нет, будет выведено сообщение о том, что обязательно нужно указать каталог с сэмплами.

$DirToNotDetected = $ARGV[0];

Помещаем в переменную $DirToNotDetected этот параметр.

После этого проверяем, есть ли второй аргумент: if ( $ARGV[1] eq "" ) {

$DirToDetected = $DirToNotDetected. 'detect';

} else {

$DirToDetected = $ARGV[1];

}

Второй параметр не является критичным — если его нет, то в качестве каталога для задетектированных файлов будет создан каталог с именем "detect" прямо в каталоге с сэмплами. Помещаем этот путь в переменную $DirToDetected.

Mkdir("$DirToDetected");

Создаем каталог для задетектированных файлов.

$PathTo7z = 'C:Program Files7-Zip';

Помещаем в переменную $PathTo7z путь к архиватору. Я использую 7zip.

$pass = 'password';

Помещаем в переменную $pass пароль, который будет использоваться для архивов.

$PathToKasper = 'C:Program FilesKaspersky LabKaspersky Internet Security 7.0';

Помещаем в переменную $PathToKasper путь к Антивирусу Касперского.

$KasperLogDir = "$DirToDetected";

Помещаем в переменную $KasperLogDir путь, по которому будет сохраняться лог работы антивирусного сканера. В данном случае лог будет сохраняться в каталог с задетектированными файлами.

$KasperCMDLine = ""$PathToKasper\avp. com" SCAN /fa /i0 /RA:"$KasperLogDir\kasperlog. txt" "$DirToNotDetected"";

Помещаем в переменную $KasperCMDLine командную строку, которой будет запускаться сканер. Рассмотрим ее подробнее:

"$PathToKasper\avp. com" - это будет интерпретировано системой как

"C:Program FilesKaspersky LabKaspersky Internet Security 7.0avp. com". Кавычки, указанные просто так, воспринимается системой как спецсимвол, поэтому перед ними указываем отмену буквального восприятия — обратную косую черту — .

SCAN /fa /i0 /RA:"$KasperLogDir\kasperlog. txt" - параметры сканера: "/fa" — сканировать все файлы без исключений; "/i0" — только отчет, никакого лечения; "/RA:" - сохранять все события, а не только критические; "$KasperLogDir\kasperlog. txt" - сохранять отчет-лог в файл "kasperlog. txt", расположив его в пути, указанном в переменной $KasperLogDir.

"$DirToNotDetected" - путь к детектируемым файлам.

System("$KasperCMDLine");

Запускаем командную строку на выполнение.

Unless ( open( INFILE, "$KasperLogDir\kasperlog. txt" ) ) { die("Cannot open input file $KasperLogDir\log. txtn");

}

По завершению сканирования открываем лог или выводим сообщение, что файл открыть невозможно, если не удается его открыть. Это может произойти, если отчет не создался, например, в случае если указанный для него каталог был доступен только для чтения.

@file_to_parse = <INFILE>;

Помещаем лог в массив @file_to_parse, каждым из элементов которого будут отдельные строки и...

Foreach $line (@file_to_parse)

{

...для каждого элемента этого массива выполняем следующее: chop($line);

Отрезаем последний символ в строке. Последним символом строки является символ переноса строки. В дальнейшем он может помешать, поэтому лучше сразу от него избавится.

If ( $line =~ /tdetectedt|tsuspiciont/ )

{

Знак "=~" выбирает совпадения. Выражение, которое нужно искать указывается между косыми чертами: /то, что ищем/. Символ "|" обозначает "или".

Если строка содержит слова "detected" или "suspicion", ограниченных символами табуляции (t), то выполнять следующее...

Тут сделаем небольшое отступление, чтобы посмотреть, как выглядит лог антивирусного сканера. Приведу часть:

Красным подчеркнуты строки, которые пройдут проверку $line =~ /tdetectedt|tsuspiciont/. Обратите внимание, на строку, подчеркнутую зеленым. Эта строка тоже содержит слово "detected", но оно не ограниченно табами. Кроме этого, слова "detected" и "suspicion" могут содержатся в пути к файлам или в названии самих файлов. Чтобы избежать ложного срабатывания условия мы и добавляем символы "t" в начале и в конце искомых ключевых слов.

Возвращаемся к скрипту. Итак, если мы обнаружили искомую строку, то:

@arr = split( /t/, $line );

Разделить строку на части по символам табуляции и поместить эти части в массив @arr (от array – массив). Рассмотрим, что же произойдет на примере одной из строк. При этом я использую редактор, который может показывать спецсимволы, чтобы было понятнее, что такое табуляция и символ переноса строки:

Первым делом, как уже сказано, будет удален символ переноса строки (подчеркнуто красным). Кроме того, обратите внимание — на предыдущем скриншоте расстояние между датой и временем (подчеркнуто синим) такое же, как и между пакером и словом "detected" (подчеркнуто зеленым), но в первом случае это просто пробел, а во втором символ табуляции. Разделив строку получим четыре элемента:

2009-08-16 12:32:35

D:testsample1.exe//PE_Patch. UPX//UPX detected

Trojan-GameThief. Win32.OnLineGames. bmtc

Эти части и будут помещены в массив @arr.

$detect = $arr[3];

В переменную $detect помещаем элемент массива номер три. Тут есть еще одна немаловажная особенность, очевидная для программистов, но часто вызывающая ошибки и непонимание у новичков — нумерация ведется с нуля. Таким образом:

2009-08-16 12:32:35 — нулевой элемент массива,

D:testsample1.exe//PE_Patch. UPX//UPX — первый, detected — второй,

Trojan-GameThief. Win32.OnLineGames. bmtc — четвертый.

То есть в переменную $detect будет записано "Trojan-GameThief. Win32.OnLineGames. bmtc".

$detect =~ s/:/_/;

Производим замену двоеточий на подчеркивания в переменной $detect. Таким образом, какой-нибудь not-a-virus:AdWare. Win32.Agent. pgv будет записан как not-a-virus_AdWare. Win32.Agent. pgv. Зачем это нужно станет понятно позднее.

If ( $arr[1] =~ /// ) {

@arr = split( ///, $arr[1] );

Если первый элемент массива (то есть в данном случае D:testsample1.exe//PE_Patch. UPX//UPX) содержит косую черту (косая черта "/" указанная просто так воспринимается системой как спецсимвол, поэтому перед ней указываем отмену буквального восприятия — обратную косую черту ""), то этот элемент нужно разделить по символу косой черты. В данном выражении мы отделяем путь и имя задетектированного файла от пакера. Так как массив @arr нам больше не понадобится (мы уже сохранили детект в переменную $detect), то можно снова использовать это же название. Итак: в нулевой элемент массива @arr ($arr[0]) будет записано "D:testsample1.exe", в первый ($arr[1]) — ничего, во второй ($arr[2]) — PE_Patch. UPX, в третий ($arr[3]) — ничего, в четвертый ($arr[4]) — UPX.

$arr[1] = $arr[0];

}

Записываем в первый элемент (где до этого ничего небыло) нулевой.

$path_name = $arr[1];

Записываем в переменную $path_name первый элемент массива, то есть имя и путь к файлу (D:testsample1.exe). Обратите внимание, что если условие не срабатывает (файл не упакован), то в $arr[1] будет уже готовые имя и путь, полученные при первом разделении строки по табуляциям.

Итак мы получили детект и путь к файлу, соответствующему этому детекту. Все, что нам остается, это переместить этот файл в архив под паролем: system(""$PathTo7z\7za" a - tzip "$DirToDetected\$detect. zip" "$path_name" - y - p$pass"n");

Тут запускается программа-архиватор 7zip. При этом все переменные будут заменены на их значения, и в итоге команда будет выглядеть так:

"C:Program Files7-Zip7za" a - tzip "$DirToDetectedTrojan-GameThief. Win32.OnLineGames. bmtc. zip" "D:testsample1.exe" - y - ppassword"

Тут:

C:Program Files7-Zip7za — путь к программе 7zip a – параметр, указывающий, что архиватор должен помещать в архив

-tzip — метод сжатия zip

$DirToDetectedTrojan-GameThief. Win32.OnLineGames. bmtc. zip — путь и имя архива, в которых следует поместить файл

D:testsample1.exe — файл, который нужно архивировать

-y — на все вопросы отвечать утвердительно (это нужно, чтобы при совпадении имен файл добавлялся к архиву не ожидая подтверждения)

-p — параметр, указывающий, что архив должен быть с паролем и сразу же указываестя пароль "password"

Тут в качестве имени архива мы используем детект. Так как имя файла не может содержать двоеточий, то именно для этого мы чуть ранее заменяли двоеточия на подчеркивание.

После этого обработанный файл можно удалять: system("del "$path_name"");

Выполнить команду del "D:testsample1.exe". В принципе, эта строка не обязательна, а иногда может даже мешать - например, когда несколько вредоносных файлов оказываются в одном самораспаковывающемся архиве, то такой файл будет иметь несколько детектов и если мы удалим его сразу же после первого перемещения, то архивы с остальными детектами окажутся пустыми.

После этого мы вернемся к началу цикла и повторим все описанное для следующей строки и так пока не закончится файл отчета.

Close(INFILE);

Закрыть файл отчета по завершению обработки.

Print("Done! n");

Вывести сообщение о завершении работы.

После того, как скрипт отработал мы получим каталог D:testdetected в котором будут аккуратненько разложены все наши файлы:

Архивов меньше, чем файлов, в исходном каталоге потому, что несколько файлов могут детектироваться одинаково:

Код:

Листинг : detect. pl if ( $ARGV[0] eq "" )

{ die "Must specify path to the directory with samples\n";

}

$DirToNotDetected = $ARGV[0]; if ( $ARGV[1] eq "" )

{

$DirToDetected = $DirToNotDetected. '\detect';

} else

{

$DirToDetected = $ARGV[1];

} mkdir("$DirToDetected");

$PathTo7z = 'C:\Program Files\7-Zip';

$pass = 'password';

$PathToKasper =

'C:\Program Files\Kaspersky Lab\Kaspersky Internet Security 7.0';

$KasperLogDir = "$DirToDetected";

$KasperCMDLine =

"\"$PathToKasper\\avp. com\" SCAN /fa /i0 /RA:\"$KasperLogDir\\kasperlog. txt\" \"$DirToNotDetected\""; system("$KasperCMDLine"); unless ( open( INFILE, "$KasperLogDir\\kasperlog. txt" ) )

{ die("Cannot open input file $KasperLogDir\\log. txt\n");

}

@file_to_parse = <INFILE>; foreach $line (@file_to_parse)

{ chop($line); if ( $line =~ /\tdetected\t|\tsuspicion\t/ )

{

@arr = split( /\t/, $line );

$detect = $arr[3];

$detect =~ s/:/_/; if ( $arr[1] =~ /\// )

{

@arr = split( /\//, $arr[1] );

$arr[1] = $arr[0];

}

$path_name = $arr[1]; system("\"$PathTo7z\\7za\" a - tzip \"$DirToDetected\\$detect\.zip\" \"$path_name\" - y - p$pass\"\n"

); system("del \"$path_name\"");

}

} close(INFILE); print("Done!\n");


Карта сайта


Информационный сайт Webavtocat.ru