Out-of-bounds read vulnerability in the function calculate_beam() – abc2mps 8.14.1
December 27, 2018
CVE Number
–
CWE
CWE-476: NULL Pointer Dereference
Product Details
abcm2ps is a C program which converts music tunes from the ABC music notation to PostScript or SVG.
URL: https://github.com/leesavide/abcm2ps.git
Vulnerable Versions
8.14.1-master
Vulnerability Details
Out-of-bounds read vulnerability is discovered in the abcm2ps (8.14.1-master). The same can be triggered by sending a crafted abc file to the abcm2ps binary. It allows an attacker to cause Denial of Service (Segmentation fault) or possibly have unspecified other impact when a victim opens a specially crafted file.
SYNOPSIS
we observed that, when a crafted audio file is passed to the binary, The function draw_sym_near
the variables holds the file from p_voice->sym
. Now it invokes to another function which is calculate_beam
located in draw.c
. In calculate_beam
at line stem_err=min_tb[0][(unsigned) s->nflags]
, where stem_err
is a float type where it checks the stem lengths, min_tb is an Array of an Array(jagged array), in s->nflags
, where s is a structure and it takes the file from p_voice->sym
and nflags
describes the number of note flags. In min_tb the product uses untrusted input when calculating or using an array index that is outside the bounds of an array which triggers to out-of-bounds read vulnerability.
Vulnerable code
if (s->nhd == 0) stem_err = min_tb[0][(unsigned) s->nflags];
Analysis
Program received signal SIGSEGV, Segmentation fault. [ Legend: Modified register | Code | Heap | Stack | String ] ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------[ registers ]---- $rax : 0x5555557d7740 ? 0x00005555557d79a0 ? 0x00005555557d7bf0 ? 0x00005555557d7e40 ? 0x00005555557d80a0 ? 0x00005555557d8300 ? 0x00005555557d8558 ? 0x00005555557d87b0 $rbx : 0xffffffd0 $rcx : 0x5555557d79a0 ? 0x00005555557d7bf0 ? 0x00005555557d7e40 ? 0x00005555557d80a0 ? 0x00005555557d8300 ? 0x00005555557d8558 ? 0x00005555557d87b0 ? 0x00005555557d8a10 $rdx : 0xffffffd0 $rsp : 0x7fffffffdad0 ? 0x0000004000000018 $rbp : 0x5555557d7740 ? 0x00005555557d79a0 ? 0x00005555557d7bf0 ? 0x00005555557d7e40 ? 0x00005555557d80a0 ? 0x00005555557d8300 ? 0x00005555557d8558 ? 0x00005555557d87b0 $rsi : 0x0 $rdi : 0x0 $rip : 0x55555556b074 ? movss xmm4, DWORD PTR [r15+rbx*4] $r8 : 0x5555557c39a0 ? 0x00005555557d6448 ? 0x00005555557d66a0 ? 0x00005555557d6900 ? 0x00005555557d6b60 ? 0x00005555557d6dc0 ? 0x00005555557d7020 ? 0x00005555557d7280 $r9 : 0x7fffffffdb50 ? 0x0000000000000000 $r10 : 0x0 $r11 : 0x540 $r12 : 0x0 $r13 : 0x1 $r14 : 0x0 $r15 : 0x5555555a31c0 ? add BYTE PTR [rax], al $eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] $es: 0x0000 $gs: 0x0000 $cs: 0x0033 $fs: 0x0000 $ds: 0x0000 $ss: 0x002b --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------[ stack ]---- 0x00007fffffffdad0¦+0x00: 0x0000004000000018 ? $rsp 0x00007fffffffdad8¦+0x08: 0x0000000000000400 0x00007fffffffdae0¦+0x10: 0x00000040557d66a0 ("f}U@"?) 0x00007fffffffdae8¦+0x18: 0x0000000000000007 0x00007fffffffdaf0¦+0x20: 0x0000000000000410 0x00007fffffffdaf8¦+0x28: 0x00005555557d1208 ? 0x0000000000000000 0x00007fffffffdb00¦+0x30: 0x0000000000000430 0x00007fffffffdb08¦+0x38: 0x0000000000000000 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------[ code:i386:x86-64 ]---- 0x55555556b069 test dil, dil 0x55555556b06c jne 0x55555556b531 0x55555556b072 mov ebx, edx ? 0x55555556b074 movss xmm4, DWORD PTR [r15+rbx*4] 0x55555556b07a cmp BYTE PTR [rax+0x58], 0x0 0x55555556b07e jle 0x55555556b558 0x55555556b084 movsx edi, BYTE PTR [rax+rdi*1+0x3d] 0x55555556b089 cmp dil, 0x1a 0x55555556b08d jle 0x55555556b09f --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------[ source:draw.c+353 ]---- 348 } 349 x = s->voice == voice ? s->xs : s->x; 350 ys = a * x + b - staff_tb[s->staff].y; 351 if (s->voice == voice) { 352 if (s->nhd == 0) 353 stem_err = min_tb[0][(unsigned) s->nflags]; 354 else 355 stem_err = min_tb[1][(unsigned) s->nflags]; 356 if (s->stem > 0) { 357 if (s->pits[s->nhd] > 26) { 358 stem_err -= 2; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------[ threads ]---- [#0] Id 1, Name: "abcm2ps", stopped, reason: SIGSEGV --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------[ trace ]---- [#0] 0x55555556b074 ? Name: calculate_beam(bm=0x7fffffffdb50, s1=0x5555557d7740) [#1] 0x5555555719b8 ? Name: draw_sym_near() [#2] 0x555555582f7d ? Name: delayed_output(indent=0) [#3] 0x555555582f7d ? Name: output_music() [#4] 0x5555555886c1 ? Name: generate() [#5] 0x555555588c38 ? Name: gen_ly(eob=0x0) [#6] 0x55555558eab8 ? Name: do_tune() [#7] 0x555555560ce2 ? Name: abc_parse(p=0x5555557ddbb0 "", fname=0x5555557f7f10 "POC", ln=0x16b) [#8] 0x555555578c14 ? Name: txt_add_eos(fname=0x5555557f7f10 "POC", linenum=0x16b) [#9] 0x5555555790a4 ? Name: frontend(s=, ftype=, fname=, linenum=) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 0x000055555556b074 in calculate_beam (bm=bm@entry=0x7fffffffdb50, s1=s1@entry=0x5555557d7740) at draw.c:353 gef➤ p min_tb $377 = {{16, 16, 14, 12, 10, 10}, {14, 14, 10, 9, 9, 9}} gef➤ p min_tb[0][(unsigned) s->nflags] $379 = 16 gef➤ p s->nflags $381 = 0x1 gef➤ p/d s->nflags $392 = -48 gef➤ i r rax 0x5555557d7740 0x5555557d7740 rbx 0xffffffd0 0xffffffd0 rcx 0x5555557d79a0 0x5555557d79a0 rdx 0xffffffd0 0xffffffd0 rsi 0x0 0x0 rdi 0x0 0x0 rbp 0x5555557d7740 0x5555557d7740 rsp 0x7fffffffdad0 0x7fffffffdad0 r8 0x5555557c39a0 0x5555557c39a0 r9 0x7fffffffdb50 0x7fffffffdb50 r10 0x0 0x0 r11 0x540 0x540 r12 0x0 0x0 r13 0x1 0x1 r14 0x0 0x0 r15 0x5555555a31c0 0x5555555a31c0 rip 0x55555556b074 0x55555556b074 eflags 0x10246 [ PF ZF IF RF] cs 0x33 0x33 ss 0x2b 0x2b ds 0x0 0x0 es 0x0 0x0 fs 0x0 0x0 gs 0x0 0x0
Tested environment
64-bit ubuntu 16.04 LTS
Proof of Concept
./abcm2ps r -E -g -x -v -O fff -O = -i -k 1 $POC -s 10 -w 1 -m 100 -d 100 -a 0 -f musicfont.fmt -D Bar/ -p -l -I 500 -x -M -N 3 -1 -G -j 0 -b 1 -f -T all -c -B 10
Timeline
Vendor Disclosure: 2018-12-13
Public Disclosure:
Credit
Discovered by ACE Team – Loginsoft