5 Commits
1.3 ... 1.5.1

Author SHA1 Message Date
ben
04eb07f321 Fix help message 2018-09-29 00:17:53 +02:00
ben
caaaaafeb0 Add pdfraw format, v1.5 2018-09-29 00:12:49 +02:00
ben
7e962d60ad Add acrobat reader compatibility for szipdf format 2018-09-28 22:55:53 +02:00
ben
79ddd879c3 Change README 2018-09-28 22:24:40 +02:00
ben
3111008246 Clean source, remove website from src. 2018-09-28 22:21:03 +02:00
33 changed files with 88 additions and 419 deletions

View File

@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .polyglotpdfzip import PolyglotPdfZip from .polyglotpdfzip import PolyglotPdfZip
from .polyglotpdfraw import PolyglotPdfRaw
from .polyglotzippdf import PolyglotZipPdf from .polyglotzippdf import PolyglotZipPdf
from .polyglotszippdf import PolyglotSZipPdf from .polyglotszippdf import PolyglotSZipPdf

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
import logging
'''
|-------------------------------| -
|--------- PDF Header ----------K1 | J1
|-------------------------------| -
|----- PDF OBJ 1 = RAW Data ----K2 |
|-------------------------------| -
|---- Original PDF Ojbects -----K3 | J2
|-------------------------------| -
|---------- Xref Table ---------| |
|-------------------------------K5 |
|----------- Trailer -----------| |
|-------------------------------| |
'''
class PolyglotPdfRaw():
from PdfFileTransformer import Pdf
def __init__(self, Pdf, Raw_filename):
self.buffer = bytearray()
self.pdf = Pdf
self.raw_filename = Raw_filename
self.buffer = bytearray()
def generate(self):
raw_buffer = bytearray()
with open(self.raw_filename, "rb") as f:
raw_buffer = f.read()
k2_stream = raw_buffer
self.pdf.insert_new_obj_stream_at_start(k2_stream)
self.buffer = self.pdf.get_build_buffer()
def write(self, filename):
fd = open(filename, "wb")
fd.write(self.buffer)
fd.close()

View File

@@ -28,8 +28,9 @@ from PdfFileTransformer import Pdf
class PolyglotSZipPdf(PolyglotPdfZip): class PolyglotSZipPdf(PolyglotPdfZip):
def __init__(self, Pdf, Zip): def __init__(self, Pdf, Zip, acrobat_compatibility):
super().__init__(Pdf, Zip) super().__init__(Pdf, Zip)
self.acrobat_compatibility = acrobat_compatibility
def get_rebuild_zip_first_part_size(self): def get_rebuild_zip_first_part_size(self):
@@ -82,7 +83,11 @@ class PolyglotSZipPdf(PolyglotPdfZip):
new_pdf.file_offset = offset new_pdf.file_offset = offset
pdf_buffer = new_pdf.get_build_buffer() pdf_buffer = new_pdf.get_build_buffer()
j2 = pdf_buffer[k2_stream_offset + size_k2_stream:] j2 = pdf_buffer[k2_stream_offset + size_k2_stream:]
new_zip.add_data_to_file(b'', j2, True)
if self.acrobat_compatibility:
new_zip.add_data_to_file(b'\x00', j2, True)
else:
new_zip.add_data_to_file(b'', j2, True)
return new_zip.buffer return new_zip.buffer

View File

@@ -1,3 +1,3 @@
# TruePolyglot # TruePolyglot #
See webiste at https://truepolyglot.hackade.org [website](https://truepolyglot.hackade.org)

BIN
caradoc

Binary file not shown.

View File

@@ -23,6 +23,10 @@ EXAMPLES
# see https://github.com/mstamy2/PyPDF2/LICENSE # see https://github.com/mstamy2/PyPDF2/LICENSE
from __future__ import print_function from __future__ import print_function
import sys
sys.path.append("../")
import argparse import argparse
from PdfFileTransformer.PyPDF2.pagerange import PAGE_RANGE_HELP from PdfFileTransformer.PyPDF2.pagerange import PAGE_RANGE_HELP

View File

@@ -6,7 +6,10 @@ import logging
from PdfFileTransformer import Pdf from PdfFileTransformer import Pdf
from ZipFileTransformer import Zip from ZipFileTransformer import Zip
from PolyglotFile import PolyglotZipPdf, PolyglotPdfZip, PolyglotSZipPdf from PolyglotFile import PolyglotZipPdf
from PolyglotFile import PolyglotPdfZip
from PolyglotFile import PolyglotSZipPdf
from PolyglotFile import PolyglotPdfRaw
def main(): def main():
@@ -17,9 +20,11 @@ def main():
' The format is closest to ZIP.\n' + ' The format is closest to ZIP.\n' +
'* szippdf: Generate a file valid as ZIP and PDF.' + '* szippdf: Generate a file valid as ZIP and PDF.' +
' The format is strictly a ZIP.' + ' The format is strictly a ZIP.' +
' Archive is modified.') ' Archive is modified.\n' +
'* pdfraw: Generate a file strictly valid as a PDF ' +
'with a custom first object content.')
usage_str = '%(prog)s format [options] output-file' usage_str = '%(prog)s format [options] output-file'
epilog_str = 'TruePolyglot v1.3' epilog_str = 'TruePolyglot v1.5.1'
frm = argparse.RawTextHelpFormatter frm = argparse.RawTextHelpFormatter
parser = argparse.ArgumentParser(description=description_str, parser = argparse.ArgumentParser(description=description_str,
epilog=epilog_str, epilog=epilog_str,
@@ -27,14 +32,21 @@ def main():
formatter_class=frm) formatter_class=frm)
parser.add_argument('format', nargs='+', choices=["pdfzip", parser.add_argument('format', nargs='+', choices=["pdfzip",
"zippdf", "zippdf",
"szippdf"], "szippdf",
"pdfraw"],
help='Output polyglot format') help='Output polyglot format')
parser.add_argument('--pdffile', dest='pdffile', parser.add_argument('--pdffile', dest='pdffile',
help='PDF input file') help='PDF input file')
parser.add_argument('--zipfile', dest='zipfile', parser.add_argument('--zipfile', dest='zipfile',
help='ZIP input file') help='ZIP input file')
parser.add_argument('--rawfile', dest='rawfile',
help='RAW input file')
parser.add_argument('--acrobat-compatibility',
dest='acrobat_compatibility',
help='Add a byte at start for Acrobat Reader compatibility with szippdf format',
action='store_true')
parser.add_argument('--verbose', dest='verbose', parser.add_argument('--verbose', dest='verbose',
help='Verbosity level (default: debug)', help='Verbosity level (default: info)',
default="info", default="info",
choices=["none", "error", "info", "debug"]) choices=["none", "error", "info", "debug"])
parser.add_argument('output_file', nargs='+', parser.add_argument('output_file', nargs='+',
@@ -42,12 +54,14 @@ def main():
args = parser.parse_args() args = parser.parse_args()
formats = ["pdfzip", "zippdf", "szippdf"] if args.acrobat_compatibility and args.format[0] != "szippdf":
if args.format[0] in formats: parser.error('--acrobat-compatibility is for szippdf only')
if args.pdffile is None: if "pdf" in args.format[0] and args.pdffile is None:
parser.error('pdffile is required') parser.error('pdffile is required')
if args.zipfile is None: if "zip" in args.format[0] and args.zipfile is None:
parser.error('zipfile is required') parser.error('zipfile is required')
if "raw" in args.format[0] and args.rawfile is None:
parser.error('rawfile is required')
if args.verbose == "none": if args.verbose == "none":
logging.basicConfig(level=logging.CRITICAL) logging.basicConfig(level=logging.CRITICAL)
@@ -58,14 +72,22 @@ def main():
if args.verbose == "debug": if args.verbose == "debug":
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
p = Pdf(args.pdffile)
z = Zip(args.zipfile)
if args.format[0] == "pdfzip": if args.format[0] == "pdfzip":
p = Pdf(args.pdffile)
z = Zip(args.zipfile)
a = PolyglotPdfZip(p, z) a = PolyglotPdfZip(p, z)
if args.format[0] == "zippdf": if args.format[0] == "zippdf":
p = Pdf(args.pdffile)
z = Zip(args.zipfile)
a = PolyglotZipPdf(p, z) a = PolyglotZipPdf(p, z)
if args.format[0] == "szippdf": if args.format[0] == "szippdf":
a = PolyglotSZipPdf(p, z) p = Pdf(args.pdffile)
z = Zip(args.zipfile)
a = PolyglotSZipPdf(p, z, args.acrobat_compatibility)
if args.format[0] == "pdfraw":
p = Pdf(args.pdffile)
a = PolyglotPdfRaw(p, args.rawfile)
a.generate() a.generate()
a.write(args.output_file[0]) a.write(args.output_file[0])

View File

@@ -1,63 +0,0 @@
html {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
body {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
td {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
th {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
h1 {
color: white;
}
a:link {
color: #47B8C7;
}
a:visited {
color: #47B8C7;
}
a:active {
color: #47B8C7;
}
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid white;
}
th {
background-color: #92D050;
color: black;
}
th {
padding-left: 0.5em;
padding-right: 0.5em;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
td {
padding-left: 0.5em;
padding-right: 0.5em;
padding-bottom: 0.5em;
padding-top: 0.5em;
text-align: left;
}
.font_reduce {
font-size: 75%;
}
.warning {
color: #ffb833;
}

View File

@@ -1,61 +0,0 @@
html {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
body {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
td {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
th {
background-color: black;
font-family: Consolas,monaco,monospace;
color: #92D050;
}
a:link {
color: #47B8C7;
}
a:visited {
color: #47B8C7;
}
a:active {
color: #47B8C7;
}
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid white;
}
th {
background-color: #92D050;
color: black;
}
th {
padding-left: 0.5em;
padding-right: 0.5em;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
td {
padding-left: 0.5em;
padding-right: 0.5em;
padding-bottom: 0.5em;
padding-top: 0.5em;
text-align: left;
}
th a:link {
color: black;
}
th a:visited {
color: black;
}
th a:active {
color: black;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

View File

@@ -1,21 +0,0 @@
#!/bin/bash
find -type f -name 'polyglot.pdf' -delete
mkdir -p ./samples/pdfzip/poc1/
../truepolyglot pdfzip --pdffile ./samples/pdfzip/poc1/doc.pdf --zipfile ./samples/pdfzip/poc1/archive.zip ./samples/pdfzip/poc1/polyglot.pdf
mkdir -p ./samples/pdfzip/poc2/
../truepolyglot pdfzip --pdffile ./samples/pdfzip/poc2/orwell_1984.pdf --zipfile ./samples/pdfzip/poc2/file-FILE5_32.zip ./samples/pdfzip/poc2/polyglot.pdf
mkdir -p ./samples/pdfzip/poc3/
../truepolyglot pdfzip --pdffile ./samples/pdfzip/poc3/x86asm.pdf --zipfile ./samples/pdfzip/poc3/fasmw17304.zip ./samples/pdfzip/poc3/polyglot.pdf
mkdir -p ./samples/zippdf/poc4/
../truepolyglot zippdf --pdffile ./samples/zippdf/poc4/doc.pdf --zipfile ./samples/zippdf/poc4/archive.zip ./samples/zippdf/poc4/polyglot.pdf
mkdir -p ./samples/szippdf/poc5/
../truepolyglot szippdf --pdffile ./samples/szippdf/poc5/electronics.pdf --zipfile ./samples/szippdf/poc5/hello_world.jar ./samples/szippdf/poc5/polyglot.pdf
mkdir -p ./samples/pdfzip/poc6/
../truepolyglot pdfzip --pdffile ./samples/pdfzip/poc6/hexinator.pdf --zipfile ./samples/pdfzip/poc6/eicar.zip ./samples/pdfzip/poc6/polyglot.pdf

View File

@@ -1,251 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>TruePolyglot</title>
<meta name="description" content="TruePolyglot project website">
<meta name="author" content="hackade">
<link rel="stylesheet" href="css/styles.css">
<link rel="shortcut icon" href="/favicon.ico">
</head>
<body>
<h1>TruePolyglot</h1>
Truepolyglot is polyglot file generator project.
This means that the generated file is composed of several file formats. The same file can be opened as a ZIP file and as a PDF file for example.
The idea of this project comes from work of <a href="https://github.com/corkami">Ange Albertini</a>, <a href="https://www.alchemistowl.org/pocorgtfo/pocorgtfo07.pdf">International Journal of Proof-of-Concept or Get The Fuck Out</a> and <a href="https://www.troopers.de/wp-content/uploads/2011/04/TR11_Wolf_OMG_PDF.pdf">Julia Wolf</a> that explain how we can build a polyglot file.<br>
Polyglot file can be fastidious to build, even more if you want to respect correctly file format. That's why I decided to build a tool to generate them.<br>
My main motivation was the technical challenge.
<br>
<h2>Features and changelog</h2>
<div class="font_reduce">
<table>
<tr>
<th>Description</th>
<th>Version</th>
</tr>
<tr>
<td>Build a polyglot file valid as PDF and ZIP format and that can be opened with 7Zip and Windows Explorer</td>
<td>POC</td>
</tr>
<tr>
<td>Add a stream object in PDF part</td>
<td>POC</td>
</tr>
<tr>
<td>Polyglot file checked without warning with <a href="https://poppler.freedesktop.org/">pdftocairo</a></td>
<td> &gt;= 1.0</td>
</tr>
<tr>
<td>Polyglot file checked without warning with <a href="https://github.com/ANSSI-FR/caradoc">caradoc</a></td>
<td> &gt;= 1.0</td>
</tr>
<tr>
<td>Rebuild PDF Xref Table</td>
<td>&gt;= 1.0</td>
</tr>
<tr>
<td>Stream object with correct length header value</td>
<td>&gt;= 1.0</td>
</tr>
<tr>
<td>Format "zippdf", file without offset after Zip data</td>
<td>&gt;= 1.1</td>
</tr>
<tr>
<td>Polyglot file keep original PDF version</td>
<td>&gt;= 1.1.1</td>
</tr>
<tr>
<td>Add "szippdf" format without offset before and after Zip data</td>
<td>&gt;= 1.2</td>
</tr>
<tr>
<td>Fix /Length stream object value and PDF offset for szippdf format</td>
<td>&gt;= 1.2.1</td>
</tr>
<tr>
<td>PDF object numbers reorder after insertion</td>
<td>&gt;= 1.3</td>
</tr>
</table>
</div>
<h2>Polyglot file compatibility</h2>
<div class="font_reduce">
<table>
<tr>
<th>Software</th>
<th>Formats</th>
<th>status</th>
</tr>
<tr>
<td>Acrobat Reader</td>
<td>pdfzip, zippdf</td>
<td>OK</td>
</tr>
<tr>
<td>Acrobat Reader</td>
<td>szippdf</td>
<td><span class="warning">KO</span></td>
</tr>
<tr>
<td>Sumatra PDF</td>
<td>pdfzip, zippdf, szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>Edge</td>
<td>pdfzip, zippdf, szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>Firefox</td>
<td>pdfzip, zippdf, szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>7zip</td>
<td>pdfzip, zippdf</td>
<td><span class="warning">OK with warning</span></td>
</tr>
<tr>
<td>7zip</td>
<td>szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>Explorer Windows</td>
<td>pdfzip, zippdf, szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>Info-ZIP (unzip)</td>
<td>pdfzip, zippdf, szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>Evince</td>
<td>pdfzip, zippdf, szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>pdftocairo -pdf</td>
<td>pdfzip, zippdf, szippdf</td>
<td>OK</td>
</tr>
<tr>
<td>caradoc stats</td>
<td>pdfzip</td>
<td>OK</td>
</tr>
<tr>
<td>java</td>
<td>szippdf</td>
<td>OK</td>
</tr>
</table>
</div>
<h2>Examples</h2>
<ul>
<li><a href="/samples/">Polyglot files repository</a></li>
</ul>
<div class="font_reduce">
<table>
<tr>
<th>PDF input file</th>
<th>Zip input file</th>
<th>Format</th>
<th>Polyglot</th>
<th>Comment</th>
</tr>
<tr>
<td><a href="/samples/pdfzip/poc1/doc.pdf">doc.pdf</a></td>
<td><a href="/samples/pdfzip/poc1/archive.zip">archive.zip</a></td>
<td>pdfzip</td>
<td><a href="/samples/pdfzip/poc1/polyglot.pdf">polyglot.pdf</a></td>
<td>PDF/ZIP polyglot - 122 Ko</td>
</tr>
<tr>
<td><a href="/samples/pdfzip/poc2/orwell_1984.pdf">orwell_1984.pdf</a></td>
<td><a href="/samples/pdfzip/poc2/file-FILE5_32.zip">file-FILE5_32.zip</a></td>
<td>pdfzip</td>
<td><a href="/samples/pdfzip/poc2/polyglot.pdf">polyglot.pdf</a></td>
<td>PDF/ZIP polyglot - 1.3 Mo</td>
</tr>
<tr>
<td><a href="/samples/pdfzip/poc3/x86asm.pdf">x86asm.pdf</a></td>
<td><a href="/samples/pdfzip/poc3/fasmw17304.zip">fasmw17304.zip</a></td>
<td>pdfzip</td>
<td><a href="/samples/pdfzip/poc3/polyglot.pdf">polyglot.pdf</a></td>
<td>PDF/ZIP polyglot - 1.8 Mo</td>
</tr>
<tr>
<td><a href="/samples/zippdf/poc4/doc.pdf">doc.pdf</a></td>
<td><a href="/samples/zippdf/poc4/archive.zip">archive.zip</a></td>
<td>zippdf</td>
<td><a href="/samples/zippdf/poc4/polyglot.pdf">polyglot.pdf</a></td>
<td>PDF/ZIP polyglot - 112 Ko</td>
</tr>
<tr>
<td><a href="/samples/szippdf/poc5/electronics.pdf">electronics.pdf</a></td>
<td><a href="/samples/szippdf/poc5/hello_world.jar">hello_world.jar</a></td>
<td>szippdf</td>
<td><a href="/samples/szippdf/poc5/polyglot.pdf">polyglot.pdf</a></td>
<td>PDF/JAR polyglot - 778 Ko</td>
</tr>
<tr>
<td><a href="/samples/pdfzip/poc6/hexinator.pdf">hexinator.pdf</a></td>
<td><a href="/samples/pdfzip/poc6/eicar.zip">eicar.zip</a>&nbsp;(<a href="https://www.virustotal.com/#/file/2174e17e6b03bb398666c128e6ab0a27d4ad6f7d7922127fe828e07aa94ab79d/detection">scan virustotal.com</a>)</td>
<td>pdfzip</td>
<td><a href="/samples/pdfzip/poc6/polyglot.pdf">polyglot.pdf</a>&nbsp;(<a href="https://www.virustotal.com/#/file/f6fef31e3b03164bb3bdf35af0521f9fc0c518a9e0f1aa9f8b60ac936201591a/detection">scan virustotal.com</a>)</td>
<td>PDF/ZIP polyglot with Eicar test in Zip - 2.9 Mo</td>
</tr>
</table>
</div>
<h2>Manual</h2>
<pre>
usage: truepolyglot format [options] output-file
Generate a polyglot file.
Formats availables:
* pdfzip: Generate a file valid as PDF and ZIP. The format is closest to PDF.
* zippdf: Generate a file valid as ZIP and PDF. The format is closest to ZIP.
* szippdf: Generate a file valid as ZIP and PDF. The format is strictly a ZIP. Archive is modified.
positional arguments:
{pdfzip,zippdf,szippdf}
Output polyglot format
output_file Output polyglot file path
optional arguments:
-h, --help show this help message and exit
--pdffile PDFFILE PDF input file
--zipfile ZIPFILE ZIP input file
--verbose {none,error,info,debug}
Verbosity level (default: info)
TruePolyglot v1.3
</pre>
<h2>Code</h2>
<pre>
git clone <a href="https://git.hackade.org/truepolyglot.git/">https://git.hackade.org/truepolyglot.git/</a>
</pre>
<h2>Contact</h2>
On <a href="https://webchat.freenode.net/">IRC Freenode</a> my nickname is hackade or by mail at <a href="mailtp:truepolyglot@hackade.org">truepolyglot@hackade.org</a>.
</body>
</html>

View File

@@ -1,2 +0,0 @@
User-agent: *
Disallow: /

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +0,0 @@
#!/bin/bash
echo "http://127.0.0.1:8000"
python -m SimpleHTTPServer 8000

View File

@@ -1,2 +0,0 @@
#!/bin/bash
rsync -av --progress ./ -e ssh dragon:/var/www/html/truepolyglot/