Skip to content

Instantly share code, notes, and snippets.

@untaman
Last active October 9, 2024 13:29
Show Gist options
  • Save untaman/cb58123fe89fc65e3984165db5d40933 to your computer and use it in GitHub Desktop.
Save untaman/cb58123fe89fc65e3984165db5d40933 to your computer and use it in GitHub Desktop.
CVE-2021-40647 and CVE-2021-40648
Here is the writeup for CVE-2021-40647.
A specific string being read in from a file will overwrite the size parameter in the top chunk of the heap. This at least causes the program to segmentation abort:
The user craft a file containing the string containing the bytes "\x27" * 1 ; '\x53'*2 ; '\x42'*19984' ; '\xff'*16. This will cause a segmentation abort because the user would have overwritten the size parameter of the top chunk but misaligned the value causing glibc to output "corrupted size vs. prev_size". Example of the top_chunk is below.
Top chunk | IS_MMAPED
Addr: 0x555555779680
prev_size: 0x4242424242424242 <== User Data
size: 0xffffffffffffff42 <== User Data
fd: 0x44443c3e412f3cff
bk: 0xa3e
fd_nextsize: 0x00
bk_nextsize: 0x00
It can be seen the both the size and the prev size parameters are overwritten with user data. If the user craft a file containing the string containing the bytes "\x27" * 1 ; '\x53'*2 ; '\x42'*19983' ; '\xff'*16. This allows the user to set the size of the top-chunk to any arbitrary value thus making the top-chunk size parameter whatever value they want. This is stopped in GLIBC version 2.29 due to sanity checks in the size parameter in the top-chunk but is valid in previous versions of glibc. Below is a example of a correctly aligned top-chunk full of user data. This DOES NOT crash the program due to it being aligned correctly.
Allocated chunk | PREV_INUSE | IS_MMAPED | NON_MAIN_ARENA
Addr: 0x555555779680
prev_size: 0x4242424242424242 <== User Data
size: 0xffffffffffffffff <== User Data
fd: 0x3e44443c3e412f3c
bk: 0x0a
fd_nextsize: 0x00
bk_nextsize: 0x00
Both errors occur at line 3203 of 'man2html.c'.
-------------------------------------------------------------------
Here is the information on CVE-2021-40648.
A filename can be created to overwrite the previous size parameter of the next chunk and the fd, bk, fd_nextsize, bk_nextsize of the current chunk. The next chunk is then freed later on causing a freeing of an arbitrary amount of memory. This DOES NOT crash the program:
The user can create a file of name 'A'*132 and overwrite the previous size parameter of the next chunk and the fd, bk, fd_nextsize, bk_nextsize of the current chunk. This happens at line 3155 of 'man2html.c'.
Before free at line 3191 of 'man2html.c':
Allocated chunk | PREV_INUSE
Addr: 0x555555764660
prev_size: 0x00
size: 0x91
fd: 0x4141414141414141 <== User Data
bk: 0x4141414141414141 <== User Data
fd_nextsize: 0x4141414141414141 <== User Data
bk_nextsize: 0x4141414141414141 <== User Data
Allocated chunk | PREV_INUSE
Addr: 0x5555557646f0
prev_size: 0x41414141 <== User Data
size: 0x231
fd: 0xfbad2488
bk: 0x55555576497b
fd_nextsize: 0x55555576497b
bk_nextsize: 0x555555764960
After free at line 3194 of 'man2html.c':
Allocated chunk | PREV_INUSE
Addr: 0x555555764660
prev_size: 0x00
size: 0x91
fd: 0x4141414141414141 <== User Data
bk: 0x4141414141414141 <== User Data
fd_nextsize: 0x4141414141414141 <== User Data
bk_nextsize: 0x4141414141414141 <== User Data
Free chunk (tcache) | PREV_INUSE
Addr: 0x5555557646f0
prev_size: 0x41414141 <== User Data
size: 0x231
fd: 0x00
bk: 0x555555764010
fd_nextsize: 0x00
bk_nextsize: 0x00
@carnil
Copy link

carnil commented Feb 3, 2024

@untaman this report is from some years ago, but recently it was discussed in https://bugs.debian.org/1062069#12 .

Can you clarify on it? From the Debian maintainer of man2html:

So I have no idea what really is wrong in this CVE. The source code
references given at the above link actually refer to calls to
fopen()/fclose() functions rather then to directly malloc() and free()
directly.

@untaman
Copy link
Author

untaman commented Oct 9, 2024

from what i remember i think i had it attach to gdb and that allowed me to bypass the namelength check. its useless but interesting, i guess. i was 20 hr in and probably not that lucid. Also i didnt look for any memory leaks or i would of written up a POC. I just was able to do a heap overflow. I tried to follow the path it in gdb and marked where it broke so i could be wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment