본문 바로가기

system/material

kernel debugging with vmware

kernel debugging with vmware

VMware Hypervisor를 이용하여 debugee를 만들고, 이의 kerneldebugging하는 방법을 소개한다.

make debugee


VMware로 분석 대상 kernel이 구축되어 있는 vmx를 로딩하거나, 딱히 상관없다면 편하게 아무 linux나 만들어서 debugee를 만들자.

debugee를 만들었다면 먼저 uname -rkernel version을 확인하자.

ubuntu@ubuntu:~$ uname -r
4.15.0-70-generic

그리고, 디버깅을 위해 vmlinux를 추출해야 한다.

vmlinux란 정적으로 링크된 실행 파일 형식의 Linux kernel을 말한다.

vmlinuzvmlinuxzlib, 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

이렇게 얻은 vmlinuxstripped 상태인데, module을 분석하기 위한 나의 입장으로써는 신경쓸게 안된다.

kernelsymbol이 필요하다면 아래의 절차를 따라주길 바란다.

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, KPTIdisable 시키도록 하자.

이는 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를 넣어주고 아래의 명령어로 grubupdate 시켜주고 reboot을 하면 간단하게 KASLR, SMEP, SMAP, KPTIdisable할 수 있다,

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]

이제 debuggerlisten하기 위하여 vmx 파일을 수정해야 한다.

각각 x86x64니 잘 보고 넣어주자.

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를 부팅시키면, 검은 화면에서 멈추게 되는데 정상이다.

이렇게 debugee0.0.0.0:8832(x86), 0.0.0.0:8864(x64)에서 debuggerlisten하는 상태가 된다.

attach to debugee


debuggerremote debugging을 지원하는 아무 debugger나 사용해도 된다.

peda를 사용하고 있다면, pwndbg를 설치하여 적용시키자.

pedaremote debugging memory mapping이 지원되지 않아 context를 가져오지 못한다.

peda의 기능은 pwndbg에서도 모두 지원되니 일단 쓰자..

아까 extract-vmlinux를 통해 얻은 vmlinux를 이용하여 debugee에 연결하자.


연결이 되면 continue 명령어를 통해 부팅을 시켜주자.


부팅을 시키고, 이제 debugging을 즐기면 된다!

module을 분석하고자 하는 경우 insmodmodule을 적재해주고, 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/

http://www.alexlambert.com/2017/12/18/kernel-debugging-for-newbies.html

'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