Monthly Archives: September 2016

Fuzzing with AFL: mpg123

CVE-2016-1000247: Denial of service with crafted id3v2 tags in all mpg123 versions since 0.60.

mpg123_announcement

In the recent weeks, I was reading on the topic of fuzzing binaries and started experimenting as well as trying it out to find new interesting bugs. I decided to use the most user-friendly fuzzer, which is the American Fuzzy Lop (AFL). And thus, the AFL fuzzing journey began.

A close friend of mine recommended fuzzing some open source binaries as an exercise, and we chose to start with mpg123, a command line mp3 player. We managed to find a simple integer underflow denial of service bug, which happens when mpg123 attempts to parse a malformed ID3v2 tag size header. The bug report that was submitted is shown below.

Summary: Segfault (unsigned long underflow) in mpg123 when parsing malformed ID3 header size in id3.c:755:765.
Discovered by : Han Lee & Jerold Hoong

- beep.mp3 id3 header  : 4944 3303 0000 0000 0026 
- crash.mp3 id3 header : 4944 3303 0040 0000 0006

----------------------------
RUN with legit beep.mp3 file
----------------------------

Breakpoint 1, INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:755
755                     while(tagpos < length-10) /* I want to read at least a full header */
(gdb) print tagpos
$1 = 0
(gdb) print length
$2 = 38
(gdb) print length-10
$3 = 28
(gdb)

----------------------------
RUN with malformed crash.mp3
----------------------------

Breakpoint 1, INT123_parse_new_id3 (fr=fr@entry=0x7421c0, first4bytes=<optimized out>) at src/libmpg123/id3.c:755
755                     while(tagpos < length-10) /* I want to read at least a full header */
(gdb) print tagpos
$1 = 1414546737
(gdb) print length
$2 = 6
(gdb) print length-10
$3 = 18446744073709551612
(gdb) n
Breakpoint 2, INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:765
765                         if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
(gdb) n
759                         int head_part = fr->id3v2.version == 2 ? 3 : 4; /* bytes of frame title and of framesize value */
(gdb) n
765                         if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:765
765                         if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
(gdb) bt
#0  INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:765
#1  0x0000000000448ac3 in handle_id3v2 (newhead=<optimized out>, fr=0x7421b0) at src/libmpg123/parse.c:1071
#2  wetwork (newheadp=<optimized out>, fr=<optimized out>) at src/libmpg123/parse.c:1241
#3  INT123_read_frame (fr=fr@entry=0x7421b0) at src/libmpg123/parse.c:536
#4  0x0000000000493862 in get_next_frame (mh=0x7421b0) at src/libmpg123/libmpg123.c:623
#5  mpg123_decode_frame (mh=0x7421b0, num=num@entry=0x741968 <framenum>, audio=audio@entry=0x7fffffffe2e0, bytes=bytes@entry=0x7fffffffe2e8) at src/libmpg123/libmpg123.c:859
#6  0x000000000042ecc8 in play_frame () at src/mpg123.c:763
#7  0x0000000000406735 in main (sys_argc=<optimized out>, sys_argv=<optimized out>) at src/mpg123.c:1369
(gdb)

--------
Analysis
--------

Description: Access violation on source operand
Short description: SourceAv (19/22)
Hash: 6bd52e79e6017b9e236d4d9edea21a67.d278ec4c10e616aa909c08fc399072bd
Exploitability Classification: UNKNOWN
Explanation: The target crashed on an access violation at an address matching the source operand of the current instruction. This likely indicates a read access violation.
Other tags: AccessViolation (21/22)

Kudos to the upstream maintainer of mpg123, Thomas Orgis, who responded very quickly and released a fix for the bug as well as a perl one-liner hotfix for older versions. The source is available for download at http://mpg123.org/download.shtml, and debian has updated the mpg123 packages as well (https://ftp-master.debian.org/new/mpg123_1.23.8-1.html).

References:

Advertisements

Docker is Awesome

I was playing around with Docker for the past few days and really think that it is an awesome tool. I installed Docker for Mac and created an image based on the original Kali docker base image. I no longer need to spawn a full-fledged virtualbox VM running Kali just to run tools such as msfconsole, wpscan etc.

small_v

I created a Dockerfile project to automatically provision a base image which contains the tools that I require. This file can be tweaked to add/remove tools to your liking, and it is available here: https://github.com/v00d00sec/kali-minimal-dockerfile. If you just want to pull the full image without building it from scratch via the Dockerfile, you can pull the image from: https://hub.docker.com/r/v00d00sec/kali_mini/ by issuing the following commands:

docker pull v00d00sec/kali_mini

After the base image is created, you can view it like this:
screen-shot-2016-09-13-at-3-27-44-pm

After-which, you can run the image like this:

screen-shot-2016-09-13-at-3-28-24-pm

Voila! Instant Kali shell spawned.