lewdlime / abcm2ps

abcm2ps is a command line program which converts ABC to music sheet in PostScript or SVG format. It is an extension of abc2ps which may handle many voices per staff. abcm2ps is Copyright © 2014-2016 Jean-Francois Moine.
http://moinejf.free.fr/
GNU General Public License v3.0
80 stars 31 forks source link

Null Pointer Dereference in function set_clefs(). #69

Open Loginsoft-Research opened 4 years ago

Loginsoft-Research commented 4 years ago

What is the vulnerability? Null pointer Dereference is discovered in abcm2ps (8.14.6-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 impacts when a victim opens a specially crafted file.

Affected version-: 8.14.6-master

Command-: ./abcm2ps $POC

Reproducer file-: REPRODUCER

Synopsis-: During our research we discovered Null pointer dereference in set_clefs () at music.c:2635. g->ts_next is not being validated. Due to a lack of validation of g->ts_next, Null pointer dereference attack can be carried out by sending the malicious file.

Vulnerable code-:

 while (g->voice != voice)
    g = g->ts_next;
if (g->type != CLEF) {
    g = insert_clef(g, new_type, new_line);
    if (s2->sflags & S_CLEF_AUTO)

Debug-:

GDB-:

abcm2ps-8.14.6 (2019-11-05)
File NPD0
NPD0: error: Bad character
  15 [C8E8]|zE FG- GEC2|[B,3E3][B,D]- [B,4D4]uD EF- FED2|D8|
                                             ^
NPD0: error: Bad character
  15 [C8E8]|zE FG- GEC2|[B,3E3][B,D]- [B,4D4]uD EF- FED2|D8|
                                              ^
NPD0: error: Not a note
  17 [C,3G,3][C,G,]) [C,4Ç,4]|[C,3G,3][C,G,]- [C,4G,4]|[B.,3G,3][B,,G,]- [B,,...
                         ^
NPD0: error: Not a note
  17 [C,3G,3][C,G,]) [C,4Ç,4]|[C,3G,3][C,G,]- [C,4G,4]|[B.,3G,3][B,,G,]- [B,,...
                          ^
NPD0: error: Not a note
  17 [C,3G,3][C,G,]) [C,4Ç,4]|[C,3G,3][C,G,]- [C,4G,4]|[B.,3G,3][B,,G,]- [B,,...
                                                           ^
NPD0: error: Missing note after accidental
  18 [B,,3G,4]|[_B,,3F,3][B,,F,]- [B,,4F,4=66
                                             ^
NPD0: error: Chord not closed
  18 [B,,3G,4]|[_B,,3F,3][B,,F,]- [B,,4F,4=66
                                   ^

Program received signal SIGSEGV, Segmentation fault.
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x0               
$rbx   : 0x0000555555943500  →  0x000000000000484c ("LH"?)
$rcx   : 0x0               
$rdx   : 0x2               
$rsp   : 0x00007fffffffd9b0  →  0x0000555555980fc0  →  0x0000000000000000
$rbp   : 0x0000555555983be8  →  0x0000000000000000
$rsi   : 0x000055555597d5c8  →  0x000055555597d818  →  0x000055555597da68  →  0x000055555597dcc0  →  0x000055555597df10  →  0x000055555597e160  →  0x000055555597e3b0  →  0x000055555597e600
$rdi   : 0x0               
$rip   : 0x0000555555668634  →  <set_clefs+20324> movzx r13d, BYTE PTR [rdi+0x3a]
$r8    : 0x0000555555980fc0  →  0x0000000000000000
$r9    : 0x2               
$r10   : 0x0000555555980fc0  →  0x0000000000000000
$r11   : 0x0000555555983bf4  →  0x0000000100000000
$r12   : 0x000055555597d5c8  →  0x000055555597d818  →  0x000055555597da68  →  0x000055555597dcc0  →  0x000055555597df10  →  0x000055555597e160  →  0x000055555597e3b0  →  0x000055555597e600
$r13   : 0x1               
$r14   : 0x1               
$r15   : 0x1               
$eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffd9b0│+0x0000: 0x0000555555980fc0  →  0x0000000000000000    ← $rsp
0x00007fffffffd9b8│+0x0008: 0x0000555555980fc0  →  0x0000000000000000
0x00007fffffffd9c0│+0x0010: 0x0000000255718150
0x00007fffffffd9c8│+0x0018: 0x00007fffffffdf60  →  0x0000555555686b2e  →  <voice_dup+734> mov rax, QWORD PTR [rsp+0x10]
0x00007fffffffd9d0│+0x0020: 0x00007fffffffdf70  →  0x0000000000000001
0x00007fffffffd9d8│+0x0028: 0x00007ffff67f96f6  →  <getenv+22> mov r14, rax
0x00007fffffffd9e0│+0x0030: 0x00007ffff6ba3680  →  0x00000000fbad2887
0x00007fffffffd9e8│+0x0038: 0x000055555596cac8  →  0x000055555596cd18  →  0x000055555596cf68  →  0x000055555596d1b8  →  0x000055555596d408  →  0x000055555596d658  →  0x000055555596d8a8
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x555555668624 <set_clefs+20308> mov    rdx, QWORD PTR [rsp]
   0x555555668628 <set_clefs+20312> lea    rsp, [rsp+0x98]
   0x555555668630 <set_clefs+20320> mov    rdi, QWORD PTR [rdi+0x20]
 → 0x555555668634 <set_clefs+20324> movzx  r13d, BYTE PTR [rdi+0x3a]
   0x555555668639 <set_clefs+20329> cmp    r13d, r14d
   0x55555566863c <set_clefs+20332> jne    0x555555668630 <set_clefs+20320>
   0x55555566863e <set_clefs+20334> xchg   ax, ax
   0x555555668640 <set_clefs+20336> lea    rsp, [rsp-0x98]
   0x555555668648 <set_clefs+20344> mov    QWORD PTR [rsp], rdx
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:music.c+2635 ────
   2630                                 // old staff
   2631                 if (new_type == staff_clef[staff].clef->u.clef.type
   2632                  && new_line == staff_clef[staff].clef->u.clef.line)
   2633                     continue;
   2634                 g = s;
 → 2635                 while (g->voice != voice)
   2636                     g = g->ts_next;
   2637                 if (g->type != CLEF) {
   2638                     g = insert_clef(g, new_type, new_line);
   2639                     if (s2->sflags & S_CLEF_AUTO)
   2640                         g->sflags |= S_CLEF_AUTO;
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "abcm2ps", stopped, reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x555555668634 → set_clefs()
[#1] 0x555555671565 → set_global()
[#2] 0x555555671565 → output_music()
[#3] 0x55555569c1a1 → generate()
[#4] 0x5555556bead1 → gen_ly(eob=0x0)
[#5] 0x5555556bead1 → do_tune()
[#6] 0x555555579865 → abc_parse(p=0x55555597b5a0 "", fname=0x5555559511d0 "result/crashes/id:000000,sig:11,src:000000,op:havoc,rep:128", ln=0x15)
[#7] 0x555555633893 → txt_add_eos(linenum=0x15, fname=<optimized out>)
[#8] 0x555555633893 → frontend(s=<optimized out>, ftype=<optimized out>, fname=<optimized out>, linenum=<optimized out>)
[#9] 0x5555555614c1 → treat_file(fn=<optimized out>, ext=<optimized out>)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
set_clefs () at music.c:2635
2635                    while (g->voice != voice)
gef➤  p g
$1 = (struct SYMBOL *) 0x0
gef➤  p g->ts_next 
Cannot access memory at address 0x20
gef➤  x g->ts_next
Cannot access memory at address 0x20
gef➤  i r
rax            0x0  0x0
rbx            0x555555943500   0x555555943500
rcx            0x0  0x0
rdx            0x2  0x2
rsi            0x55555597d5c8   0x55555597d5c8
rdi            0x0  0x0
rbp            0x555555983be8   0x555555983be8
rsp            0x7fffffffd9b0   0x7fffffffd9b0
r8             0x555555980fc0   0x555555980fc0
r9             0x2  0x2
r10            0x555555980fc0   0x555555980fc0
r11            0x555555983bf4   0x555555983bf4
r12            0x55555597d5c8   0x55555597d5c8
r13            0x1  0x1
r14            0x1  0x1
r15            0x1  0x1
rip            0x555555668634   0x555555668634 <set_clefs+20324>
eflags         0x10202  [ IF RF ]
cs             0x33 0x33
ss             0x2b 0x2b
ds             0x0  0x0
es             0x0  0x0
fs             0x0  0x0
gs             0x0  0x0

Valgrind-:

Process terminating with default action of signal 11 (SIGSEGV)
==16037==  Access not within mapped region at address 0x3A
==16037==    at 0x134F74: set_clefs (music.c:2635)
==16037==    by 0x136711: set_global (music.c:3583)
==16037==    by 0x136711: output_music (music.c:5080)
==16037==    by 0x13D9C0: generate (parse.c:1041)
==16037==    by 0x13DF27: gen_ly (parse.c:1062)
==16037==    by 0x143F07: do_tune (parse.c:3635)
==16037==    by 0x115B61: abc_parse (abcparse.c:179)
==16037==    by 0x12DEE3: txt_add_eos (front.c:379)
==16037==    by 0x12E373: frontend (front.c:891)
==16037==    by 0x110F1C: treat_file (abcm2ps.c:240)
==16037==    by 0x11013B: main (abcm2ps.c:1041)
Segmentation fault