Null pointer dereference vulnerability in the function show( ) - abcm2ps-8.14.1
December 26, 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 observed that the vulnerability exists in show()
located in file svg.c
. The function user_ps_write
gives user defined postscript sequences then invokes the function svg_write
, which writes string length to buffer and goes to ps_exec
. when a crafted file is passed to binary abcm2ps, in function show which is triggered by ps_exec
, at condition if (stack->type == STR)
,we observed that stack is a structure and has the value NULL in it ,which triggered a null pointer dereference vulnerability.
Vulnerable code
-> if (stack->type == STR) {
s = pop_free_str();
if (!s || s[0] != '(') {
fprintf(stderr, "svg: No string\n");
ps_error = 1;
return;
}
p = s + 1;
}
Analysis
0x00000000004dbda8 in show (type=0x73) at svg.c:1697
1697 if (stack->type == STR) {
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ registers ]────
$rax : 0x0
$rbx : 0x7fffffffcd60 → 0x0000000041b58ab3
$rcx : 0x8
$rdx : 0x0
$rsp : 0x7fffffffcd20 → 0x000000000040647f → mov ecx, 0x0
$rbp : 0x7fffffffcde0 → 0x00007fffffffd020 → 0x00007fffffffd280 → 0x00007fffffffd530 → 0x00007fffffffd570 → 0x00007fffffffd860 → 0x00007fffffffd870 → 0x00007fffffffd8b0
$rsi : 0x755900 → 0x000000003f333333 ("333?"?)
$rdi : 0x755888 → 0x0000000000000000
$rip : 0x4dbda8 → movzx eax, BYTE PTR [rax+0x8]
$r8 : 0x800e2b18 → 0x0000000000000000
$r9 : 0x800e2b29 → 0x00f9f9f9f9f9f9f9
$r10 : 0x39a
$r11 : 0x7ffff5a5ff90 → 0xfffda370fffda09f
$r12 : 0x7fffffffcdc0 → 0x00007fffffffcff0 → 0x00007fffffffd020 → 0x00007fffffffd280 → 0x00007fffffffd530 → 0x00007fffffffd570 → 0x00007fffffffd860 → 0x00007fffffffd870
$r13 : 0xffffffff9ac → 0x0000000000000000
$r14 : 0x7fffffffcd60 → 0x0000000041b58ab3
$r15 : 0x7fffffffd5d0 → 0x0000000041b58ab3
$eflags: [carry PARITY adjust ZERO sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$es: 0x0000 $gs: 0x0000 $fs: 0x0000 $ds: 0x0000 $ss: 0x002b $cs: 0x0033
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ stack ]────
0x00007fffffffcd20│+0x00: 0x000000000040647f → mov ecx, 0x0 ← $rsp
0x00007fffffffcd28│+0x08: 0x00007f73f58eb830
0x00007fffffffcd30│+0x10: 0x0000000000000000
0x00007fffffffcd38│+0x18: 0x00000000f5a5973b → 0x0000000000000000
0x00007fffffffcd40│+0x20: 0x0000000000000000
0x00007fffffffcd48│+0x28: 0x54fc41fbea02f700
0x00007fffffffcd50│+0x30: 0x0000000000000000
0x00007fffffffcd58│+0x38: 0x00007fffffffcff0 → 0x00007fffffffd020 → 0x00007fffffffd280 → 0x00007fffffffd530 → 0x00007fffffffd570 → 0x00007fffffffd860 → 0x00007fffffffd870
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ code:i386:x86-64 ]────
0x4dbd9e je 0x4dbda8
0x4dbda0 mov rdi, rcx
0x4dbda3 call 0x402e20
→ 0x4dbda8 movzx eax, BYTE PTR [rax+0x8]
0x4dbdac cmp al, 0x1
0x4dbdae jne 0x4dbe7a
0x4dbdb4 call 0x4d7f1b
0x4dbdb9 mov QWORD PTR [rbp-0x98], rax
0x4dbdc0 cmp QWORD PTR [rbp-0x98], 0x0
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ source:svg.c+1697 ]────
1692 p = tmp;
1693 tmp[0] = '\0';
1694 s = NULL;
1695 break;
1696 default:
// type=0x73
→ 1697 if (stack->type == STR) {
1698 s = pop_free_str();
1699 if (!s || s[0] != '(') {
1700 fprintf(stderr, "svg: No string\n");
1701 ps_error = 1;
1702 return;
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ threads ]────
[#0] Id 1, Name: "abcm2ps", stopped, reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x4dbda8 → Name: show(type=0x73)
[#1] 0x4e13d9 → Name: ps_exec(op=0x6230000014c8 "gcshow")
[#2] 0x4eb574 → Name: svg_write(buf=0x623000000109 "/octava{\t% usage: w x y octava\n\texch -10 add exch 2 copy\n\tM 0 10 RM /Times-Roman 16 selectfont(8)show\n\t/Times-Roman 12 selectfont(va)show\n\tM 0 6 RL currentpoint stroke M\n\t[6] 0 setdash 30 add 0 RL currentpoint stroke M\n\t[] 0 setdash 0 -6 RL stroke}!\n/octavab{\t% usage: w x y octavab\n\texch -14 add exch 2 copy \n\tM 0 2 RM /Times-Roman 16 selectfont(8)show\n\t/Times-Roman 12 selectfont(va basso)show\n\t22 add M 0 -6 RL currentpoint stroke M\n\t[6] 0 setdash 30 add 0 RL stroke\n\t[] 0 setdash}!\n/bigl{\t\t% usage: str x y bigl\n\t/Times-Bold 26 selectfont\n\t4 add M showc\n\t1 SLW 1 -2 RM \n\t0 22 RL -22 0 RL\n\t0 -22 RL 22 0 RL stroke}!\n/biglc{\t\t% usage: str x y biglc\n\t2 copy 5 2 roll /Times-Bold 22 selectfont\n\t6 add M showc\n\t1 SLW 13 add newpath\n\t12 0 360 arc stroke}!\n/ped{\t\t% usage: str x y ped\n\tgsave 4 add exch -10 add exch T 26 dup scale\n\t0.368 0.074 moveto\n\t0.341 0.121 0.335 0.147 0.371 0.203 curveto\n\t0.435 0.289 0.531 0.243 0.488 0.155 curveto\n\t0.472 0.117 0.434 0.096 0.414 0.080 curveto\n\t0.429 0.038 0.494 -0.006 0.541 0.075 curveto\n\t0.559 0.123 0.558 0.224 0.663 0.252 curveto\n\t0.603 0.354 0.449 0.393 0.461 0.405 curveto\n\t0.902 0.262 0.705 -0.124 0.555 0.046 curveto\n\t0.488 -0.032 0.417 0.021 0.389 0.055 curveto\n\t0.303 -0.018 0.303 -0.020 0.248 0.040 curveto\n\t0.218 0.108 0.191 0.062 0.164 0.047 curveto\n\t0.010 -0.056 0.032 0.019 0.124 0.062 curveto\n\t0.229 0.117 0.200 0.091 0.228 0.195 curveto\n\t0.240 0.241 0.149 0.250 0.166 0.311 curveto\n\t0.207 0.493 lineto\n\t-0.041 0.441 0.049 0.261 0.126 0.387 curveto\n\t0.138 0.381 lineto\n\t-0.020 0.119 -0.100 0.472 0.220 0.507 curveto\n\t0.548 0.486 0.399 0.171 0.254 0.374 curveto\n\t0.264 0.384 lineto\n\t0.338 0.259 0.521 0.449 0.228 0.488 curveto\n\t0.198 0.356 lineto\n\t0.181 0.304 0.273 0.294 0.262 0.241 curveto\n\t0.229 0.101 lineto\n\t0.273 0.070 0.282 -0.038 0.368 0.074 curveto\n\t0.391 0.094 moveto\n\t0.456 0.130 0.476 0.171 0.468 0.213 curveto\n\t0.452 0.276 0.333 0.171 0.391 0.094 curveto\n\t0.627 0.019 moveto\n\t0.533 0.041 0.586 0.228 0.678 0.229 curveto\n\t0.729 0.170 0.712 0.025 0.627 0.019 curveto\n\teofill\n\t0.8 0.04 0.04 0 360 newpath arc fill\n\tpop grestore}!\n/pedoff{\t% usage: str x y pedoff\n\tgsave 4 add exch -5 add exch T 26 dup scale\n\t0.219 0.198 moveto\n\t0.231 0.172 0.195 0.138 0.162 0.173 curveto\n\t0.149 0.219 0.206 0.231 0.219 0.198 curveto\n\t0.144 0.242 moveto\n\t0.166 0.223 0.193 0.230 0.181 0.267 curveto\n\t0.178 0.306 0.144 0.302 0.151 0.335 curveto\n\t0.160 0.381 0.225 0.377 0.224 0.330 curveto\n\t0.228 0.302 0.198 0.306 0.197 0.267 curveto\n\t0.194 0.237 0.213 0.222 0.237 0.247 curveto\n\t0.263 0.276 0.234 0.297 0.268 0.322 curveto\n\t0.314 0.347 0.354 0.297 0.316 0.259 curveto\n\t0.296 0.237 0.273 0.266 0.246 0.237 curveto\n\t0.223 0.217 0.232 0.194 0.266 0.197 curveto\n\t0.303 0.202 0.302 0.232 0.332 0.228 curveto\n\t0.381 0.232 0.388 0.156 0.332 0.152 curveto\n\t0.302 0.148 0.302 0.185 0.266 0.183 curveto\n\t0.231 0.186 0.228 0.169 0.245 0.143 curveto\n\t0.273 0.116 0.297 0.141 0.316 0.117 curveto\n\t0.350 0.075 0.303 0.029 0.258 0.062 curveto\n\t0.237 0.082 0.261 0.102 0.233 0.133 curveto\n\t0.212 0.151 0.194 0.147 0.197 0.113 curveto\n\t0.203 0.075 0.232 0.075 0.230 0.043 curveto\n\t0.223 -0.004 0.159 -0.002 0.152 0.042 curveto\n\t0.148 0.075 0.185 0.076 0.183 0.113 curveto\n\t0.183 0.147 0.163 0.150 0.141 0.133 curveto\n\t0.113 0.104 0.140 0.079 0.113 0.059 curveto\n\t0.069 0.037 0.033 0.077 0.063 0.117 curveto\n\t0.082 0.141 0.104 0.117 0.132 0.142 curveto\n\t0.153 0.163 0.144 0.188 0.113 0.182 curveto\n\t0.073 0.182 0.075 0.147 0.046 0.152 curveto\n\t-0.003 0.152 -0.003 0.227 0.048 0.227 curveto\n\t0.075 0.231 0.075 0.198 0.113 0.196 curveto\n\t0.141 0.197 0.147 0.207 0.133 0.237 curveto\n\t0.102 0.264 0.082 0.237 0.062 0.261 curveto\n\t0.028 0.302 0.077 0.347 0.118 0.318 curveto\n\t0.138 0.297 0.116 0.275 0.144 0.242 curveto\n\tfill pop grestore}!\n/glissup{\t% usage: x y glissup\n\tgsave T 5 0 T\n\t25 rotate 10 0 T 0 0 M\n\t0 8 8{\n\t\t2 -1.15 2.30 150 30 arcn 4 0 T\n\t\t2 1.15 2.30 -150 -30 arc 4 0 T pop\n\t}for\n\t1 SLW stroke grestore}!\n/tr3{\t\t% usage: x y tr3 - mordent with 3 peeks\n\tM 2.2 2.2 RL 2.1 -2.9 RL 0.7 0.7 RL\n\t2.2 2.2 RL 2.1 -2.9 RL 0.7 0.7 RL\n\t2.2 2.2 RL 2.1 -2.9 RL 0.7 0.7 RL\n\t-2.2 -2.2 RL -2.1 2.9 RL -0.7 -0.7 RL\n\t-2.2 -2.2 RL -2.1 2.9 RL -0.7 -0.7 RL\n\t-2.2 -2.2 RL -2.1 2.9 RL -0.7 -0.7 RL fill}!\n/t2ub{\t\t% usage: x y t2ub - mordent ending with an upper bar\n\t2 copy umrd 0.6 SLW\n\tM 5 4 RM 0 6 RL stroke}!\n/t3tab{\t\t% usage: x y t3tab - mordent + upper turn and bar\n\t4 add 2 copy exch 7.5 sub exch tr3 exch 7.5 add exch\n\t2 copy 0.6 SLW M 2 6 14 6 16 0 RC\n\tM 8 1 RM 0 6 RL stroke}!\n/ubt3ta{\t% usage: x y ubt3ta - up bar + mordent + upper turn\n\t4 add 2 copy 0.6 SLW\n\tM -7.5 0 RM 0 6 RL stroke\n\t2 copy exch 7.5 sub exch tr3\n\tM 7.5 0 RM 2 6 14 6 16 0 RC stroke}!\n/tbt3{\t\t% usage: x y tbt3 - low turn + long mordent\n\texch 10 sub exch 6 add 2 copy 0.6 SLW\n\tM -8 0 RM 2 -6 14 -6 16 0 RC stroke\n\texch 8 add exch tr3}!\n/t2ta{\t\t% usage: x y t2ta - mordent + upper turn\n\t2 copy umrd\n\tM 5 4 RM 1 5 9 5 10 0 RC stroke}!\n/t3b{\t\t% usage: x y t3b - upper + lower mordent\n\t2 copy exch -7.5 add exch 4 add tr3 0.6 SLW\n\tM 2.5 0 RM 0 8 RL stroke}!\n gcshow", len=0x6c7)
[#3] 0x4d697d → Name: user_ps_write()
[#4] 0x41c747 → Name: init_page()
[#5] 0x41e58a → Name: write_buffer()
[#6] 0x4200c8 → Name: check_buffer()
[#7] 0x49a25c → Name: output_music()
[#8] 0x4a1368 → Name: generate()
[#9] 0x4a16eb → Name: gen_ly(eob=0x0)
gef➤ p stack
$1 = (struct elt_s *) 0x0
gef➤ p *stack
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
Explore Cybersecurity Platforms
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros.