Uncontrolled recursion loop in Exiv2::Image::printTiffStructure() – exiv2-0.27
Loginsoft-2018-1095
February 25, 2019
CVE Number
CVE-2019-9143
CWE
CWE-400: Uncontrolled Resource Consumption
Product Details
Exiv2 is a C++ library and a command line utility to read, write, delete and modify Exif, IPTC, XMP and ICC image metadata.
URL: https://github.com/Exiv2/exiv2
Vulnerable Versions
0.27
Vulnerability Details
We observed that there is an infinite loop generating recursively at Exiv2::Image::printTiffStructure in file image.cpp .The same be triggered by sending a crafted file to the exiv2 binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact.
SYNOPSIS
In progress
Vulnerable code
do { // Read top of directory const int seekSuccess = !io.seek(start,BasicIo::beg); const long bytesRead = io.read(dir.pData_, 2); if (!seekSuccess || bytesRead == 0) { throw Error(kerCorruptedMetadata); } uint16_t dirLength = byteSwap2(dir,0,bSwap); bool tooBig = dirLength > 500; if ( tooBig ) { out << Internal::indent(depth) << "dirLength = " << dirLength << std::endl; throw Error(kerTiffDirectoryTooLarge); } if ( bFirst && bPrint ) { out << Internal::indent(depth) << Internal::stringFormat("STRUCTURE OF TIFF FILE (%c%c): ",c,c) << io.path() << std::endl;
Analysis
84 ../sysdeps/unix/syscall-template.S: No such file or directory. [ Legend: Modified register | Code | Heap | Stack | String ] ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ──── $rax : 0x49 $rbx : 0x4a $rcx : 0x00007ffff5c172c0 → cmp rax, 0xfffffffffffff001 $rdx : 0x4a $rsp : 0x00007fffffffd338 → 0x00007ffff5b98bff → test rax, rax $rbp : 0x0000619000001480 → "STRUCTURE OF TIFF FILE (II): id:000000,src:000553+[...]" $rsi : 0x0000619000001480 → "STRUCTURE OF TIFF FILE (II): id:000000,src:000553+[...]" $rdi : 0x1 $rip : 0x00007ffff5c172c0 → cmp rax, 0xfffffffffffff001 $r8 : 0x00007ffff5ee6780 → 0x0000000100000001 → 0x0000000000000000 $r9 : 0x00007ffff7fd1780 → 0x00007ffff7fd1780 → [loop detected] $r10 : 0x733a706f2c333132 ("213,op:s"?) $r11 : 0x246 $r12 : 0x4a $r13 : 0x1 $r14 : 0x00007ffff5ee5620 → 0x00000000fbad2a84 → 0x0000000000000000 $r15 : 0x00007fffffffdb20 → 0x0000000041b58ab3 $eflags: [carry PARITY adjust ZERO sign trap INTERRUPT direction overflow resume virtualx86 identification] $cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ──── 0x00007fffffffd338│+0x0000: 0x00007ffff5b98bff → test rax, rax ← $rsp 0x00007fffffffd340│+0x0008: 0x00007ffff5ee5620 → 0x00000000fbad2a84 → 0x0000000000000000 0x00007fffffffd348│+0x0010: 0x000000000000004a ("J"?) 0x00007fffffffd350│+0x0018: 0x0000619000001480 → "STRUCTURE OF TIFF FILE (II): id:000000,src:000553+[...]" 0x00007fffffffd358│+0x0020: 0x00007fffffffd530 → 0x0000000041b58ab3 0x00007fffffffd360│+0x0028: 0x00007fffffffd960 → 0x0000000041b58ab3 0x00007fffffffd368│+0x0030: 0x00007ffff5b9a409 → mov r13, rax 0x00007fffffffd370│+0x0038: 0x00007fffffffdb20 → 0x0000000041b58ab3 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ──── 0x7ffff5c172b2 mov DWORD PTR [rbp*1+0x10750000], esp 0x7ffff5c172b9 mov eax, 0x1 0x7ffff5c172be syscall → 0x7ffff5c172c0 cmp rax, 0xfffffffffffff001 0x7ffff5c172c6 jae 0x7ffff5c172f9 0x7ffff5c172c8 ret 0x7ffff5c172c9 sub rsp, 0x8 0x7ffff5c172cd call 0x7ffff5c350d0 0x7ffff5c172d2 mov QWORD PTR [rsp], rax ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ──── [#0] Id 1, Name: "exiv2", stopped, reason: SIGINT ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ──── [#0] 0x7ffff5c172c0 → __write_nocancel() [#1] 0x7ffff5b98bff → _IO_new_file_write(f=0x7ffff5ee5620 , data=0x619000001480, n=0x4a) [#2] 0x7ffff5b9a409 → new_do_write(to_do=0x4a, data=0x619000001480 "STRUCTURE OF TIFF FILE (II): id:000000,src:000553+000213,op:splice,rep:64\n", '\276' , fp=0x7ffff5ee5620 ) [#3] 0x7ffff5b9a409 → _IO_new_do_write(fp=0x7ffff5ee5620 , data=0x619000001480 "STRUCTURE OF TIFF FILE (II): id:000000,src:000553+000213,op:splice,rep:64\n", '\276' , to_do=0x4a) [#4] 0x7ffff5b9a81b → _IO_new_file_overflow(f=0x7ffff5ee5620 , ch=0xa) [#5] 0x7ffff5b96533 → __GI__IO_putc(c=, fp=0x7ffff5ee5620 ) [#6] 0x7ffff6214a4a → std::ostream::put(char)() [#7] 0x7ffff6214c3f → std::basic_ostream<char, std::char_traits >& std::endl<char, std::char_traits >(std::basic_ostream<char, std::char_traits >&)() [#8] 0x7ffff673df1e → Exiv2::Image::printIFDStructure(this=0x61200000bec0, io=@0x60300000ecb0, out=@0x672ac0, option=Exiv2::kpsRecursive, start=0xff, bSwap=0x0, c=0x49, depth=0x0) [#9] 0x7ffff673fe2a → Exiv2::Image::printTiffStructure(this=0x61200000bec0, io=@0x60300000ecb0, out=@0x672ac0, option=Exiv2::kpsRecursive, depth=0xffffffff, offset=0x0)
Tested environment
64-bit ubuntu 16.04 LTS
Proof of Concept
exiv2 -b -u -k -p R pr $POC
Timeline
Vendor Disclosure: 21-02-2019
Public Disclosure: 15-02-2019
Credit
Discovered by ACE Team – Loginsoft