Out-of-bounds read vulnerability in the function calculate_beam() – abc2mps 8.14.1

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