
이중 해제
CVE-2020-25637
*** 설명 ***
libvirt API(6.8.0 이전 버전)에서 실행 중인 QEMU 도메인의 네트워크 인터페이스 정보를 요청할 때 이중 해제(double free) 메모리 문제가 발생했습니다. 이 취약점은 polkit 접근 제어 드라이버에 영향을 미칩니다. 보다 정확히는, 제한된 ACL 권한으로 읽기-쓰기 소켓에 연결하는 클라이언트가 이 취약점을 악용하여 libvirt 데몬을 충돌시켜 서비스 거부를 일으키거나 잠재적으로 시스템에서 권한을 상승시킬 수 있습니다. 이 취약성의 가장 큰 위협은 데이터의 기밀성과 무결성, 그리고 시스템 가용성입니다.
이 취약성의 가장 중요한 위협은 다음과 같습니다.
취약점 점수:
RedHat의 중간(Moderate) 등급 취약점, 평균 6.4
NVD의 중간(Moderate) 등급 취약점, 평균 6.7
*** 이 취약점을 악용하기 위해 필요한 다양한 도구와 중요한 사전 요구 사항 ***
먼저 운영 체제의 호환성을 확인해야 합니다. 다음 명령어를 실행하세요:
grep -E -c "vmx|svm" /proc/cpuinfo
명령어가 ok로 응답하면 설치를 진행할 수 있습니다:
sudo apt-get -y install qemu-kvm libvirt-bin virt-top outils-libguestfs virtinst bridge-utils
2) Vagrant 설치 :
Vagrant를 설치하려면 다음 명령어를 실행하면 됩니다:
sudo apt -y install vagrant
Vagrant와 KVM을 설치했다면, Vagrant를 사용하여 KVM 가상 머신을 관리할 수 있도록 libvirt 플러그인을 설치할 준비가 된 것입니다.
vagrant plugin install vagrant-libvirt
플러그인이 설치되었는지 확인할 수 있습니다.
vagrant plugin list
3) Vagrant 박스 (box vagrant) :
Vagrant에서 바로 사용할 수 있는 이미지를 사용할 수 있습니다. 이 경우 우분투 20.04 이미지를 사용합니다.
이미지를 Vagrant 박스에 추가하려면 다음 명령어를 실행하면 됩니다:
vagrant box add generic / ubuntu1804 --provider = libvirt
로컬에 있는 박스 목록을 확인하려면:
vagrant box list
4) 디버깅
디버깅에는 두 가지 옵션이 있습니다.
GDB: 도구가 운영 체제에 없는 경우 다음 명령어를 실행하세요:
sudo apt-get install gdb
Valgrind: 도구가 운영 체제에 없는 경우 다음 명령어를 실행하세요:
sudo apt-get install valgrind
*** 코드 실행 ***
Vagrant를 통해 VM 실행:
vagrant up
먼저 라이브러리를 설치하세요:
sudo apt-get install -y libvirt-dev
컴파일:
gcc -g -Wall info1.c -o info1 -lvirt
코드 실행:
./info1 qemu:///system vagrant-vms_ubuntu-01
디버깅과 함께 실행:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=valgrind-out.txt ./info1 qemu:///system vagrant-vms_ubuntu-01
*** 취약점 활성화 ***
취약점을 활성화하기 전에 libvirt에서 문제를 일으키는 함수의 동작 방식을 아는 것이 필수적입니다.
공격자는 libvirt의 qemuAgentGetInterfaces()를 통해 해제된 메모리 영역, 정확히는 ifname 변수의 메모리 영역을 사용하도록 유도하여 서비스 거부를 일으키고 잠재적으로 코드를 실행할 수 있다고 가정합니다.
기다리던 순간이 왔습니다.
Vagrant 파일이 실행되면, Qemu/KVM으로 실행되는 가상 머신 안에서 info1.c 코드를 실행해야 합니다. 즉, VM 안에 VM을 만드는 것, 다시 말해 Vagrant로 만든 VM 안에서 코드를 실행하는 것입니다.
*** 이 취약점 수정 ***
libvirt의 qemuAgentGetInterfaces() 함수에서 ifname 변수를 null로 설정하면 됩니다. 즉, 각 인터페이스에 대해 ifname 변수를 해제해야 합니다.
*** 데모 ***
PowerPoint 파일에서 이중 해제(double free) 문제에 대한 간단한 데모를 찾을 수 있습니다.
*** 중요 ***
이 프로젝트는 취약점의 복잡성, 하드웨어 문제, 그리고 시간 부족으로 인해 끝까지 완성되지 못했습니다.