문제

VM 내에서 코드가 VM 내에서 실행되고 있는지 식별할 수 있는 방법이 있습니까?

특정 VM 시스템을 식별하는 다소 쉬운 방법이 있을 것 같습니다. 특히 VM에 공급자의 확장 기능(예: VirtualBox 또는 VMWare)이 설치되어 있는 경우 더욱 그렇습니다.하지만 CPU에서 직접 실행되고 있지 않다는 것을 식별하는 일반적인 방법이 있습니까?

도움이 되었습니까?

해결책

이에 대한 많은 연구는 소위 "블루필(blue pill)" 공격, 즉 적극적으로 탐지를 회피하려고 시도하는 악성 하이퍼바이저를 탐지하는 데 전념하고 있습니다.

VM을 감지하는 일반적인 방법은 ITLB를 채우고 다음 명령을 실행하는 것입니다. ~ 해야 하다 가상화된 다음(하이퍼바이저에 제어권을 부여할 때 이러한 프로세서 상태가 반드시 지워짐), 추가 코드를 실행하여 ITLB가 여전히 채워져 있는지 감지합니다.그 위에 첫 번째 종이가 있습니다. 여기, 그리고 a의 다소 다채로운 설명 연구원의 블로그 그리고 대안 블로그 기사에 대한 Wayback Machine 링크(이미지 깨짐).

이에 대한 논의의 요점은 악성 하이퍼바이저를 탐지할 수 있는 방법이 항상 존재하며 숨기려고 하지 않는 하이퍼바이저를 탐지하는 것이 훨씬 간단하다는 것입니다.

다른 팁

Red Hat에는 어떤 가상화 제품(있는 경우)이 실행되고 있는지 감지하는 프로그램이 있습니다. virt-what.

타사에서 관리하는 도구를 사용하는 것은 자체 감지 논리를 실행하는 것보다 장기적으로 더 나은 전략입니다.더 많은 눈(더 많은 가상화 제품에 대한 테스트) 등

보다 경험적인 접근 방식은 알려진 VM 장치 드라이버를 확인하는 것입니다.예를 들어 VMware 디스플레이 어댑터, 디스크 드라이브, 네트워크 어댑터 등을 찾기 위해 WMI 쿼리를 작성할 수 있습니다.이는 사용자 환경에서 알려진 VM 호스트 유형에 대해서만 걱정하면 된다는 것을 알고 있는 경우에 적합합니다.여기 Perl에서 이를 수행하는 예, 원하는 언어로 이식될 수 있습니다.

그것은 당신이 무엇을 추구하는지에 따라 다릅니다:

  • VM이 의도적으로 숨겨지지 않은 경우 알려진 후크를 사용할 수 있습니다.VmWare 드라이버를 찾거나 메모리에 특정 문자열이 있거나 기타 특정 징후를 찾는 것과 같습니다.

  • VM이 실제로 사용자가 특별한 작업을 수행하기를 원하는 경우 프로세서 ID를 수정하거나 이를 감지하기 위해 액세스할 수 있는 특수 레지스터를 추가하는 등의 확실한 연결이 있을 것입니다.또는 메모리의 알려진 위치에 있는 특수 장치입니다(세계의 물리적 메모리 공간에 대한 원시 액세스를 얻을 수 있다고 가정).IBM Power6 및 Sun UltraSparc T1/T2와 같은 최신 기계 설계는 항상 하이퍼바이저를 실행하도록 설계되었으며 원시 하드웨어에서 직접 실행하도록 설계되지 않았습니다.OS가 사용하는 "하드웨어"에 대한 인터페이스는 사실 하이퍼바이저 소프트웨어 계층의 인터페이스이므로 우회할 방법이 없습니다.이 경우 상수 "예"이므로 감지가 쉽지 않습니다.이는 오버헤드를 감당할 수 있는 모든 컴퓨터 시스템의 미래 방향일 것으로 예상됩니다. 예를 들어 Freescale QorIQ P4080 칩(www.freescale.com/qoriq)과 같은 최근 설계의 지원을 살펴보세요.

  • VM이 의도적으로 숨기려고 하고 사용자가 그 존재를 쫓는 경우 VM의 타이밍 방해와 다양한 성능 프로필로 인해 거의 항상 이를 포기하게 되는 고양이와 쥐 게임이 됩니다.분명히 이것은 VM이 구현되는 방식과 아키텍처에 얼마나 많은 하드웨어 지원이 있는지에 따라 달라집니다(제 생각에는 zSeries 메인프레임이 일반 x86보다 특정 OS에서 VM 또는 VM 스택의 존재를 숨기는 데 훨씬 더 낫다고 생각합니다) 예를 들어 기계는 다음과 같습니다).보다 http://jakob.engbloms.se/archives/97 이 주제에 대한 토론을 위해.VM으로 숨기려고 시도하는 것이 가능하지만 충분히 열심히 시도하면 탐지가 항상 승리할 가능성이 높습니다.

한 번은 VM에 있는지 알려주는 어셈블리 코드 조각을 발견한 적이 있습니다....Google에서 검색했지만 원본 기사를 찾을 수 없었습니다.

그래도 나는 이것을 찾았습니다. 프로그램이 가상 머신 내에서 실행되고 있는지 감지.

도움이 되길 바랍니다.

대부분의 경우에는 그렇게 하려고 하면 안 됩니다.몇 가지 특정한 경우를 제외하고는 누군가가 VM에서 코드를 실행하고 있는지 신경쓰지 않아도 됩니다.

필요한 경우 Linux에서 가장 일반적인 방법은 다음을 보는 것입니다. /sys/devices/virtual/dmi/id/product_name, 대부분의 실제 시스템에 있는 노트북/메인보드의 이름과 대부분의 가상 시스템에 있는 하이퍼바이저의 이름이 나열됩니다. dmidecode | grep Product 또 다른 일반적인 방법이지만 루트 액세스가 필요하다고 생각합니다.

여기에 (자바 + 윈도우) 기본 머신이 물리적인지 가상인지 식별하는 솔루션입니다.

가상 머신 예:

제조업체

  • 마이크로 소프트 회사
  • 이노텍 GmbH
  • 빨간 모자
  • VMware, Inc.

모델

  • HVM 돔U
  • 가상 기기
  • 버추얼박스
  • KVM
  • VMware 가상 플랫폼

    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());
    }
    }
    

출력을 사용하여 VM인지 실제 머신인지 결정할 수 있습니다.

실제 머신 출력:

BIOS 시리얼:2HC3J12
하드웨어 모델:인스피론 7570
하드웨어 제조업체:델 주식회사

가상 머신 출력:

BIOS 시리얼:0
하드웨어 모델:이노텍 GmBH
하드웨어 제조업체:가상박스

한 가지 좋은 예는 분명히 마더보드 제조업체에 대해 WMI 쿼리를 수행하고 "Microsoft"를 반환하는 경우 VM에 있는 것입니다.나는 이것이 VMWare에만 해당된다고 생각했습니다.각 VM 호스트 소프트웨어에 대해 알려주는 방법은 다양할 수 있습니다.

이 글은 여기 http://blogs.technet.com/jhoward/archive/2005/07/26/407958.aspx VM(적어도 VMWare 및 VirtualPC)에 있는지 감지할 수 있는 몇 가지 좋은 제안과 링크가 있습니다.

네트워크 연결의 MAC 주소를 확인하여 가상 머신에 있는지 여부를 식별할 수 있습니다.예를 들어 Xen은 일반적으로 특정 범위의 주소 00:16:3e:xx:xx:xx를 사용할 것을 권장합니다.

원하는 MAC 주소를 지정하는 것은 시스템 관리자의 몫이므로 이는 보장되지 않습니다.

Linux 시스템에서는 /proc에서 공통 파일을 검색해 볼 수 있습니다.

예를 들어, /proc/vz/의 존재는 OpenVZ임을 알려줍니다.

VM 환경을 감지하는 전체 가이드는 다음과 같습니다. Linux에서는 "약을 마실" 필요가 없습니다 :)

TrapKIT는 VMware 식별 도구인 ScoopyNG를 제공합니다. -- 회피 기술을 우회하려고 시도하지만 반드시 VMware 이외의 가상화 소프트웨어를 대상으로 하는 것은 아닙니다.소스와 바이너리를 모두 사용할 수 있습니다.

VM이 작업을 잘 수행한다면 가상화되고 있다는 사실이 클라이언트에 보이지 않아야 합니다.그러나 다른 단서를 볼 수 있습니다.

VM 환경에 특정한 알려진 드라이버나 소프트웨어를 찾는 것이 최선의 방법이라고 생각합니다.

예를 들어, Windows를 실행하는 VMWare 클라이언트에서는 vmxnet.sys가 네트워크 드라이버가 되며 VMware 가속 AMD PCNet 어댑터로 표시됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top