Как определить, что вы работаете под виртуальной машиной?

Есть ли способ определить изнутри ВМ, что ваш код выполняется внутри ВМ?

Я предполагаю, что есть более или менее простые способы идентификации конкретных систем виртуальных машин, особенно если на виртуальной машине установлены расширения провайдера (например, для VirtualBox или VMWare). Но есть ли общий способ определить, что вы не работаете непосредственно на процессоре?

12 ответов

Решение

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

Классический трюк для обнаружения виртуальной машины состоит в заполнении ITLB, выполнении инструкции, которая должна быть виртуализирована (которая обязательно очищает такое состояние процессора, когда он передает управление гипервизору), а затем запускает еще немного кода, чтобы определить, заполнен ли ITLB., Первая статья об этом находится здесь, и довольно красочное объяснение из блога исследователя и альтернативной ссылки Wayback Machine на статью блога (изображения повреждены).

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

Red Hat имеет программу, которая определяет, под каким (если есть) продуктом виртуализации он работает: virt-what,

Использование стороннего инструмента, поддерживаемого сторонними разработчиками, - это лучшая стратегия в долгосрочной перспективе, чем попытка развернуть собственную логику обнаружения: больше глаз (тестирование на большем количестве продуктов для виртуализации) и т. Д.

Более эмпирический подход заключается в проверке известных драйверов устройств ВМ. Вы можете написать WMI-запросы, чтобы найти, скажем, дисплейный адаптер VMware, дисковод, сетевой адаптер и т. Д. Это подойдет, если вы знаете, что вам нужно беспокоиться только об известных типах хостов виртуальных машин в вашей среде. Вот пример этого в Perl, который можно перенести на язык по вашему выбору.

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

Если вам нужно, в Linux самый распространенный способ - это посмотреть на /sys/devices/virtual/dmi/id/product_name, в котором будет указано имя ноутбука / материнской платы в большинстве реальных систем и гипервизор в большинстве виртуальных систем. dmidecode | grep Product это еще один распространенный метод, но я думаю, что требует root-доступа.

Это зависит от того, что вы после:

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

  • Если виртуальная машина действительно хочет, чтобы вы делали для нее особые действия, она будет иметь некоторые очевидные возможности, такие как изменение идентификатора процессора или добавление некоторых специальных регистров, к которым вы можете получить доступ для его обнаружения. Или специальное устройство в известном месте в памяти (при условии, что вы можете получить сырой доступ к физическому пространству памяти вашего мира). ЗАМЕТЬТЕ, что современные конструкции машин, такие как IBM Power6 и Sun UltraSparc T1/T2, предназначены для ВСЕГДА запуска гипервизора и никогда напрямую на необработанном оборудовании. Интерфейс "аппаратного обеспечения", который использует ОС, на самом деле является интерфейсом на программном уровне гипервизора, и его невозможно обойти. В этом случае обнаружение является тривиальным, поскольку это постоянное "да". Это вероятное будущее направление для всех компьютерных систем, которые могут позволить себе накладные расходы, посмотрите на поддержку в последних разработках, таких как, например, чип Freescale QorIQ P4080 (www.freescale.com/qoriq).

  • Если виртуальная машина намеренно пытается спрятаться, и вы преследуете ее присутствие, то это игра в кошки-мышки, в которой временные помехи и другой профиль производительности виртуальной машины почти всегда отдают ее. Очевидно, что это зависит от того, как реализована виртуальная машина и от того, какая аппаратная поддержка имеется в архитектуре (я думаю, что мэйнфрейм zSeries гораздо лучше скрывает присутствие виртуальной машины или стека виртуальных машин под вашей конкретной ОС, чем обычный x86 машина есть, например). Смотрите http://jakob.engbloms.se/archives/97 для обсуждения этой темы. Можно попытаться спрятаться как виртуальная машина, но обнаружение, скорее всего, всегда победит, если она будет стараться достаточно сильно.

Вот решение (java + windows), чтобы определить, является ли базовая машина физической или виртуальной.

Примеры виртуальных машин:

производитель

  • Xen
  • Корпорация Майкрософт
  • Иннотек ГмбХ
  • Красная шляпа
  • VMware, Inc.

модель

  • HVM domU
  • Виртуальная машина
  • VirtualBox
  • KVM
  • VMware Virtual Platform

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    
    public abstract class OSUtil {
    
    public static final List<String> readCmdOutput(String command) {
        List<String> result = new ArrayList<>();
    
        try {
            Process p=Runtime.getRuntime().exec("cmd /c " + command);
            p.waitFor();
            BufferedReader reader=new BufferedReader(
                    new InputStreamReader(p.getInputStream())
                    );
            String line;
            while((line = reader.readLine()) != null) {
                if(line != null && !line.trim().isEmpty()) {
                    result.add(line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return result;
    }
    
    public static final String readCmdOutput(String command, int lineNumber) {
        List<String> result = readCmdOutput(command);
        if(result.size() < lineNumber) {
            return null;
        }
    
        return result.get(lineNumber - 1);
    }
    
    public static final String getBiosSerial() {
        return readCmdOutput("WMIC BIOS GET SERIALNUMBER", 2);
    }
    
    public static final String getHardwareModel() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MODEL", 2);
    }
    
    public static final String getHardwareManufacturer() {
        return readCmdOutput("WMIC COMPUTERSYSTEM GET MANUFACTURER", 2);
    }
    
    public static void main(String[] args) {
        System.out.println("BIOS Serial: " + getBiosSerial());
        System.out.println("Hardware Model: " + getHardwareModel());
        System.out.println("Hardware Manufacturer: " + getHardwareManufacturer());
    }
    }
    

Вы можете использовать выходные данные, чтобы решить, является ли это виртуальной машиной или физической машиной:

Физическая производительность машины:

Серийный BIOS: 2HC3J12
Модель аппаратного обеспечения: Inspiron 7570
Производитель оборудования: Dell Inc.

Выход виртуальной машины:

BIOS Serial: 0
Модель оборудования: Innotec GmBH
Производитель оборудования: Virtual Box

Однажды я наткнулся на фрагмент кода ассемблера, в котором говорилось, что вы работаете в ВМ.... Я гуглил, но не смог найти оригинальную статью.

Я нашел это, хотя: определить, работает ли ваша программа внутри виртуальной машины.

Надеюсь, поможет.

Вы можете определить, находитесь ли вы на виртуальной машине, посмотрев на MAC-адрес вашего сетевого подключения. Например, Xen обычно рекомендует использовать определенный диапазон адресов 00:16:3e:xx:xx:xx.

Это не гарантируется, так как администратор системы должен указать, какой MAC-адрес им нравится.

В системах Linux вы можете попытаться найти общие файлы в /proc.

Например, экзистент /proc/vz/ сказать вам является OpenVZ.

Вот полное руководство по обнаружению среды виртуальной машины под Linux без необходимости "пить таблетки":)

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

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

Например, на клиенте VMWare под управлением Windows vmxnet.sys будет сетевым драйвером, отображаемым как ускоренный адаптер VMware AMD PCNet.

TrapKIT предоставляет ScoopyNG, инструмент для идентификации VMware - он пытается обойти методы уклонения, но не обязательно нацелен на любое программное обеспечение для виртуализации, кроме VMware. И источник и двоичные файлы доступны.

Хорошим примером является то, что, очевидно, выполняется запрос WMI для производителя материнской платы, и если он возвращает "Microsoft", вы находитесь в виртуальной машине. Я думал, что это только для VMWare. Вероятно, существуют разные способы определения программного обеспечения для каждой виртуальной машины.

Эта статья здесь http://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspx содержит несколько полезных советов и ссылок на несколько способов определения наличия виртуальной машины (VMWare и VirtualPC по адресу наименее).

Другие вопросы по тегам