본문 바로가기
Virtualization/[상용] hyper-v

Hyper-V 분석하기 위한 환경설정 하는 방법

by blackcon 2021. 12. 22.

들어가기에 앞서..

해당 포스트는 MSRC(Microsoft Security Response Center) 블로그에 작성된 First Step Hyper-V Research 내용을 토대로 작성하였습니다.


Debugging Environment

1) Intro

이 글에서 작성할 환경 설정은 nested(중첩) VM을 생성하고 이 내부에서 Hyper-V guest의 하이퍼바이저와 루트 파티션의 커널을 디버깅하기 위함입니다. Hyper-V하이퍼바이저 중에서도 Type-1 방식이기 때문에 Host 에서는 커널과 하이퍼바이저를 디버깅할 수 없습니다. 이를 위해 게스트를 만들고 그 안에 Hyper-V를 활성화(nested vm)하고 모든 것을 구성하여 디버깅을 할 것입니다. 다행히도 Hyper-V는 이 방식에서 활용할 중첩 가상화를 지원합니다. 디버깅 환경은 아래 이미지와 같습니다.

Arch for degugging on hyper-v

디버깅하려는 하이퍼바이저 내부에 다른 하이퍼바이저의 게스트로 실행합니다. 간단히 말해서 L0 루트 파티션의 사용자 공간에서 L1 하이퍼바이저와 루트 파티션의 커널을 디버그합니다.

<Nested VM 용어 설명>

  • L0 = 물리적 호스트에서 실행되는 코드. 하이퍼바이저를 실행합니다.
  • L1 = L0의 하이퍼바이저 게스트. 디버그하려는 하이퍼바이저를 실행합니다.
  • L2 = L1의 하이퍼바이저 게스트.

Hyper-V 의 중첩 가상화에 대하여 좀 더 상세한 설명은 여기를 참조해주세요 :)

2) Setting for debugging

하이퍼바이저에 디버그 지원이 내장되어 있어 디버거로 Hyper-V에 연결할 수 있습니다. 활성화하려면 BCD(Boot Configuration Data) 변수에서 몇 가지 설정을 구성해야 합니다.

 

<디버깅 할 VM 설정하기>

  1. Hyper-V 가 활성화되어 있지 않다면 활성화하기(Level0)
    1. 이 문서를 참고하여 Hyper-v 활성화
    2. Host OS 재부팅하기
  2. 디버깅을 위해 새로운 guest VM을 설정하기(Level1)
    1. 여기에 설명된 대로 1세대 Windows 10 게스트를 만듭니다. (2세대 guest에서도 작동하지만 'Secure boot' 를 비활성화해야 함)
      • 참고 이미지 (nested VM)
    2. 게스트 프로세서에서 VT-x를 활성화합니다. 활성화하지 않으면 Hyper-V 플랫폼이 게스트 내부에서 실행되지 않습니다.
      (L1 Guest OS의 전원을 끄고 L0 Host에서 PowerShell(관리자 권한) 에서 활성화 가능)
      • command
        Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true​
      • 참고 이미지
    3. L1게스트 내부에서 하이퍼바이저를 디버깅할 것이므로 L1게스트 내부에서도 Hyper-V를 활성화해야 합니다( 여기에 문서화됨 ). 나중에 게스트 VM을 재부팅합니다.
    4. 이제 디버깅을 활성화하기 위해 BCD 변수를 설정해야 합니다. L1 게스트(방금 설정한 내부 OS) 내부에서 cmd.exe (관리자 권한) 에서 다음을 실행합니다. 아래와 같이 설정을 하면 부팅 후에 적용됩니다
      • command
        # 직렬 포트를 통해 Hyper-V 디버깅 활성화
        bcdedit /hypervisorsettings serial DEBUGPORT:1 BAUDRATE:115200
        bcdedit /set hypervisordebug on
        
        # Hyper-V가 부팅 시 실행되도록 활성화하고 커널을 로드
        bcdedit /set hypervisorlaunchtype auto
        
        # 다른 직렬 포트를 통해 커널 디버그 활성화
        bcdedit /dbgsettings serial DEBUGPORT:2 BAUDRATE:115200
        bcdedit /debug on
        
        # 테스트 커널 드라이버를 load 할 일이 있을 경우, 아래 기능 활성화
        bcdedit /set TESTSIGN on
      • 참고 이미지
  3. 앞서 설정한 직렬포트와 연결하기 위해서는 Level 0 VM에서 아래와 같이 셋팅한다.
    1. Level 1 VM (guestOS) 종료하기
    2. Level 1 VM 설정하기
      • Hyper-V 관리자에서 Level1 VM 오른쪽 버튼 클릭 -> [설정] -> 왼쪽 탭에서 [하드웨어] -> [COM1]을 선택
      • Named Pipe를 선택하고 "debug_kernel"로 설정
      • COM2에 대해서도 동일한 작업을 수행하고 이름을 "debug_hv"로 설정합니다.
      • 참고:  Set-VMComPort cmdlet를 사용해서도 위와 같은 설정을 할 수 있음
    3. 이제 Named Pipe 로써 “\\.\pipe\debug_hv” 와 “\\.\pipe\debug_kernel” 이 생성되었고, 각각 hypervisor와 루트 파티션(Level1 VM) 커널에 디버깅을 할 수 있게 되었다.
      • 참고 이미지
    4. Level 0 VM에서 2개의 windbg를 open하여 named pipe로 연결한다.
      • windbg 열기 -> 디버깅 시작-커널 연결 (ctrl+k)
    5. guest OS (level1 VM)을 재부팅하면 디버깅이 가능하다.
      • 참고 이미지

3) EOD (End-Of-Documentation)

여기까지 Hyper-V의 커널과 하이퍼바이저를 디버깅하기 위해서 어떻게 해야하는지 작성해보았는데요. 이 내용은 MS 내부 직원이 분석하는 방법중 하나로써 MS블로그 글에 기재가 되어 있었습니다.

블로그 글에서 이 방법뿐만 아니라 다른 방법에 대한 링크를 아래와 같이 공유가 되었으니 참고해주세요 :)