Divide By Zero vulnerability in function parse_len() – abcm2ps – 1.8.2

Null pointer dereference in function calculate_beam() – abcm2ps – 1.8.2

Loginsoft-2020-1001

5 february, 2020

CVE Number
CWE

CWE – 369 : Divide By Zero

Product Details

abcm2ps is a command line program which converts ABC to music sheet in PostScript or SVG format.
URL: https://github.com/leesavide/abcm2ps

Vulnerable Versions

1.8.2

Vulnerability Details

As per our research, We discovered Divide By Zero vulnerability in parse_len() at abcparse.c. Variable fac is not being checked before performing division with variable len. which can lead to a denial of service attack

SYNOPSIS

In Progress

vulnerable Source code
        // len=0x300, fac=0x0
if (len % fac)
	syntax("Bad length divisor", p - 1);
len /= fac;
*p_len = len;
return p;
Analysis

DEBUG:
GDB :

Gdb:  
Program received signal SIGFPE, Arithmetic exception.
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x300             
$rbx   : 0x0               
$rcx   : 0x0               
$rdx   : 0x0               
$rsp   : 0x00007fffffffe0d0  →  0x00007fffffffe134  →  0x000001220000000f  →  0x0000000000000000
$rbp   : 0x00007fffffffe100  →  0x00007fffffffe160  →  0x00007fffffffe230  →  0x00007fffffffe260  →  0x00007fffffffe280  →  0x00007fffffffe2f0  →  0x00007fffffffe330  →  0x00007fffffffe3b0
$rsi   : 0x0000625000000124  →  "4////////////////////////////////D4]|zD EF- FED2|D[...]"
$rdi   : 0x00007fffffffe098  →  0x00007ffff6f42e80  →  0x73006c6f74727473 ("strtol"?)
$rip   : 0x000055555556197c  →   idiv DWORD PTR [rbp-0x8]
$r8    : 0xa               
$r9    : 0x0               
$r10   : 0x1               
$r11   : 0xa               
$r12   : 0x000055555555b1b0  →   xor ebp, ebp
$r13   : 0x00007fffffffe500  →  0x0000000000000002
$r14   : 0x0               
$r15   : 0x0               
$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 ────
0x00007fffffffe0d0│+0x0000: 0x00007fffffffe134  →  0x000001220000000f  →  0x0000000000000000	 ← $rsp
0x00007fffffffe0d8│+0x0008: 0x00007fffffffe130  →  0x0000000f000000c0  →  0x0000000000000000
0x00007fffffffe0e0│+0x0010: 0x000000c0557cf260  →  0x0000000000000000
0x00007fffffffe0e8│+0x0018: 0x0000625000000145  →  "D4]|zD EF- FED2|D8|"
0x00007fffffffe0f0│+0x0020: 0x0000625000000125  →  "////////////////////////////////D4]|zD EF- FED2|D8[...]"
0x00007fffffffe0f8│+0x0028: 0x0000030000000000  →  0x0000000000000000
0x00007fffffffe100│+0x0030: 0x00007fffffffe160  →  0x00007fffffffe230  →  0x00007fffffffe260  →  0x00007fffffffe280  →  0x00007fffffffe2f0  →  0x00007fffffffe330  →  0x00007fffffffe3b0	 ← $rbp
0x00007fffffffe108│+0x0038: 0x0000555555563343  →   mov QWORD PTR [rbp-0x48], rax
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x555555561972   je     0x5555555618e9 
   0x555555561978   mov    eax, DWORD PTR [rbp-0x4]
   0x55555556197b   cdq    
 → 0x55555556197c   idiv   DWORD PTR [rbp-0x8]
   0x55555556197f   mov    eax, edx
   0x555555561981   test   eax, eax
   0x555555561983   je     0x55555556199c 
   0x555555561985   mov    rax, QWORD PTR [rbp-0x18]
   0x555555561989   sub    rax, 0x1
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:abcparse.c+1822 ────
   1817	 			p = q;
   1818	 		} else {
   1819	 			fac *= 2;
   1820	 		}
   1821	 	}
          // len=0x300, fac=0x0
 → 1822	 	if (len % fac)
   1823	 		syntax("Bad length divisor", p - 1);
   1824	 	len /= fac;
   1825	 	*p_len = len;
   1826	 	return p;
   1827	 }
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "abcm2ps", stopped, reason: SIGFPE
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x55555556197c → parse_len(p=0x625000000145 "D4]|zD EF- FED2|D8|", dur_u=0xc0, p_len=0x7fffffffe130)
[#1] 0x555555563343 → parse_note(p=0x625000000124 "4", '/' , "D4]|zD EF- FED2|D8|", flags=0x4)
[#2] 0x555555562504 → parse_line(p=0x625000000122 "B,4", '/' , "D4]|zD EF- FED2|D8|")
[#3] 0x55555555d51f → abc_parse(p=0x625000000100 "[C8E8]|zE FG- GEC2|[B,3E3][B,D]- [B,4", '/' , "D4]|zD EF- FED2|D8|", fname=0x606000000a40 "result/crashes/id:000037,sig:08,src:000033,op:havoc,rep:16", ln=0x11)
[#4] 0x5555555826c0 → txt_add_eos(fname=0x606000000a40 "result/crashes/id:000037,sig:08,src:000033,op:havoc,rep:16", linenum=0x11)
[#5] 0x5555555839c3 → frontend(s=0x61f000000141 "[C8E8]|zE FG- GEC2|[B,3E3][B,D]- [B,4", '/' , "D4]|zD EF- FED2|D8|\nV:LH\n[C,3G,3][C,G,]- [C,4G,4]|[C,3G,3][C,G,]- [C,4G,4]|[B,,3G,3][B,,G,]- [B,,4G,4]|\\\n[B,,3G,3][B,,G,]- [B,,4G,4]|[_B,,3F,3][B,,F,]- [B,,4F,4]|\n\nX:2\nT:8th Sonata for piano\nC:L. van Beethoven\nM:C\nL:1/16\nQ:1/8=66\n%%staves {1 2}\nK:Cm\n% .. even\031when there are a lot of notes\nV:1\n!fp![E,4G,4C4]- [E,3/G,3/C3/]!3![G,/C/]!4![G,3/=B,3/D3/]!5![G,/C/E/] ([=A, (T B)]\nK:A\n% Breton words on a4C4E4]!4![=B,2D2])z2|\\\n!fp!!3![=B,4D4F4]- [B,3/D3/F3/=[B,/D/F/][B,3/D3/G3/][B,/D/A/] ([B,4D4A4]!3![C2E2G2])z2|\nV:2\n[C,,4E,,4G,,4C,4]- [C,,3/E,,3/G,,3/C,3/]!2!E,/!3!D,3/!4!C,/ (!2!^F,4G,2)z _A,,|\\\n_A,4-A,3/!2!A,/!1!G,3/=F,/ E,4-E,2z3/ E,/|\n\nX:3\nT: Praeludium II (WT II)\nC: J.S.dBach\nM\035 C\nL: 1/16\nQ:1/4=66\n%%staves {RH LH}\n%%MIDI program 6\nK:Cm\n% same as bach.abc (abc2ps-1.3.0) but rewritten in a more standard way\nV:RH\n  zGFG AFEF GEDE FDCD     | E2c2F2c2 E2c2D2=B2", ' ' , "| \nV:LH\n  C,2C2F,2C2 E,2C2D,2=B,2 | C,G,F,G, A,F,E,F, G,E,D,E, F,D,C,D, |  \n\nX:4\nT:Allegro grazioso\nC:Schumann\nM:C\nL:1/8\nQ:1/4=66\n%%staves {1 (2 3)}\nK:G\nV:1\n(!p!B2AB G3)(A |Bcd[Ge]) ([F3A3][^GB])|([A2c2][^GB][Ac] AF=GA)|[G2B2][F2A2] {/G}G3B|\nV:2\n% this voice is not complete, but the measure must be respected\n G,2C2 xD3-    |D2x2\t x4\t      | A,2D2\t\tC2x2  |x8\t\t   |\nV:2\357(G,DCD B,D2)(F,|G,A,B,C  (D2)CB,)     |(A,EDE\t\tCDB,C)|D2[D,2C2]  [G,3B,3]D|\n\n% --- vocal ---\n\nX:5\nT:Tridal a ra va c'halon\nT:(Mor Fawr Wyt Ti!)\nM:4/4\nL:1/8\nQ:1/4=48\n%%staves [(S\025A) (T B)]\nK:A\n% Breton words on a Wales ahoral\nV:S\nEEE\t  |C3E\t   EEFF        |(D2F3)\t  FFF\t |E3C   EEDD\t\t |C4   z:|\nw:Ka-na a |rin, ka-na a rin be-|pred,* rag an Ao-|trou en-eus va zan-tel-|let.\nw:Eñ eo va|nerz, eñ eo i-vez va|Zad,*    eñ eo va|han, ka-na a rin e     |hloar.\nV:A\nCCC\t  |A,3A,   B,CA,A,     |(B,2A,3)  DDB,   |C3A,  B,A,A,G,\t |A,4  z:|\nV:T\nA,A,A,\t  |E,3E,   G,A,F,F,    |(F,2F,3)  A,A,G, |A,3A, G,A,F,E,\t |E,4  z:|\nV:B\nA,,A,,A,, |A,,3C,  B,,A,,D,D,  |(B,,2D,3) D,D,B,,|E,3F, E,C,B,,E,,\t |A,,4 z:|\n\n% organ ---\n\nX:6\nT:Wär Gott nicht mit uns diese Zeit\nC:Johann Nicolaus Hanff\nM:C\nL:1/8\nQ:1/4=66\n%%staves [1 (2 3) 4]\nV:1 nm=\"Rückpos\"\nV:2 nm=\"Orvano\"\nK:Am\nV:1\n%%MIDI program 53\nA3B    c2c2    |d2e2    de/f/P ^c3/d/|d8    |z8\t\t  |\nV:2\n%%MIDI program 73\nz2E2-  E2AG    |F2E2    F2E2\t     |F6  F2|E2CD  ,E3F/G/|\nV:3\n%%MIDI program 73\nz2C2-  CB,A,2  |A,8\t\t     |A,6 D2|C2A,B, C3D/E/|\nV:4\n%%MIDI program 73\nz2A,2- A,G,F,E,|D,2^C,2 D,2A,,2      |D,,8  |z4\t    z2A,2 |\n\nX:7\nT:Qui Toli\213 (Trio)\nC:André Raison\nM:3/4\nL:1/\020", ftype=0x0, fname=0x606000000a40 "result/$POC, linenum=0x11)
[#6] 0x55555555b933 → treat_file(fn=0x7fffffffe78a "result/$POC, ext=0x5555555b4126 "abc")
[#7] 0x55555555ba1f → treat_abc_file(fn=0x7fffffffe78a "result/$POC,rep:16")
[#8] 0x55555555d010 → main(argc=0x0, argv=0x7fffffffe510)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0x000055555556197c in parse_len (p=0x625000000145 "D4]|zD EF- FED2|D8|", dur_u=0xc0, p_len=0x7fffffffe130) at abcparse.c:1822
1822		if (len % fac)
gef➤  p fac
$2 = 0x0
gef➤  i r
rax            0x300	0x300
rbx            0x0	0x0
rcx            0x0	0x0
rdx            0x0	0x0
rsi            0x625000000124	0x625000000124
rdi            0x7fffffffe098	0x7fffffffe098
rbp            0x7fffffffe100	0x7fffffffe100
rsp            0x7fffffffe0d0	0x7fffffffe0d0
r8             0xa	0xa
r9             0x0	0x0
r10            0x1	0x1
r11            0xa	0xa
r12            0x55555555b1b0	0x55555555b1b0
r13            0x7fffffffe500	0x7fffffffe500
r14            0x0	0x0
r15            0x0	0x0
rip            0x55555556197c	0x55555556197c 
eflags         0x10212	[ AF IF RF ]
cs             0x33	0x33
ss             0x2b	0x2b
ds             0x0	0x0
es             0x0	0x0
fs             0x0	0x0
gs             0x0	0x0

ASAN:
ASAN:DEADLYSIGNAL
=================================================================
==24156==ERROR: AddressSanitizer: FPE on unknown address 0x56497236697c (pc 0x56497236697c bp 0x7ffc55450da0 sp 0x7ffc55450d70 T0)
    #0 0x56497236697b in parse_len /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:1822
    #1 0x564972368342 in parse_note /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:2411
    #2 0x564972367503 in parse_line /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:2066
    #3 0x56497236251e in abc_parse /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:166
    #4 0x5649723876bf in txt_add_eos /home/farid/Desktop/fuzzing/abcm2ps/front.c:379
    #5 0x5649723889c2 in frontend /home/farid/Desktop/fuzzing/abcm2ps/front.c:891
    #6 0x564972360932 in treat_file /home/farid/Desktop/fuzzing/abcm2ps/abcm2ps.c:240
    #7 0x564972360a1e in treat_abc_file /home/farid/Desktop/fuzzing/abcm2ps/abcm2ps.c:283
    #8 0x56497236200f in main /home/farid/Desktop/fuzzing/abcm2ps/abcm2ps.c:1041
    #9 0x7f45c9e15b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #10 0x5649723601d9 in _start (/home/farid/Desktop/fuzzing/abcm2ps/abcm2ps+0x71d9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:1822 in parse_len
==24156==ABORTING

Proof of Concept

./abcm2ps $POC
Vendor Disclosure: 2020-2-04
Public Disclosure: 2020-2-05

Credit

Discovered by ACE Team – Loginsoft