Загружаем Kaspersky Rescue Disk 10 по сети

в 6:16, , рубрики: pxe, информационная безопасность, системное администрирование, метки:

Предлагаемая к ознакомлению статья расскажет как из популярного инструмента лечения от компьютерных вирусов сделать загружаемый по сети (pxe-bootable) вариант. Материал будет полезен системным администраторам, работникам сервис-центров и, возможно, кому-то еще, кому приходится часто реанимировать зараженные вирусами компьютеры в промышленных масштабах.

В свое время подобное решение было предложено тут, но совсем недавно (февраль-март этого года), с выходом обновленной версии Kaspersky Rescue Disk 10 (далее просто KRD10), эта методика перестала работать. В новую версию были добавлены редактор реестра и утилита windowsunlocker, а также кардинально изменились кое-какие скрипты, что сделало невозможным применение старых патчей.

Изложенный ниже материал актуален для текущей на данный момент версии 10.0.31.4.

Постановка задачи

Задача сводится к нескольким пунктам:

  1. Адаптировать Kaspersky Rescue Disk 10 к загрузке по сети.
  2. Предусмотреть локальное зеркало обновлений, из которого можно было бы периодически обновлять антивирусные базы, не скачивая каждый раз свежий iso-образ.
  3. Изменить кое-какие настройки антивируса по-умолчанию. Например, проверка архивов подчас занимает много времени, а каждый раз снимать перед сканом одну и ту же галку в настройках утомительно.
  4. Максимально автоматизировать выполнение перечисленных выше пунктов, сведя количество необходимых к нажатию кнопок до минимума.

Системные требования

Требования к серверной части:

  • Операционная система Ubuntu 10.04 или новее. Я тестировал скрипты с Ubuntu 10.04 Server x32 и Ubuntu 11.10 Desktop x32. Если у вас иной дистрибутив Linux, то, возможно, потребуется что-то изменить.
  • Работают сервисы dhcp и tftp.
  • Настроен pxelinux (имеется загрузчик pxelinux.0, конфигурационный файл pxelinux.cfg/defult и т.п).

Дополнительно о том как развернуть сетевую загрузку за пятнадцать минут можно почитать тут.

Требования к клиентской части:

  • Сетевой адаптер с поддержкой PXE BOOT ROM.
  • Не менее 512MB RAM.

Скрипт prepare.sh

Скрипт prepare.sh запускается один раз с целью подготовить все необходимое, а именно:

  • Установить недостающие пакеты (или убедиться в их наличии).
  • Скачать iso-образ KRD10.
  • Скачать утилиту обновления антивирусных баз.
  • Скачать и собрать из исходников squashfs-tools.

Последнее необходимо по той причине, что в Ubuntu из репозиториев по-умолчанию устанавливаются squashfs-tools без поддержки xz-сжатия. Если у вас уже установлены squashfs-tools какой-либо версии, удалять их из системы нет необходимости, никакого конфликта не будет.

Листинг prepare.sh:

#!/bin/sh

# Объявляем переменные
krd10_src="http://rescuedisk.kaspersky-labs.com/rescuedisk/updatable/kav_rescue_10.iso"
retranslator_src="http://utils.kaspersky.com/updater/retranslator_5.0.0.9/Linux/retranslator-5.0.0-9.tar.gz"
squashfs_src="http://jaist.dl.sourceforge.net/project/squashfs/squashfs/squashfs4.2/squashfs4.2.tar.gz"

# Установка недостающих пакетов
echo && echo "STEP 1 : Do you have zlib, lzma, g++ and patch?"
apt-get -q -y install zlib1g-dev liblzma-dev lzma g++ patch

# Скачиваем необходимые файлы
echo && echo "STEP 2 : I need to download some files..."

# KRD10
wget -nc -c $krd10_src
if [ "$?" -ne "0" ]; then
  echo
  echo "Can't download Kaspersky Rescue Disk 10 iso image!"
  echo
  exit 1
fi

# Утилита обновления антивирусных баз
wget -nc -c $retranslator_src
if [ "$?" -ne "0" ]; then
  echo
  echo "Can't download RETRANSLATOR!"
  echo
  exit 1
fi

# Исходники squashfs-tools
wget -nc -c $squashfs_src
if [ "$?" -ne "0" ]; then
  echo
  echo "Can't download SQUASHFS package!"
  echo
  exit 1
fi

# Распаковка
echo && echo "STEP 3 : Let's see what's inside..."
tar -xzf retranslator-5.0.0-9.tar.gz
tar -xzf squashfs4.2.tar.gz

# Патчим файлы конфигурации
echo && echo "STEP 4 : Patching config files..."
# Настройка утилиты обновления антивирусных баз
patch -p0 -i retranslator.patch
# Настройка Makefile (активация опции поддержки XZ-сжатия)
patch -p0 -i squashfs.patch

# Собираем squashfs4.2
echo && echo "STEP 5 : Building squashfs4.2 with XZ support..."
make -C ./squashfs4.2/squashfs-tools/

Патч retranslator.patch

--- ./retranslator/retranslator.bak	2010-07-14 02:51:11.000000000 +1100
+++ ./retranslator/retranslator.conf	2012-01-08 18:30:56.438109054 +1100
@@ -35,23 +35,23 @@
 #
 # Optional specification of components to be retranslated.
 #
-RetranslateComponentsList=AVS, CORE, BLST, Updater
+RetranslateComponentsList=EMU,KDB,QSCAN,RD
 
 #
 # Optional specification of OS filter.
 #
-#os2=Win;Mac;Linux
+os2=Linux
 
 #
 # Optional specification of instruction set filter.
 #
-#instrset=kernel:i386,x64;user:i386;
+instrset=kernel:i386;user:i386;
 
 
 #
 # Optional specification of application filter.
 #
-#application=WKS 6.0.4.1424;
+application=RD 10.*.*.*;
 
 #
 # Optional specification of build filter.
@@ -182,5 +182,5 @@
 #    this level if you are reporting bugs in the product. Do not forget to turn
 #    it off afterwords. Debug messages have 'D' mark in the log file.
 #
-ReportLevel=9
+ReportLevel=3
 

Патч squashfs.patch

--- ./squashfs4.2/squashfs-tools/Makefile.bak	2011-03-01 06:04:15.000000000 +1000
+++ ./squashfs4.2/squashfs-tools/Makefile	2012-03-13 12:20:20.823261029 +1100
@@ -26,7 +26,7 @@
 # To build using XZ Utils liblzma - install the library and uncomment
 # the XZ_SUPPORT line below.
 #
-#XZ_SUPPORT = 1
+XZ_SUPPORT = 1
 
 
 ############ Building LZO support ##############

Если все прошло без ошибок, то в папке ./squashfs4.2/squashfs-tools/ появятся два исполняемых файла — mksquashfs и unsquashfs, а в папке ./retranslator появится готовое к работе локальное зеркало антивирусных баз.

Скрипт make_rescue.igz.sh

Это основной скрипт, результатом работы которого являются три файла: ядро «rescue», рамдиск «rescue.igz» и файл конфигурации «menu.cfg» для pxelinux.

Листинг make_rescue.igz.sh:

#!/bin/sh

# Переход в каталог, из которого запущен этот скрипт, актуально для запуска из crontab.
cd $(cd $(dirname $0) && pwd)

# Объявляем переменные:

# Установите download_iso="1" если хотите, чтобы каждый раз скачивался свежий образ KRD10.
# Менять не рекомендуется, оставлено для отладки
download_iso="0"
krd10_iso="http://rescuedisk.kaspersky-labs.com/rescuedisk/updatable/kav_rescue_10.iso"

# Корневая папка tftp (в ней должен также быть загрузчик pxelinux.0 и т.п.),
# измените путь на свой.
tftproot_dir="/storage/tftproot"

# Папка назначения относительно tftproot_dir, измените путь на свой.
dest_dir="apps/kaspersky"

# Установите update_liveos="0" если не хотите менять его настройки или добавлять какие-то свои файлы
update_liveos="1"

# Установите compress_lzma="0" если не хотите сжимать конечный образ
compress_lzma="1"

# Скачиваем образ KRD10 если соответствующий флаг установлен.
echo && echo "STEP 1 : Downloading iso image..."
if [ "${download_iso}" = "1" ]; then
  if [ -e "kav_rescue_10.iso" ]; then
    mv -f kav_rescue_10.iso kav_rescue_10.iso.bak
  fi
  wget -nv ${krd10_iso}
  else
  echo "This step was skipped."
fi 

# Обновляем антивирусные базы
echo && echo "STEP 2 : Downloading anti-virus bases..."
# Запоминаем версию старых баз (sed нужен для избавления от символа "возврата каретки" в конце строки).
if [ -e "retranslator/bases/bases/av/kdb/i386/kdb.stt" ]; then
  old_base=`cat retranslator/bases/bases/av/kdb/i386/kdb.stt | sed 's/x0D$//'`
else
  old_base="did not update yet"
fi

./retranslator/retranslator

# Запоминаем версию новых баз.
new_base=`cat retranslator/bases/bases/av/kdb/i386/kdb.stt | sed 's/x0D$//'`
echo "Old base version : ${old_base}"
echo "New base version : ${new_base}"
# Короткая версия баз (только дата выпуска, без кол-ва известных вирусов) пригодится позднее.
base_ver=`echo ${new_base} | sed 's/.*;//'`

# Монтируем iso образ.
echo && echo "STEP 3 : Mounting iso image..."
mkdir iso && mount -o loop kav_rescue_10.iso iso/
# Запоминаем версию образа
disk_ver=`cat iso/rescue/KRD.VERSION | sed 's/; $//'`
echo "Disk version : ${disk_ver}"

# Распаковка rescue.igz.
echo && echo "STEP 4 : Decompressing rescue.igz..."
mkdir tmp
cp iso/boot/rescue.igz ./tmp/rescue.lzma
mkdir initrd
cd initrd && lzcat -S lz ../tmp/rescue.lzma | cpio -i --no-absolute-filenames && cd ../

# Самые главные патчи!
echo && echo "STEP 5 : Patching some files..."
# Блокируем поиск загрузочного диска, указываем скрипту монтировать содержимое LiveCD
# из готового образа, который соберем на шаге 7.
patch -p0 -i init.patch
patch -p0 -i dmsquash-live-root.patch

# Изменение настроек, добавление пользовательских файлов можно делать на этом этапе.
echo && echo "STEP 6 : Patching LiveOS..."
if [ "${update_liveos}" = "1" ]; then
  # Образ упакован с xz-компрессией! Распаковываем по-умолчанию в squashfs-root.
  ./squashfs4.2/squashfs-tools/unsquashfs iso/rescue/LiveOS/squashfs.img

  # Внутри еще один образ, монтируем его.
  mkdir mnt && mount -o loop -t auto squashfs-root/LiveOS/ext3fs.img mnt

  # Патч меняет кое-какие настройки (см. содержимое патча config.xml.patch ниже).
  patch -p0 -i config.xml.patch
  
  # Свои файлы можно кидать в ./mnt прямо СЕЙЧАС

  # Упаковываем измененный образ и заметаем следы.
  umount mnt && rm -rf mnt
  ./squashfs4.2/squashfs-tools/mksquashfs squashfs-root squashfs.img -comp xz
  rm -rf squashfs-root
else
  echo "This step was skipped."
fi

# Собираем образ загрузочного диска "с нуля".
echo && echo "STEP 7 : Building livecd.squash..."

mkdir -p livecd/rescue/help
cp iso/rescue/help/*.txt livecd/rescue/help/
cp -r iso/rescue/help/English livecd/rescue/help
cp -r iso/rescue/help/Russian livecd/rescue/help

cp iso/rescue/KRD.VERSION livecd/rescue/
cp iso/livecd livecd/

# Если было выбрано изменение настроек, пользуемся образом, собранным на предыдущем шаге...
if [ "${update_liveos}" = "1" ]; then
  mkdir livecd/rescue/LiveOS && mv squashfs.img livecd/rescue/LiveOS/
# ...В противном случае используем "родной".
else
  cp -r iso/rescue/LiveOS livecd/rescue
fi

# Собираем папку с обновленными базами!
mkdir -p livecd/rescue/bases/Stat
cp retranslator/bases/bases/av/kdb/i386/* livecd/rescue/bases/
cp retranslator/bases/bases/av/emu/i386/* livecd/rescue/bases/
cp retranslator/bases/bases/av/qscan/i386/u/* livecd/rescue/bases/
mv livecd/rescue/bases/kdb-i386-0607g.xml livecd/rescue/bases/kdb-0607g.xml
cp retranslator/bases/bases/av/kdb/i386/kdb.stt livecd/rescue/bases/Stat/
cp retranslator/bases/index/u0607g.xml livecd/rescue/bases/Stat/

# WindowsUnlocker тоже обновляем из зеркала.
mkdir livecd/rescue/bases/data
cp retranslator/bases/AutoPatches/rd/rd-0607g.xml livecd/rescue/bases/
cp retranslator/bases/AutoPatches/rd/windowsunlocker livecd/rescue/bases/data/

# Упаковываем.
./squashfs4.2/squashfs-tools/mksquashfs livecd initrd/livecd.squash

# Собираем обновленный rescue.igz.
echo && echo "STEP 8 : Building rescue.igz..."
if [ "${compress_lzma}" = "1" ]; then
  # с lzma сжатием
  echo "Lzma compress enabled."
  cd ./initrd && find . | cpio -o -Hnewc | lzma -c > ../rescue.igz && cd ../
  else
  # без lzma сжатия
  echo "Lzma compress disabled."
  cd ./initrd && find . | cpio -o -Hnewc > ../rescue.igz && cd ../
fi

# Перемещаем полученный образ, чистим временные папки.
echo && echo "STEP 9 : Moving image and cleaning temp dirs..."
if [ ! -d ${tftproot_dir}/${dest_dir} ]; then
  mkdir -p ${tftproot_dir}/${dest_dir}
fi

cp -f iso/boot/rescue ${tftproot_dir}/${dest_dir}/
mv -f rescue.igz ${tftproot_dir}/${dest_dir}/

rm -rf tmp
rm -rf livecd
rm -rf initrd
umount iso && rm -rf iso

# Создаем конфиг для pxelinux. Конфиг будет не простой, а красивый...
echo && echo "STEP 10 : Pxelinux config..."

echo "LABEL kaspersky_rescue_disk_10" > ${tftproot_dir}/${dest_dir}/menu.cfg
echo "MENU LABEL Kaspersky Rescue Disk ${disk_ver}-${base_ver}" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "KERNEL ${dest_dir}/rescue" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "APPEND initrd=${dest_dir}/rescue.igz root=live rootfstype=auto vga=791 init=/init kav_lang=ru udev liveimg doscsi nomodeset quiet splash" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "TEXT HELP" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "Disk version : ${disk_ver}" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "New base version : ${new_base}" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "Old base version : ${old_base}" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "Rescue.igz build date : `date +%H:%M/%d.%m.%y`" >> ${tftproot_dir}/${dest_dir}/menu.cfg
echo "ENDTEXT" >> ${tftproot_dir}/${dest_dir}/menu.cfg

echo && cat ${tftproot_dir}/${dest_dir}/menu.cfg

Патч init.patch

--- ./initrd/init.bak	2012-03-11 23:30:56.000000000 +1100
+++ ./initrd/init	2012-03-12 00:09:33.165699617 +1100
@@ -270,7 +270,7 @@
 #    [ $main_loop -gt $RDRETRY ] 
 #        &9>/.console_lock
     if [ $main_loop -gt $RDRETRY ]; then
-	CDROM_DEVICES="/dev/sr*"
+	CDROM_DEVICES="/livecd.squash"
 	for i in $CDROM_DEVICES
 	do
 	    /sbin/dmsquash-live-root $i
@@ -288,7 +288,7 @@
 unset RDRETRY
 
 if  ! ismounted "/run/initramfs/live"; then
-    CDROM_DEVICES="/dev/sr*"
+    CDROM_DEVICES="/livecd.squash"
     for i in $CDROM_DEVICES
     do
         /sbin/dmsquash-live-root $i

Патч dmsquash-live-root.patch

--- ./initrd/sbin/dmsquash-live-root.bak	2012-03-11 23:30:56.000000000 +1100
+++ ./initrd/sbin/dmsquash-live-root	2012-03-12 00:07:12.531467569 +1100
@@ -28,47 +28,47 @@
 overlay=$(getarg rd.live.overlay overlay)
 
 # CD/DVD media check
-[ -b $livedev ] && fs=$(blkid -s TYPE -o value $livedev)
-if [ "$fs" = "iso9660" -o "$fs" = "udf" ]; then
-    check="yes"
-fi
-getarg rd.live.check check || check=""
+#[ -b $livedev ] && fs=$(blkid -s TYPE -o value $livedev)
+#if [ "$fs" = "iso9660" -o "$fs" = "udf" ]; then
+#    check="yes"
+#fi
+#getarg rd.live.check check || check=""
 
-if [ -n "$check" ]; then
-    [ -x /bin/plymouth ] && /bin/plymouth --hide-splash
-    checkisomd5 --verbose $livedev || :
-    if [ $? -ne 0 ]; then
-        die "CD check failed!"
-        exit 1
-    fi
-    [ -x /bin/plymouth ] && /bin/plymouth --show-splash
-fi
+#if [ -n "$check" ]; then
+#    [ -x /bin/plymouth ] && /bin/plymouth --hide-splash
+#    checkisomd5 --verbose $livedev || :
+#    if [ $? -ne 0 ]; then
+#        die "CD check failed!"
+#        exit 1
+#    fi
+#    [ -x /bin/plymouth ] && /bin/plymouth --show-splash
+#fi
 
 # determine filesystem type for a filesystem image
-det_img_fs() {
-    local _img="$1" _loop=$(losetup -f) _fs
-    losetup $_loop $_img; _fs=$(det_fs $_loop); losetup -d $_loop
-    echo $_fs
-}
+#det_img_fs() {
+#    local _img="$1" _loop=$(losetup -f) _fs
+#    losetup $_loop $_img; _fs=$(det_fs $_loop); losetup -d $_loop
+#    echo $_fs
+#}
 
 for arg in $CMDLINE; do case $arg in ro|rw) liverw=$arg ;; esac; done
 # mount the backing of the live image first
 mkdir -m 0755 -p /run/initramfs/live
-if [ -f $livedev ]; then
-    # no mount needed - we've already got the LiveOS image in initramfs
-    # check filesystem type and handle accordingly
-    case `det_img_fs $livedev` in
-        squashfs) SQUASHED=$livedev ;;
-        auto) die "cannot mount live image (unknown filesystem type)" ;;
-        *) FSIMG=$livedev ;;
-    esac
-else
-    mount -n -t $fstype -o ${liverw:-ro} $livedev /run/initramfs/live
+#if [ -f $livedev ]; then
+#    # no mount needed - we've already got the LiveOS image in initramfs
+#    # check filesystem type and handle accordingly
+#    case `det_img_fs $livedev` in
+#        squashfs) SQUASHED=$livedev ;;
+#        auto) die "cannot mount live image (unknown filesystem type)" ;;
+#        *) FSIMG=$livedev ;;
+#    esac
+#else
+    mount -n -t auto -o ro $livedev /run/initramfs/live
     if [ "$?" != "0" ]; then
         die "Failed to mount block device of live image"
         exit 1
     fi
-fi
+#fi
 
 # overlay setup helper function
 do_live_overlay() {

Патч config.xml.patch меняет всего лишь две настройки: во-первых, включает проверку файлов «по формату», и, во-вторых, отключает проверку архивов:

--- ./mnt/etc/kl/config.xml.bak	2012-02-07 09:03:33.000000000 +1100
+++ ./mnt/etc/kl/config.xml	2012-03-13 12:45:20.000000000 +1100
@@ -795,8 +795,8 @@
                     <tDWORD name="ExcludeByMask">0</tDWORD>
                     <tDWORD name="MandatoryScanPeriod">7</tDWORD>
                     <tDWORD name="RootkitScan">1</tDWORD>
-                    <tDWORD name="ScanArchived">1</tDWORD>
-                    <tDWORD name="ScanFilter">1</tDWORD>
+                    <tDWORD name="ScanArchived">0</tDWORD>
+                    <tDWORD name="ScanFilter">0</tDWORD>
                     <tDWORD name="ScanFixed">1</tDWORD>
                     <tDWORD name="ScanMail">0</tDWORD>
                     <tDWORD name="ScanMailBases">0</tDWORD>

Настройка pxelinux

По завершении работы скрипта файл ${tftproot_dir}/${dest_dir}/menu.cfg будет иметь примерно такое содержимое:

LABEL kaspersky_rescue_disk_10
MENU LABEL Kaspersky Rescue Disk 10.0.31.4-201203130310
KERNEL apps/kaspersky/rescue
APPEND initrd=apps/kaspersky/rescue.igz root=live rootfstype=auto vga=791 init=/init kav_lang=ru udev liveimg doscsi nomodeset quiet splash
TEXT HELP
Disk version : 10.0.31.4
New base version : 7211135;201203101925
Old base version : 7205908;201203100727
Rescue.igz build date : 08:01/11.03.12
ENDTEXT

Остается добавить в ваш pxelinux.cfg/default такую строку (конечно, изменив путь на свой):

INCLUDE apps/kaspersky/menu.cfg

И, чтобы было совсем понятно, приведу часть моего pxelinux.cfg/default

DEFAULT vesamenu.c32
PROMPT 0
TIMEOUT 100
ONTIMEOUT local

MENU TITLE -= PXE Boot Menu =-
MENU BACKGROUND menu.jpg

MENU COLOR border 30;44 #00000000 #00000000 none
MENU COLOR unsel 37;44 #90ffffff #00000000 std
MENU COLOR sel 7;37;40 #70ffffff #20ff8000 all
MENU COLOR hotsel 1;7;37;40 #e0ffffff #20ff8000 all

LABEL local
      MENU LABEL Boot from local drive
      localboot 0

LABEL memtest86p
      MENU LABEL MemTest86+ v4.20
      KERNEL memdisk
      APPEND initrd=apps/memtest.bin

INCLUDE apps/drweb/menu.cfg

INCLUDE apps/kaspersky/menu.cfg

У меня меню выглядит вот так:

image

Процесс загрузки:

image

Ура, всё работает:

image

Заключение

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

SHELL=/bin/sh
00 8 * * * /storage/projects/kaspersky_rescue_disk_10/make_rescue.igz.sh > /storage/projects/kaspersky_rescue_disk_10/results.log 2>&1

Не забудьте изменить пути на свои!

P.S. скачать архив со всеми скриптами и патчами можно тут.

Автор: Alexander_Erofeev

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js