libvorbis multiple vulnerabilities
================
Author : qflb.wu
===============


Introduction:
=============
The libvorbis package contains a general purpose audio and music encoding format. This is useful for creating (encoding) and playing (decoding) sound in an open (patent free) format.


Affected version:
=====
1.3.5


Vulnerability Description:
==========================
1.
the vorbis_analysis_wrote function in lib/block.c in Xiph.Org libvorbis 1.3.5 can cause a denial of service(OOM) via a crafted wav file.


I found this bug when I test Sound eXchange(SoX) 14.4.2 which used the libvorbis library.


./sox libvorbis_1.3.5_OOM.wav out.ogg


/var/log/syslog info:
  Jul 13 19:58:05 ubuntu kernel: [] Out of memory: Kill process 44203 (sox) score 364 or sacrifice child
Jul 13 19:58:05 ubuntu kernel: [] Killed process 44203 (sox) total-vm:1831804kB, anon-rss:599932kB, file-rss:40kB


----debug info:----
#0  0x00007ffff5df5e92 in vorbis_analysis_wrote ()
from /usr/local/lib/libvorbis.so.0
#1  0x00007ffff7ba1cba in write_samples (ft=0x611c20, buf=buf@entry=0x0, 
    len=len@entry=0x0) at vorbis.c:358
#2  0x00007ffff7ba1dc5 in stopwrite (ft=<optimized out>) at vorbis.c:398
#3  0x00007ffff7b58488 in sox_close (ft=0x611c20) at formats.c:1006
#4  0x0000000000405fa8 in cleanup () at sox.c:246
#5  0x0000000000403479 in main (argc=argc@entry=0x3, 
    argv=argv@entry=0x7fffffffe5e8) at sox.c:3050
#6  0x00007ffff727bec5 in __libc_start_main (main=0x4029c0 <main>, argc=0x3, 
    argv=0x7fffffffe5e8, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe5d8) at libc-start.c:287
#7  0x0000000000403c65 in _start ()
--------
Program terminated with signal SIGKILL, Killed.
The program no longer exists.


POC:
libvorbis_1.3.5_OOM.wav
CVE:
CVE-2017-11333


2.
the vorbis_block_clear function in lib/block.c in Xiph.Org libvorbis 1.3.5 can cause a denial of service(NULL pointer dereference and application crash) via a crafted ogg file.


I found this bug when I test mp3splt 2.6.2 which used the libvorbis library.


./mp3splt -P -t 0.9 libvorbis_1.3.5_null_pointer_dereference.ogg


----debug info:----
0x00007ffff61752c0 in vorbis_block_clear () from /usr/local/lib/libvorbis.so.0
(gdb) disassemble 
Dump of assembler code for function vorbis_block_clear:
   0x00007ffff61752a0 <+0>:push   %r14
   0x00007ffff61752a2 <+2>:mov    %rdi,%r14
   0x00007ffff61752a5 <+5>:push   %r13
   0x00007ffff61752a7 <+7>:push   %r12
   0x00007ffff61752a9 <+9>:push   %rbp
   0x00007ffff61752aa <+10>:push   %rbx
   0x00007ffff61752ab <+11>:mov    0xb8(%rdi),%r13
   0x00007ffff61752b2 <+18>:callq  0x7ffff616b240 <_vorbis_block_ripcord@plt>
   0x00007ffff61752b7 <+23>:mov    0x70(%r14),%rdi
   0x00007ffff61752bb <+27>:test   %rdi,%rdi
   0x00007ffff61752be <+30>:je     0x7ffff61752c5 <vorbis_block_clear+37>
=> 0x00007ffff61752c0 <+32>:callq  0x7ffff616b130 <free@plt>
   0x00007ffff61752c5 <+37>:test   %r13,%r13
   0x00007ffff61752c8 <+40>:je     0x7ffff617530c <vorbis_block_clear+108>
   0x00007ffff61752ca <+42>:mov    $0x1,%r12d
   0x00007ffff61752d0 <+48>:xor    %ebx,%ebx
   0x00007ffff61752d2 <+50>:jmp    0x7ffff61752df <vorbis_block_clear+63>
   0x00007ffff61752d4 <+52>:nopl   0x0(%rax)
   0x00007ffff61752d8 <+56>:add    $0x1,%ebx
   0x00007ffff61752db <+59>:add    $0x1,%r12d
   0x00007ffff61752df <+63>:movslq %ebx,%rax
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i r
rax            0x22
rbx            0x61fca06421664
rcx            0x00
rdx            0x7ffff7ba6778140737349576568
rsi            0x00
rdi            0x80128
rbp            0x7fffffffd4700x7fffffffd470
rsp            0x7fffffffd4000x7fffffffd400
r8             0x746e656d75636f008389754676633104128
r9             0x6143506374224
r10            0x7fffffffd1f0140737488343536
r11            0x7ffff61752a0140737322111648
r12            0x6128506367312
r13            0x00
r14            0x6205606423904
r15            0x7ffff7bcf146140737349742918
rip            0x7ffff61752c00x7ffff61752c0 <vorbis_block_clear+32>
eflags         0x202[ IF ]
cs             0x3351
ss             0x2b43
ds             0x00
es             0x00
fs             0x00
---Type <return> to continue, or q <return> to quit---
gs             0x00
(gdb) ni


Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x80) at malloc.c:2929
2929malloc.c: No such file or directory.
(gdb) bt
#0  __GI___libc_free (mem=0x80) at malloc.c:2929
#1  0x00007ffff61752c5 in vorbis_block_clear ()
   from /usr/local/lib/libvorbis.so.0
#2  0x00007ffff65ac5ae in splt_ogg_v_free (oggstate=0x61fca0) at ogg.c:162
#3  0x00007ffff65ace0b in splt_ogg_info (in=<optimized out>, 
    state=state@entry=0x60ddb0, error=error@entry=0x7fffffffdbf0) at ogg.c:545
#4  0x00007ffff65acf75 in splt_ogg_get_info (state=state@entry=0x60ddb0, 
    file_input=<optimized out>, error=error@entry=0x7fffffffdbf0) at ogg.c:108
#5  0x00007ffff65ae6c7 in splt_pl_init (state=0x60ddb0, error=0x7fffffffdbf0)
    at ogg.c:1482
#6  0x00007ffff7bcac16 in splt_tp_get_original_tags_and_append (
    error=0x7fffffffdbf0, state=0x60ddb0) at tags_parser.c:545
#7  splt_tp_process_original_tags_variable (tpu=tpu@entry=0x61f800, 
    state=state@entry=0x60ddb0, error=error@entry=0x7fffffffdbf0, 
    set_original_tags=1) at tags_parser.c:514
#8  0x00007ffff7bcb4d1 in splt_tp_process_tag_variable (error=0x7fffffffdbf0, 
    state=0x60ddb0, tpu=0x61f800, end_paranthesis=0x7ffff7bcf14c "]", 
    tag_variable_start=0x7ffff7bcf146 "o,@N=1]") at tags_parser.c:363
#9  splt_tp_process_tags (error=0x7fffffffdbf0, state=0x60ddb0, tpu=0x61f800, 
    tags=0x7ffff7bcf143 "%[@o,@N=1]") at tags_parser.c:293
#10 splt_tp_put_tags_from_string (state=state@entry=0x60ddb0, 
    tags=tags@entry=0x7ffff7bcf143 "%[@o,@N=1]", 
    error=error@entry=0x7fffffffdbf0) at tags_parser.c:192
---Type <return> to continue, or q <return> to quit---
#11 0x00007ffff7bbb4f3 in mp3splt_split (state=state@entry=0x60ddb0)
    at mp3splt.c:1232
#12 0x0000000000403320 in main (argc=<optimized out>, 
    orig_argv=<optimized out>) at mp3splt.c:872
(gdb) 
--------------------
 int vorbis_block_clear(vorbis_block *vb){
 int i;
 vorbis_block_internal *vbi=vb->internal;


 _vorbis_block_ripcord(vb);
 if(vb->localstore)_ogg_free(vb->localstore);  <========


 if(vbi){
   for(i=0;i<PACKETBLOBS;i++){
     oggpack_writeclear(vbi->packetblob[i]);
     if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
   }
   _ogg_free(vbi);
 }
 memset(vb,0,sizeof(*vb));
 return(0);
 }


POC:
libvorbis_1.3.5_null_pointer_dereference.ogg
CVE:
CVE-2017-11735


Proof of Concept:
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/42399.zip