Schizophrenic�files
2014/06/02
Zürich, Switzerland
Ange Albertini
Gynvael Coldwind
Schizophrenic files
Area41
Gynvael Coldwind
Security researcher, Google
Dragon Sector captain
likes hamburgers
http://gynvael.coldwind.pl/
All opinions expressed during this presentation are mine and mine alone.
They are not opinions of my lawyer, barber and especially not my employer.
Ange Albertini
Reverse engineering
&
Visual Documentations
http://corkami.com
1 file + 2 tools�⇒ 2 different documents
No active detection in the file.
abusing parsers for
ZIP archives
excerpt from Gynvael's talk:
"Dziesięć tysięcy pułapek: ZIP, RAR, etc."
ZIP
trick 1
a glitch in the matrix
file names in ZIP
a couple of files with the same name?
update:
for an awesome example see:
Android: One Root to Own Them All
Jeff Forristal / Bluebox
(https://media.blackhat.com/us-13/US-13-Forristal-Android-One-Root-to-Own-Them-All-Slides.pdf)
ZIP
trick 2
abstract kitty
Let's start with simple stuff -�the ZIP format
A ZIP file begins with letters PK.
Let's start with simple stuff -�the ZIP format
A ZIP file begins with letters PK.
WRONG
ZIP - second attempt :)
.zip file
last 65557 bytes of the file�the "header" is "somewhere" here
PK\5\6...
ZIP - "somewhere" ?!
4.3.16 End of central directory record:
end of central dir signature 4 bytes (0x06054b50)
number of this disk 2 bytes
number of the disk with the
start of the central directory 2 bytes
total number of entries in the
central directory on this disk 2 bytes
total number of entries in
the central directory 2 bytes
size of the central directory 4 bytes
offset of start of central
directory with respect to
the starting disk number 4 bytes
.ZIP file comment length 2 bytes
.ZIP file comment (variable size)
you begin ZIP parsing
from this; it MUST be
at the end of the file
$0000-$FFFF
0-65535
22 bajty
Total: from 22 to 65557 bytes
(aka: PK\5\6 magic will be somewhere between EOF-65557 and EOF-22)
ZIP - looking for the "header"?
"From the START"
Begin at EOF-65557,
and move forward.
"From the END"
(ZIPs usually don't have comments)
Begin at EOF-22,
and move backward.
PK\5\6...
"somewhere"
PK\5\6...
"somewhere"
The show will continue in a moment.
Larch
Something completely different
ZIP Format - LFH
4.3.7 Local file header:�� local file header signature 4 bytes (0x04034b50)� version needed to extract 2 bytes� general purpose bit flag 2 bytes� compression method 2 bytes� last mod file time 2 bytes� last mod file date 2 bytes� crc-32 4 bytes� compressed size 4 bytes� uncompressed size 4 bytes� file name length 2 bytes� extra field length 2 bytes�� file name (variable size)� extra field (variable size)
file data (variable size)
random stuff
PK\3\4... LFH + data
Each file/directory in a ZIP has LFH + data.
ZIP Format - CDH
[central directory header n]�� central file header signature 4 bytes (0x02014b50)� version made by 2 bytes� version needed to extract 2 bytes� general purpose bit flag 2 bytes� compression method 2 bytes� last mod file time 2 bytes� last mod file date 2 bytes� crc-32 4 bytes� compressed size 4 bytes� uncompressed size 4 bytes� file name length 2 bytes� extra field length 2 bytes� file comment length 2 bytes� disk number start 2 bytes� internal file attributes 2 bytes� external file attributes 4 bytes� relative offset of local header 4 bytes�� file name (variable size)� extra field (variable size)� file comment (variable size)
similar stuff to LFH
PK\2\1... CDH
Each file/directory has a CDH entry in the Central Directory
thanks to the redundancy you can recover LFH using CDH, or CDH using LFH
ZIP - a complete file
PK\3\4... LFH + data
PK\5\6...EOCD
PK\2\1... CDH
Files (header+data)
List of files�(and pointers)
ZIP - a complete file (continued)
PK\3\4... LFH + data
PK\5\6...EOCD
PK\2\1... CDH
PK\3\4... LFH + data
PK\5\6...EOCD
PK\2\1... CDH
If the list of the files has pointers to files...
... the ZIP structure can be more relaxed.
ZIP - a complete file (continued)
PK\5\6...EOCD
PK\2\1... CDH
PK\3\4... LFH + data
file comment (variable size)
You can even do an "inception"
(some parsers may allow EOCD(CHD(LFH)))
And now back to our show!
(we were looking for the EOCD)
Larch
Something completely different
ZIP - looking for the "header"?
"stream"
Let's ignore EOCD!
(it's sometimes faster)
(99.9% of ZIPs out there can be parsed this way)
PK\3\4... LFH + data
PK\3\4... LFH + data
PK\3\4... LFH + data
(single "files" in an archive)
PK\5\6...
(who cares...)
ZIP - looking for the "header"?
"aggressive stream"
We ignore the "garbage"!
(forensics)
PK\3\4... LFH + data
PK\3\4... LFH + data
PK\3\4... LFH + data
(single "files" in an archive)
PK\5\6...
(who cares...)
Let's test the parsers!
abstract.zip
abstract.zip
EOCD
LFH+data
CDH
EOCD
LFH+data
CDH
LFH+data
LFH+data
syntax breaker
yellow is a comment of the green archive
stream
aggressive
stream
start-first
end-first
abstract.zip
from zipfile import ZipFile�ZipFile("abstract.zip", "r").printdir()
abstract.zip
<?php�$za = new ZipArchive();�$za->open('abstract.zip');�for ($i=0; $i<$za->numFiles;$i++) {� echo "index: $i\n";� print_r($za->statIndex($i));�}�echo "numFile:" . $za->numFiles . "\n";
abstract.zip
import java.io.FileInputStream;�import java.io.InputStream;�import java.util.zip.ZipEntry;�import java.util.zip.ZipInputStream;��public class zip {� public static void main(String args[]) throws � java.io.IOException, java.io.FileNotFoundException {� InputStream f = new FileInputStream("abstract.zip");� ZipInputStream z = new ZipInputStream(f);�� ZipEntry e;� while((e = z.getNextEntry()) != null) {� System.out.println(e.getName());� } � }�}
abstract.zip
abstract.zip
EOCD
CDH
EOCD
readme_StartFirst.txt
CDH
readme_AggressiveStream.txt
readme_Stream.txt
syntax breaker
readme_EndFirst.txt
Total Commander 8.01
UnZip 6.00 (Debian)
Midnight Commander
Windows 7 Explorer
ALZip
KGB Archiver
7-zip
b1.org
Python zipfile
JSZip
C# DotNetZip
perl Archive::Zip
Jeffrey's Exif Viewer
WOBZIP
GNOME File Roller
WinRAR
OSX UnZip
zip.vim v25
Emacs Zip-Archive mode
Ada Zip-Ada v45
Go archive/zip
Pharo smalltalk 2.0 ZipArchive
Ubuntu less
Java ZipFile
abstract.zip
EOCD
CDH
EOCD
readme_StartFirst.txt
CDH
readme_AggressiveStream.txt
readme_Stream.txt
syntax breaker
readme_EndFirst.txt
PHP ZipArchive
PHP zip_open ...
PHP zip:// wrapper
tcl + tclvfs + tclunzip
abstract.zip
EOCD
CDH
EOCD
readme_StartFirst.txt
CDH
readme_AggressiveStream.txt
readme_Stream.txt
syntax breaker
readme_EndFirst.txt
Ruby rubyzip2
Java ZipArchiveInputStream
java.util.zip.ZipInputStream
abstract.zip
EOCD
CDH
EOCD
readme_StartFirst.txt
CDH
readme_AggressiveStream.txt
readme_Stream.txt
syntax breaker
readme_EndFirst.txt
binwalk (found all)
abstract.zip - result summary
EOCD
CDH
EOCD
readme_StartFirst.txt
CDH
readme_AggressiveStream.txt
readme_Stream.txt
syntax breaker
readme_EndFirst.txt
Thanks!
abstract.zip - who cares?
Oops.
abstract.zip - AV
EICAR test results (using VT):
https://docs.google.com/spreadsheet/ccc?key=0Apy5AGVPzpIOdDRPTFNJQXpqNkdjUzl4SE80c1kwdkE&usp=sharing
Portable Document File
% trailer <</Root …>>
trailer <</Root …>>
<</Root …>>
sometimes,�it’s in the specs
obscurity via over-specification?
notice anything unusual?
WYSIWYG
PDF Layers 1/2
“Optional Content Configuration”
PDF Layers 2/2
BMP
Trick 1
(originally published in Gynvael's "Format BMP okiem hakera" article in 2008)
FILE HEADER
INFO HEADER
PIXEL DATA
offset 0
offset N
bfOffBits
bfOffBits
Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits
(MSDN)
FILE HEADER
INFO HEADER
PIXEL DATA�(secondary)
offset 0
offset N
bfOffBits
bfOffBits
Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits
(MSDN)
PIXEL DATA
Different images, depending on which pixel data is used.
PIXEL DATA�(secondary)
PIXEL DATA
BMP
Trick 2�Something I've learnt about because it spoiled my steg100 task for a CTF (thankfully during testing).
BMP compression & palette
Run-Length Encoding (each box is 1 byte):
Length
>0
Palette Index (color)
Length
0
End of Line
0
Length
0
End of Bitmap
1
Length
0
Move Cursor
2
X offset
Y offset
Length
0
RAW Length
>2
Palette Index (color)
Palette Index (color)
...
BMP compression & palette
Question: If the opcodes below allow jump over pixels and set no data, how will the pixels look like?
Hint: Please take a look at the presentation title :)
Length
0
End of Line
0
Length
0
End of Bitmap
1
Length
0
Move Cursor
2
X offset
Y offset
Option 1
The missing data will be filled with background color.
(index 0 in the palette)
Option 2
The missing data will be black.
Option 3
The missing data will be transparent.�(pink represents transparency)
PNG
a data schizophren
image data combining
cute PoC by @reversity
“There shall not be more than one PLTE chunk”
different images depending on which PLTE chunk is used
Portable Executable
Relocations types
W8
Vista
XP
| | | |
Type 4 HIGH_ADJ | -- | -- | ✓ |
Type 9�MIPS_JMPADDR16 IA64_IMM64 MACHINE_SPEC_9 | 32 bit | 64 bit | ✗ |
Relocations on relocations
| | | |
Type 4 HIGH_ADJ | -- | -- | ✓ |
Type 9�MIPS_JMPADDR16 IA64_IMM64 MACHINE_SPEC_9 | 32 bit | 64 bit | ✗ |
Type 10�DIR64 | ✓ | ✓ | ✓ |
as seen in
PoC||GTFO
Relocation-based PE Schizophren
Julian Bangert, Sergey Bratus -- ELF Eccentricities
GIF
Something Gynvael stumbled on in 2008,�but never made a PoC... until now.
(with great input from Ange)
GIF
GIF can be made of many small images.
If "frame speed" is defined, these are frames instead�(and the first frame is treated as background).
x
x
x
y
y
y
GIF
Certain parsers (e.g. browsers) treat "images" as "frames" regardless of "frame speed" not being defined.
Frame 1
Frame 2
Frame 3
GIF
Certain parsers (e.g. browsers) treat "images" as "frames" regardless of "frame speed" not being defined.
Frame 1
Frame 2
Frame 3
GIF
Schizophrenic PoC:
Frame 1
Frames 2-10001
1x1 px
Frame 10002
These apps try to force animation.
These apps render the GIF by the specs.
GIMP says "frames", but allows one to see all the frames, which is nice.
same-tool schizophrenia
1 file + 1 tool = 2 behaviors
it was too simple
Failures / Ideas / WIP
Screen ⇔ Printer schizophren
via color profiles?
Failures / Ideas / WIP
PNG
Various ancillary chunks (rendering level)
Conclusion
Conclusion
PoCs and slides: http://goo.gl/Sfjfo4
ACK
@reversity @travisgoodspeed @sergeybratus
qkumba @internot @pdfkungfoo�
@j00ru ise ds vx
thank you
questions?
Ange Albertini
Gynvael Coldwind
It's time to kick ass and chew bubble gum... and I'm all outta gum.
Flash (SWF) vs Prezi
vs
Bonus Round
(not a fully schizophrenic problem in popular parsers, that's why it's here)
Prezi SWF sanitizer
Prezi allows embedding SWF files.
But it first sanitizes them.
It uses one of two built-in SWF parsers.
There was a problem in one of them:
Prezi SWF sanitizer
"good" SWF sent to sanitizer
and its evil twin brother
kudos to the sanitizer!
Fixed in Q1 2014. For details see:
"Integer overflow into XSS and other fun stuff - a case study of a bug bounty"