VMware Hypervisor
를 이용하여 debugee
를 만들고, 이의 kernel
을 debugging
하는 방법을 소개한다.
make debugee
VMware
로 분석 대상 kernel
이 구축되어 있는 vmx
를 로딩하거나, 딱히 상관없다면 편하게 아무 linux
나 만들어서 debugee
를 만들자.
debugee
를 만들었다면 먼저 uname -r
로 kernel version
을 확인하자.
ubuntu@ubuntu:~$ uname -r
4.15.0-70-generic
그리고, 디버깅을 위해 vmlinux
를 추출해야 한다.
vmlinux
란 정적으로 링크된 실행 파일 형식의Linux kernel
을 말한다.
vmlinuz
는vmlinux
를zlib, bzip2
등으로 압축한 파일이다.
zImage, bzImage
또한 동일하게vmlinux
를 압축한 파일이다. 커널 크기에 따라 다름
추출을 도와주는 바이너리는 아래 경로에서 찾을 수 있다.
/usr/src/linux-headers-$(uname -r)/scripts/extract-vmlinux
만약 존재하지 않는다면 설치가 필요하다.
sudo apt-get install linux-headers-$(uname -r)
이를 이용하여 아래와 같이 vmlinux
를 추출할 수 있다.
/usr/src/linux-headers-$(uname -r)/scripts/extract-vmlinux /boot/vmlinuz-$(uname -r) > vmlinux
이렇게 얻은 vmlinux
는 stripped
상태인데, module
을 분석하기 위한 나의 입장으로써는 신경쓸게 안된다.
kernel
의 symbol
이 필요하다면 아래의 절차를 따라주길 바란다.
ubuntu@ubuntu:~$ cat /etc/apt/sources.list.d/ddebs.list
deb http://ddebs.ubuntu.com xenial main restricted universe multiverse
deb http://ddebs.ubuntu.com xenial-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com xenial-proposed main restricted universe multiverse
ubuntu@ubuntu:~$ sudo apt-get update
...
ubuntu@ubuntu:~$ sudo apt-get install linux-image-$(uname -r)-dbgsym
key
에러가 뜨는 경우 아래의 명령어로 해결할 수 있다.
ubuntu@ubuntu:~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C8CAB6595FDFF622
이렇게 설치한 파일은 다음과 같은 경로에 존재한다.
/usr/lib/debug/boot/vmlinux-$(uname -r)
disable mitigations
Linux kernel
에는 KASLR, SMEP, SMAP, KADR, KPTI
라는 보호기법들이 존재한다.
KASLR(Kernel Address Space Layout Randomization)
- 커널 메모리 주소 랜덤화
SMEP(Supervisor Mode Execution Protection)
-user space
에서code execution
방지
SMAP(Supervisor mode Access Protection)
-user space
에서memory access
방지
KPTI(Kernel Page Table Isolation)
-user space
에서kernel space
의 데이터를 획득하는 것을 방지하기 위해kernel page
를 분리
원활한 debugging
을 위해 KASLR, SMEP, SMAP, KADR, KPTI
을 disable
시키도록 하자.
이는 KADR
을 제외하고는 아래의 파일에서 설정 가능하다.
/etc/default/grub
내용은 다음과 같다.
GRUB_DEFAULT=0
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet nosmap nosmep nokaslr nopti"
GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US"
위와 같이 nosmap, nosmep, nokaslr, nopti
를 넣어주고 아래의 명령어로 grub
을 update
시켜주고 reboot
을 하면 간단하게 KASLR, SMEP, SMAP, KPTI
를 disable
할 수 있다,
sudo update-grub
sudo reboot
KADR
은 다음과 같이 disable
할 수 있다.
ubuntu@ubuntu:/boot$ sudo sysctl -w kernel.kptr_restrict=0
kernel.kptr_restrict = 0
ubuntu@ubuntu:/boot$ sudo sysctl -w kernel.perf_event_paranoid=0
kernel.perf_event_paranoid = 0
ubuntu@ubuntu:/boot$ cat /proc/kallsyms | tail
ffffffffc00022b0 t pacpi_set_dmamode [pata_acpi]
ffffffffc0002350 t pacpi_set_piomode [pata_acpi]
ffffffffc00023b0 t pacpi_qc_issue [pata_acpi]
ffffffffc0004000 d pacpi_pci_driver [pata_acpi]
ffffffffc0002414 t pacpi_pci_driver_exit [pata_acpi]
ffffffffc0004100 d pacpi_ops [pata_acpi]
ffffffffc0003080 r pacpi_pci_tbl [pata_acpi]
ffffffffc0004480 d __this_module [pata_acpi]
ffffffffc0002414 t cleanup_module [pata_acpi]
ffffffffc0003080 r __mod_pci__pacpi_pci_tbl_device_table [pata_acpi]
이제 debugger
를 listen
하기 위하여 vmx
파일을 수정해야 한다.
각각 x86
과 x64
니 잘 보고 넣어주자.
debugStub.listen.guest32 = "TRUE"
debugStub.listen.guest32.remote = "TRUE"
debugStub.hideBreakpoints = "FALSE"
monitor.debugOnStartGuest32 = "TRUE"
debugStub.listen.guest64 = "TRUE"
debugStub.listen.guest64.remote = "TRUE"
debugStub.hideBreakpoints = "FALSE"
monitor.debugOnStartGuest64 = "TRUE"
vmx
를 수정해주고 debugee
를 부팅시키면, 검은 화면에서 멈추게 되는데 정상이다.
이렇게 debugee
는 0.0.0.0:8832(x86), 0.0.0.0:8864(x64)
에서 debugger
를 listen
하는 상태가 된다.
attach to debugee
debugger
는 remote debugging
을 지원하는 아무 debugger
나 사용해도 된다.
peda
를 사용하고 있다면, pwndbg
를 설치하여 적용시키자.
peda
는 remote debugging memory mapping
이 지원되지 않아 context
를 가져오지 못한다.
peda
의 기능은 pwndbg
에서도 모두 지원되니 일단 쓰자..
아까 extract-vmlinux
를 통해 얻은 vmlinux
를 이용하여 debugee
에 연결하자.
연결이 되면 continue
명령어를 통해 부팅을 시켜주자.
부팅을 시키고, 이제 debugging
을 즐기면 된다!
module
을 분석하고자 하는 경우 insmod
로 module
을 적재해주고, module
의 .text
주소를 찾아 symbol
을 로딩시켜주면 된다.
ubuntu@ubuntu:~/kernel_ex/stack_smashing$ sudo insmod chardev.ko
ubuntu@ubuntu:~/kernel_ex/stack_smashing$ lsmod | grep chardev
chardev 16384 0
ubuntu@ubuntu:~/kernel_ex/stack_smashing$ sudo cat /sys/module/chardev/sections/.text
0xffffffffc03b6000
이제 module debugging
을 즐기면 된다!
ref
https://www.lazenca.net/display/TEC/02.Debugging+kernel+and+modules
https://defenit.kr/2019/10/21/Pwn/%E3%84%B4%20Research/%EC%BB%A4%EB%84%90_%EA%B8%B0%EC%B4%88/
https://animal0day.blogspot.com/2017/12/linux-kernel-debugging-with-vmware.html
https://xakcop.com/post/vmw-kernel-debugging/
'system > material' 카테고리의 다른 글
linux file vtable check bypass (0) | 2019.12.24 |
---|---|
iretq, fops, tty, tty_ops struct (0) | 2019.11.19 |
peda special instruction (0) | 2019.11.11 |
linux kernel module 작성해보기 (0) | 2019.11.11 |
return-to-dynamic-linker (0) | 2019.11.07 |