origami 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -8
- data/bin/pdf2ruby +8 -8
- data/bin/pdfcop +13 -13
- data/bin/pdfmetadata +4 -4
- data/bin/shell/.irbrc +1 -1
- data/bin/shell/console.rb +18 -18
- data/bin/shell/hexdump.rb +1 -1
- data/origami/dictionary.rb +2 -2
- data/origami/header.rb +1 -1
- data/origami/parser.rb +67 -63
- data/origami/pdf.rb +5 -5
- data/origami/stream.rb +4 -4
- metadata +76 -87
- data/origami/docmdp.rb +0 -96
data/README
CHANGED
@@ -25,13 +25,13 @@ See the COPYING.LESSER file for more details.
|
|
25
25
|
:: RELEASE
|
26
26
|
==========
|
27
27
|
|
28
|
-
- Current : Version 1.0.
|
28
|
+
- Current : Version 1.0.3
|
29
29
|
|
30
30
|
|
31
31
|
:: DEPENDENCIES
|
32
32
|
===============
|
33
33
|
|
34
|
-
- Ruby 1.8 (actually not tested on 1.9)
|
34
|
+
- Ruby 1.8 (actually not very tested on 1.9)
|
35
35
|
- Ruby-GTK2 (only for GUI), http://ruby-gnome2.sourceforge.jp/
|
36
36
|
|
37
37
|
|
@@ -42,13 +42,10 @@ See the COPYING.LESSER file for more details.
|
|
42
42
|
* Core scripts used to parse a PDF file. All objects and features are
|
43
43
|
provided here.
|
44
44
|
|
45
|
-
``walker/``
|
46
|
-
* An unfinished GTK interface to analyze a PDF.
|
47
|
-
|
48
45
|
``samples/``
|
49
46
|
* Many samples, mostly sorted to generate specially crafted PDFs.
|
50
47
|
|
51
|
-
``
|
48
|
+
``bin/``
|
52
49
|
* Useful tools based on Origami.
|
53
50
|
|
54
51
|
``tests/``
|
@@ -68,8 +65,7 @@ Frédéric Raynal <fred@security-labs.org> - Contributor
|
|
68
65
|
:: NOTES
|
69
66
|
========
|
70
67
|
|
71
|
-
|
72
|
-
features. If you encounter a problem, feel free to report it by mail at
|
68
|
+
If you encounter a problem, feel free to report it by mail at
|
73
69
|
<guillaume [at] security-labs [dot] org>, with a short explanation of
|
74
70
|
what you did and any necessary PDF documents.
|
75
71
|
|
data/bin/pdf2ruby
CHANGED
@@ -100,8 +100,8 @@ def objectToRuby(obj, inclevel = 0, internalname = nil, do_convert = false)
|
|
100
100
|
"'#{obj.value.gsub("'","\\\\'")}'"
|
101
101
|
when Origami::Dictionary
|
102
102
|
customtype = nil
|
103
|
-
if obj[:Type] and
|
104
|
-
customtype =
|
103
|
+
if obj[:Type] and Origami::DICT_SPECIAL_TYPES.include?(obj[:Type].value)
|
104
|
+
customtype = Origami::DICT_SPECIAL_TYPES[obj[:Type].value]
|
105
105
|
end
|
106
106
|
dictionaryToRuby(obj, inclevel, internalname, customtype)
|
107
107
|
when Origami::Array
|
@@ -259,11 +259,11 @@ def streamToRuby(stm, internalname)
|
|
259
259
|
code
|
260
260
|
end
|
261
261
|
|
262
|
-
colorprint "[*] ", Colors::RED
|
262
|
+
Console.colorprint "[*] ", Console::Colors::RED
|
263
263
|
puts "Loading document '#{TARGET}'"
|
264
264
|
verbosity = @options[:verbose] ? Parser::VERBOSE_INSANE : Parser::VERBOSE_QUIET
|
265
265
|
target = PDF.read(TARGET, :verbosity => verbosity)
|
266
|
-
colorprint "[*] ", Colors::RED
|
266
|
+
Console.colorprint "[*] ", Console::Colors::RED
|
267
267
|
puts "Document successfully loaded into Origami"
|
268
268
|
|
269
269
|
Dir::mkdir(TARGET_DIR) unless File.directory? TARGET_DIR
|
@@ -295,7 +295,7 @@ OUTPUT = "\#{File.basename(__FILE__, '.rb')}.pdf"
|
|
295
295
|
|
296
296
|
RUBY
|
297
297
|
|
298
|
-
colorprint "[*] ", Colors::RED
|
298
|
+
Console.colorprint "[*] ", Console::Colors::RED
|
299
299
|
puts "Retrieving all indirect objects..."
|
300
300
|
roots = target.root_objects
|
301
301
|
roots.each do |obj|
|
@@ -303,14 +303,14 @@ roots.each do |obj|
|
|
303
303
|
@var_hash[obj.reference] = varname
|
304
304
|
end
|
305
305
|
|
306
|
-
colorprint "[*] ", Colors::RED
|
306
|
+
Console.colorprint "[*] ", Console::Colors::RED
|
307
307
|
puts "Retrieving the document Catalog..."
|
308
308
|
catalog = target.Catalog
|
309
309
|
|
310
310
|
@var_hash[catalog.reference] = "#{DOCREF}.Catalog"
|
311
311
|
@obj_route.push "#{DOCREF}.Catalog"
|
312
312
|
|
313
|
-
colorprint "[*] ", Colors::RED
|
313
|
+
Console.colorprint "[*] ", Console::Colors::RED
|
314
314
|
puts "Processing the object hierarchy..."
|
315
315
|
@current_idx = 0
|
316
316
|
while @current_idx != @obj_route.size
|
@@ -346,7 +346,7 @@ fd.puts <<RUBY
|
|
346
346
|
|
347
347
|
RUBY
|
348
348
|
|
349
|
-
colorprint "[*] ", Colors::RED
|
349
|
+
Console.colorprint "[*] ", Console::Colors::RED
|
350
350
|
puts "Successfully generated script '#{TARGET_FILE}'"
|
351
351
|
fd.close
|
352
352
|
exit
|
data/bin/pdfcop
CHANGED
@@ -115,10 +115,10 @@ else
|
|
115
115
|
TARGET = ARGV.shift
|
116
116
|
end
|
117
117
|
|
118
|
-
def log(str, color = Colors::GREY)
|
118
|
+
def log(str, color = Console::Colors::GREY)
|
119
119
|
if @options[:colors]
|
120
|
-
colorprint("[#{Time.now}] ", Colors::CYAN, LOGGER)
|
121
|
-
colorprint(str, color, LOGGER)
|
120
|
+
Console.colorprint("[#{Time.now}] ", Console::Colors::CYAN, LOGGER)
|
121
|
+
Console.colorprint(str, color, LOGGER)
|
122
122
|
else
|
123
123
|
LOGGER.print("[#{Time.now}] #{str}")
|
124
124
|
end
|
@@ -331,22 +331,22 @@ def analyze_action(action, triggered_at_opening, level = 0)
|
|
331
331
|
end
|
332
332
|
|
333
333
|
begin
|
334
|
-
log("PDFcop is running on target `#{TARGET}', policy = `#{@options[:policy]}'", Colors::GREEN)
|
335
|
-
log(" File size: #{File.size(TARGET)} bytes", Colors::MAGENTA)
|
336
|
-
log(" MD5: #{Digest::MD5.hexdigest(File.read(TARGET))}", Colors::MAGENTA)
|
334
|
+
log("PDFcop is running on target `#{TARGET}', policy = `#{@options[:policy]}'", Console::Colors::GREEN)
|
335
|
+
log(" File size: #{File.size(TARGET)} bytes", Console::Colors::MAGENTA)
|
336
|
+
log(" MD5: #{Digest::MD5.hexdigest(File.read(TARGET))}", Console::Colors::MAGENTA)
|
337
337
|
|
338
338
|
@pdf = PDF.read(TARGET,
|
339
339
|
:verbosity => Parser::VERBOSE_QUIET,
|
340
340
|
:ignore_errors => SECURITY_POLICIES["POLICY_#{@options[:policy].upcase}"]['allowParserErrors']
|
341
341
|
)
|
342
342
|
|
343
|
-
log("> Inspecting document structure...", Colors::YELLOW)
|
343
|
+
log("> Inspecting document structure...", Console::Colors::YELLOW)
|
344
344
|
if @pdf.is_encrypted?
|
345
345
|
log(" . Encryption = YES")
|
346
346
|
check_rights(:allowEncryption)
|
347
347
|
end
|
348
348
|
|
349
|
-
log("> Inspecting document catalog...", Colors::YELLOW)
|
349
|
+
log("> Inspecting document catalog...", Console::Colors::YELLOW)
|
350
350
|
catalog = @pdf.Catalog
|
351
351
|
reject("Invalid document catalog") unless catalog.is_a?(Catalog)
|
352
352
|
|
@@ -383,23 +383,23 @@ begin
|
|
383
383
|
end
|
384
384
|
end
|
385
385
|
|
386
|
-
log("> Inspecting JavaScript names directory...", Colors::YELLOW)
|
386
|
+
log("> Inspecting JavaScript names directory...", Console::Colors::YELLOW)
|
387
387
|
unless @pdf.ls_names(Names::Root::JAVASCRIPT).empty?
|
388
388
|
check_rights(:allowJS)
|
389
389
|
check_rights(:allowJSAtOpening)
|
390
390
|
end
|
391
391
|
|
392
|
-
log("> Inspecting attachment names directory...", Colors::YELLOW)
|
392
|
+
log("> Inspecting attachment names directory...", Console::Colors::YELLOW)
|
393
393
|
unless @pdf.ls_names(Names::Root::EMBEDDEDFILES).empty?
|
394
394
|
check_rights(:allowAttachments)
|
395
395
|
end
|
396
396
|
|
397
|
-
log("> Inspecting document pages...", Colors::YELLOW)
|
397
|
+
log("> Inspecting document pages...", Console::Colors::YELLOW)
|
398
398
|
@pdf.each_page do |page|
|
399
399
|
analyze_page(page, 1)
|
400
400
|
end
|
401
401
|
|
402
|
-
log("> Inspecting document streams...", Colors::YELLOW)
|
402
|
+
log("> Inspecting document streams...", Console::Colors::YELLOW)
|
403
403
|
@pdf.indirect_objects.find_all{|obj| obj.is_a?(Stream)}.each do |stream|
|
404
404
|
if stream.dictionary.has_key?(:Filter)
|
405
405
|
filters = stream.Filter
|
@@ -443,7 +443,7 @@ begin
|
|
443
443
|
# ...
|
444
444
|
#
|
445
445
|
|
446
|
-
log("Document accepted by policy `#{@options[:policy]}'.", Colors::GREEN)
|
446
|
+
log("Document accepted by policy `#{@options[:policy]}'.", Console::Colors::GREEN)
|
447
447
|
|
448
448
|
rescue SystemExit
|
449
449
|
rescue Exception => e
|
data/bin/pdfmetadata
CHANGED
@@ -92,11 +92,11 @@ begin
|
|
92
92
|
|
93
93
|
if @options[:doc_info]
|
94
94
|
if pdf.has_document_info?
|
95
|
-
colorprint "[*] Document information dictionary:\n", Colors::MAGENTA
|
95
|
+
Console.colorprint "[*] Document information dictionary:\n", Console::Colors::MAGENTA
|
96
96
|
|
97
97
|
docinfo = pdf.get_document_info
|
98
98
|
docinfo.each_pair do |name, item|
|
99
|
-
colorprint name.value.to_s.ljust(20, ' '), Colors::GREEN
|
99
|
+
Console.colorprint name.value.to_s.ljust(20, ' '), Console::Colors::GREEN
|
100
100
|
puts ": #{item.solve.value}"
|
101
101
|
end
|
102
102
|
puts
|
@@ -105,11 +105,11 @@ begin
|
|
105
105
|
|
106
106
|
if @options[:doc_stream]
|
107
107
|
if pdf.has_metadata?
|
108
|
-
colorprint "[*] Metadata stream:\n", Colors::MAGENTA
|
108
|
+
Console.colorprint "[*] Metadata stream:\n", Console::Colors::MAGENTA
|
109
109
|
|
110
110
|
metadata = pdf.get_metadata
|
111
111
|
metadata.each_pair do |name, item|
|
112
|
-
colorprint name.ljust(20, ' '), Colors::GREEN
|
112
|
+
Console.colorprint name.ljust(20, ' '), Console::Colors::GREEN
|
113
113
|
puts ": #{item}"
|
114
114
|
end
|
115
115
|
end
|
data/bin/shell/.irbrc
CHANGED
data/bin/shell/console.rb
CHANGED
@@ -74,10 +74,10 @@ module Origami
|
|
74
74
|
|
75
75
|
class Revision
|
76
76
|
def to_s
|
77
|
-
colorprint("---------- Body ----------\n", Colors::WHITE, true)
|
77
|
+
Console.colorprint("---------- Body ----------\n", Console::Colors::WHITE, true)
|
78
78
|
@body.each_value { |obj|
|
79
|
-
colorprint("#{obj.reference.to_s.rjust(8,' ')}".ljust(10), Colors::MAGENTA)
|
80
|
-
colorprint("#{obj.type}\n", Colors::YELLOW)
|
79
|
+
Console.colorprint("#{obj.reference.to_s.rjust(8,' ')}".ljust(10), Console::Colors::MAGENTA)
|
80
|
+
Console.colorprint("#{obj.type}\n", Console::Colors::YELLOW)
|
81
81
|
}
|
82
82
|
#colorprint("---------- Xrefs -----------\n", Colors::BRIGHT_WHITE, true)
|
83
83
|
#set_fg_color(Colors::BLUE, true) {
|
@@ -89,20 +89,20 @@ module Origami
|
|
89
89
|
# }
|
90
90
|
# end
|
91
91
|
#}
|
92
|
-
colorprint("---------- Trailer ---------\n", Colors::WHITE, true)
|
92
|
+
Console.colorprint("---------- Trailer ---------\n", Console::Colors::WHITE, true)
|
93
93
|
if not @trailer.dictionary
|
94
|
-
set_fg_color(Colors::BLUE, true) {
|
94
|
+
Console.set_fg_color(Console::Colors::BLUE, true) {
|
95
95
|
puts " [x] No trailer found."
|
96
96
|
}
|
97
97
|
else
|
98
98
|
@trailer.dictionary.each_pair { |entry, value|
|
99
|
-
colorprint(" [*] ", Colors::MAGENTA)
|
100
|
-
colorprint("#{entry.to_s}: ", Colors::YELLOW)
|
101
|
-
colorprint("#{value.to_s}\n", Colors::RED)
|
99
|
+
Console.colorprint(" [*] ", Console::Colors::MAGENTA)
|
100
|
+
Console.colorprint("#{entry.to_s}: ", Console::Colors::YELLOW)
|
101
|
+
Console.colorprint("#{value.to_s}\n", Console::Colors::RED)
|
102
102
|
}
|
103
|
-
colorprint(" [+] ", Colors::MAGENTA)
|
104
|
-
colorprint("startxref: ", Colors::YELLOW)
|
105
|
-
colorprint("#{@trailer.startxref}\n", Colors::RED)
|
103
|
+
Console.colorprint(" [+] ", Console::Colors::MAGENTA)
|
104
|
+
Console.colorprint("startxref: ", Console::Colors::YELLOW)
|
105
|
+
Console.colorprint("#{@trailer.startxref}\n", Console::Colors::RED)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -114,13 +114,13 @@ module Origami
|
|
114
114
|
def to_s
|
115
115
|
puts
|
116
116
|
|
117
|
-
colorprint("---------- Header ----------\n", Colors::WHITE, true)
|
118
|
-
colorprint(" [+] ", Colors::MAGENTA)
|
119
|
-
colorprint("Major version: ", Colors::YELLOW)
|
120
|
-
colorprint("#{@header.majorversion}\n", Colors::RED)
|
121
|
-
colorprint(" [+] ", Colors::MAGENTA)
|
122
|
-
colorprint("Minor version: ", Colors::YELLOW)
|
123
|
-
colorprint("#{@header.minorversion}\n", Colors::RED)
|
117
|
+
Console.colorprint("---------- Header ----------\n", Console::Colors::WHITE, true)
|
118
|
+
Console.colorprint(" [+] ", Console::Colors::MAGENTA)
|
119
|
+
Console.colorprint("Major version: ", Console::Colors::YELLOW)
|
120
|
+
Console.colorprint("#{@header.majorversion}\n", Console::Colors::RED)
|
121
|
+
Console.colorprint(" [+] ", Console::Colors::MAGENTA)
|
122
|
+
Console.colorprint("Minor version: ", Console::Colors::YELLOW)
|
123
|
+
Console.colorprint("#{@header.minorversion}\n", Console::Colors::RED)
|
124
124
|
|
125
125
|
@revisions.each { |revision|
|
126
126
|
revision.to_s
|
data/bin/shell/hexdump.rb
CHANGED
@@ -61,7 +61,7 @@ class String #:nodoc:
|
|
61
61
|
if RUBY_PLATFORM =~ /win32/
|
62
62
|
dump << "#{offset if offsets} #{bytes.to_s.ljust(bytesperline * 3 - 1)} #{ascii}\n"
|
63
63
|
else
|
64
|
-
dump << "#{
|
64
|
+
dump << "#{Console.colorize(offset, Console::Colors::YELLOW) if offsets} #{Console.colorize(bytes.to_s.ljust(bytesperline * 3 - 1), Console::Colors::BRIGHT_GREY)} #{ascii}\n"
|
65
65
|
end
|
66
66
|
|
67
67
|
counter += bytesperline
|
data/origami/dictionary.rb
CHANGED
@@ -100,8 +100,8 @@ module Origami
|
|
100
100
|
dict =
|
101
101
|
if Origami::OPTIONS[:enable_type_guessing]
|
102
102
|
type = pairs[Name.new(:Type)]
|
103
|
-
if type.is_a?(Name) and
|
104
|
-
|
103
|
+
if type.is_a?(Name) and DICT_SPECIAL_TYPES.include?(type.value)
|
104
|
+
DICT_SPECIAL_TYPES[type.value].new(pairs)
|
105
105
|
else
|
106
106
|
Dictionary.new(pairs)
|
107
107
|
end
|
data/origami/header.rb
CHANGED
@@ -50,7 +50,7 @@ module Origami
|
|
50
50
|
def initialize(majorversion = 1, minorversion = 4)
|
51
51
|
|
52
52
|
#if majorversion.to_i != 1 || ! ((MINVERSION..MAXVERSION) === minorversion.to_i)
|
53
|
-
# colorprint("[info ] Warning: Invalid file version : #{majorversion}.#{minorversion}\n", Colors::YELLOW, false, STDERR)
|
53
|
+
# Console.colorprint("[info ] Warning: Invalid file version : #{majorversion}.#{minorversion}\n", Console::Colors::YELLOW, false, STDERR)
|
54
54
|
#end
|
55
55
|
|
56
56
|
@majorversion, @minorversion = majorversion, minorversion
|
data/origami/parser.rb
CHANGED
@@ -22,73 +22,77 @@
|
|
22
22
|
require 'strscan'
|
23
23
|
|
24
24
|
module Origami
|
25
|
+
|
26
|
+
module Console
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
if RUBY_PLATFORM =~ /win32/ or RUBY_PLATFORM =~ /mingw32/
|
29
|
+
require "Win32API"
|
30
|
+
|
31
|
+
getStdHandle = Win32API.new("kernel32", "GetStdHandle", ['L'], 'L')
|
32
|
+
@@setConsoleTextAttribute = Win32API.new("kernel32", "SetConsoleTextAttribute", ['L', 'N'], 'I')
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
@@hOut = getStdHandle.call(-11)
|
35
|
+
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
37
|
+
module Colors #:nodoc;
|
38
|
+
if RUBY_PLATFORM =~ /win32/ or RUBY_PLATFORM =~ /mingw32/
|
39
|
+
BLACK = 0
|
40
|
+
BLUE = 1
|
41
|
+
GREEN = 2
|
42
|
+
CYAN = 3
|
43
|
+
RED = 4
|
44
|
+
MAGENTA = 5
|
45
|
+
YELLOW = 6
|
46
|
+
GREY = 7
|
47
|
+
WHITE = 8
|
48
|
+
else
|
49
|
+
GREY = '0;0'
|
50
|
+
BLACK = '0;30'
|
51
|
+
RED = '0;31'
|
52
|
+
GREEN = '0;32'
|
53
|
+
YELLOW = '0;33'
|
54
|
+
BLUE = '0;34'
|
55
|
+
MAGENTA = '0;35'
|
56
|
+
CYAN = '0;36'
|
57
|
+
WHITE = '0;37'
|
58
|
+
BRIGHT_GREY = '1;30'
|
59
|
+
BRIGHT_RED = '1;31'
|
60
|
+
BRIGHT_GREEN = '1;32'
|
61
|
+
BRIGHT_YELLOW = '1;33'
|
62
|
+
BRIGHT_BLUE = '1;34'
|
63
|
+
BRIGHT_MAGENTA = '1;35'
|
64
|
+
BRIGHT_CYAN = '1;36'
|
65
|
+
BRIGHT_WHITE = '1;37'
|
66
|
+
end
|
64
67
|
end
|
65
|
-
end
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
69
|
+
def self.set_fg_color(color, bright = false, fd = STDOUT) #:nodoc:
|
70
|
+
if RUBY_PLATFORM =~ /win32/ or RUBY_PLATFORM =~ /mingw32/
|
71
|
+
if bright then color |= Colors::WHITE end
|
72
|
+
@@setConsoleTextAttribute.call(@@hOut, color)
|
73
|
+
yield
|
74
|
+
@@setConsoleTextAttribute.call(@@hOut, Colors::GREY)
|
75
|
+
else
|
76
|
+
col, nocol = [color, Colors::GREY].map! { |key| "\033[#{key}m" }
|
77
|
+
fd << col
|
78
|
+
yield
|
79
|
+
fd << nocol
|
80
|
+
end
|
78
81
|
end
|
79
|
-
end
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
unless RUBY_PLATFORM =~ /win32/ or RUBY_PLATFORM =~ /mingw32/
|
84
|
+
def self.colorize(text, color, bright = false)
|
85
|
+
col, nocol = [color, Colors::GREY].map! { |key| "\033[#{key}m" }
|
86
|
+
"#{col}#{text}#{nocol}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.colorprint(text, color, bright = false, fd = STDOUT) #:nodoc:
|
91
|
+
set_fg_color(color, bright, fd) {
|
92
|
+
fd << text
|
93
|
+
}
|
85
94
|
end
|
86
|
-
end
|
87
95
|
|
88
|
-
def colorprint(text, color, bright = false, fd = STDOUT) #:nodoc:
|
89
|
-
set_fg_color(color, bright, fd) {
|
90
|
-
fd << text
|
91
|
-
}
|
92
96
|
end
|
93
97
|
|
94
98
|
EOL = "\r\n" #:nodoc:
|
@@ -245,23 +249,23 @@ module Origami
|
|
245
249
|
private
|
246
250
|
|
247
251
|
def error(str = "") #:nodoc:
|
248
|
-
colorprint("[error] #{str}\n", Colors::RED, false, STDERR)
|
252
|
+
Console.colorprint("[error] #{str}\n", Console::Colors::RED, false, STDERR)
|
249
253
|
end
|
250
254
|
|
251
255
|
def warn(str = "") #:nodoc:
|
252
|
-
colorprint("[info ] Warning: #{str}\n", Colors::YELLOW, false, STDERR) if @options[:verbosity] >= VERBOSE_INFO
|
256
|
+
Console.colorprint("[info ] Warning: #{str}\n", Console::Colors::YELLOW, false, STDERR) if @options[:verbosity] >= VERBOSE_INFO
|
253
257
|
end
|
254
258
|
|
255
259
|
def info(str = "") #:nodoc:
|
256
|
-
(colorprint("[info ] ", Colors::GREEN, false, STDERR); STDERR << "#{str}\n") if @options[:verbosity] >= VERBOSE_INFO
|
260
|
+
(Console.colorprint("[info ] ", Console::Colors::GREEN, false, STDERR); STDERR << "#{str}\n") if @options[:verbosity] >= VERBOSE_INFO
|
257
261
|
end
|
258
262
|
|
259
263
|
def debug(str = "") #:nodoc:
|
260
|
-
(colorprint("[debug] ", Colors::MAGENTA, false, STDERR); STDERR << "#{str}\n") if @options[:verbosity] >= VERBOSE_DEBUG
|
264
|
+
(Console.colorprint("[debug] ", Console::Colors::MAGENTA, false, STDERR); STDERR << "#{str}\n") if @options[:verbosity] >= VERBOSE_DEBUG
|
261
265
|
end
|
262
266
|
|
263
267
|
def trace(str = "") #:nodoc:
|
264
|
-
(colorprint("[trace] ", Colors::CYAN, false, STDERR); STDERR << "#{str}\n") if @options[:verbosity] >= VERBOSE_INSANE
|
268
|
+
(Console.colorprint("[trace] ", Console::Colors::CYAN, false, STDERR); STDERR << "#{str}\n") if @options[:verbosity] >= VERBOSE_INSANE
|
265
269
|
end
|
266
270
|
end
|
267
271
|
end
|
data/origami/pdf.rb
CHANGED
@@ -57,8 +57,8 @@ require 'origami/xfa'
|
|
57
57
|
|
58
58
|
module Origami
|
59
59
|
|
60
|
-
VERSION = "1.0.
|
61
|
-
REVISION = "$Revision
|
60
|
+
VERSION = "1.0.3"
|
61
|
+
REVISION = "$Revision$" #:nodoc:
|
62
62
|
|
63
63
|
#
|
64
64
|
# Global options for Origami.
|
@@ -77,7 +77,7 @@ module Origami
|
|
77
77
|
OPTIONS[:use_openssl] = false
|
78
78
|
end
|
79
79
|
|
80
|
-
|
80
|
+
DICT_SPECIAL_TYPES = #:nodoc:
|
81
81
|
{
|
82
82
|
:Catalog => Catalog,
|
83
83
|
:Pages => PageTreeNode,
|
@@ -110,7 +110,7 @@ module Origami
|
|
110
110
|
:CuePoint => Annotation::RichMedia::CuePoint
|
111
111
|
}
|
112
112
|
|
113
|
-
|
113
|
+
STM_SPECIAL_TYPES = #:nodoc:
|
114
114
|
{
|
115
115
|
:ObjStm => ObjectStream,
|
116
116
|
:EmbeddedFile => EmbeddedFileStream,
|
@@ -119,7 +119,7 @@ module Origami
|
|
119
119
|
:"3D" => U3DStream
|
120
120
|
}
|
121
121
|
|
122
|
-
|
122
|
+
STM_XOBJ_SUBTYPES = #:nodoc:
|
123
123
|
{
|
124
124
|
:Image => Graphics::ImageXObject,
|
125
125
|
:Form => Graphics::FormXObject
|
data/origami/stream.rb
CHANGED
@@ -123,11 +123,11 @@ module Origami
|
|
123
123
|
type, subtype = dictionary[:Type], dictionary[:Subtype]
|
124
124
|
|
125
125
|
if type.is_a?(Name)
|
126
|
-
if
|
127
|
-
|
126
|
+
if STM_SPECIAL_TYPES.include?(type.value)
|
127
|
+
STM_SPECIAL_TYPES[type.value].new("", dictionary.to_h)
|
128
128
|
else
|
129
|
-
if type == :XObject and subtype.is_a?(Name) and
|
130
|
-
|
129
|
+
if type == :XObject and subtype.is_a?(Name) and STM_XOBJ_SUBTYPES.include?(subtype.value)
|
130
|
+
STM_XOBJ_SUBTYPES[subtype.value].new("", dictionary.to_h)
|
131
131
|
else
|
132
132
|
Stream.new('', dictionary.to_h)
|
133
133
|
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origami
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 19
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 1
|
8
7
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
8
|
+
- 3
|
9
|
+
version: 1.0.3
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- "Guillaume Delugr\xC3\xA9"
|
@@ -15,20 +14,13 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-05-
|
17
|
+
date: 2011-05-31 00:00:00 +02:00
|
19
18
|
default_executable:
|
20
19
|
dependencies: []
|
21
20
|
|
22
21
|
description: |
|
23
|
-
|
22
|
+
Origami is a PDF-compliant parser. It is not a PDF rendering library, it aims at providing a scripting tool to generate and analyze malicious PDF files.
|
24
23
|
As well, it can be used to create on-the-fly customized PDFs, or to inject (evil) code into already existing documents.
|
25
|
-
|
26
|
-
- Create PDF documents from scratch.
|
27
|
-
- Parse existing documents, modify them and recompile them.
|
28
|
-
- Explore documents at the object level, going deep into the document structure, uncompressing PDF object streams and desobfuscating names and strings.
|
29
|
-
- High-level operations, such as encryption/decryption, signature, file attachments...
|
30
|
-
- A GTK interface to quickly browse into the document contents.
|
31
|
-
- A set of command-line tools for PDF analysis.
|
32
24
|
|
33
25
|
email: guillaume at security-labs dot org
|
34
26
|
executables:
|
@@ -52,111 +44,110 @@ files:
|
|
52
44
|
- COPYING.LESSER
|
53
45
|
- VERSION
|
54
46
|
- origami.rb
|
55
|
-
- origami/
|
47
|
+
- origami/adobe/fdf.rb
|
48
|
+
- origami/adobe/ppklite.rb
|
49
|
+
- origami/boolean.rb
|
50
|
+
- origami/signature.rb
|
51
|
+
- origami/export.rb
|
52
|
+
- origami/parser.rb
|
53
|
+
- origami/catalog.rb
|
54
|
+
- origami/header.rb
|
56
55
|
- origami/file.rb
|
56
|
+
- origami/linearization.rb
|
57
57
|
- origami/object.rb
|
58
|
-
- origami/
|
59
|
-
- origami/array.rb
|
60
|
-
- origami/filters/ccitt.rb
|
61
|
-
- origami/filters/predictors.rb
|
62
|
-
- origami/filters/jpx.rb
|
63
|
-
- origami/filters/flate.rb
|
64
|
-
- origami/filters/lzw.rb
|
65
|
-
- origami/filters/runlength.rb
|
66
|
-
- origami/filters/dct.rb
|
67
|
-
- origami/filters/ascii.rb
|
68
|
-
- origami/filters/jbig2.rb
|
69
|
-
- origami/filters/crypt.rb
|
70
|
-
- origami/acroform.rb
|
71
|
-
- origami/parser.rb
|
72
|
-
- origami/encryption.rb
|
73
|
-
- origami/xfa.rb
|
74
|
-
- origami/reference.rb
|
75
|
-
- origami/metadata.rb
|
76
|
-
- origami/stream.rb
|
58
|
+
- origami/3d.rb
|
77
59
|
- origami/actions.rb
|
78
|
-
- origami/
|
60
|
+
- origami/xreftable.rb
|
79
61
|
- origami/name.rb
|
62
|
+
- origami/graphics.rb
|
63
|
+
- origami/xfa.rb
|
64
|
+
- origami/graphics/xobject.rb
|
65
|
+
- origami/graphics/text.rb
|
66
|
+
- origami/graphics/patterns.rb
|
67
|
+
- origami/graphics/state.rb
|
68
|
+
- origami/graphics/colors.rb
|
69
|
+
- origami/graphics/path.rb
|
70
|
+
- origami/graphics/instruction.rb
|
71
|
+
- origami/destinations.rb
|
80
72
|
- origami/numeric.rb
|
81
|
-
- origami/
|
73
|
+
- origami/page.rb
|
74
|
+
- origami/annotations.rb
|
82
75
|
- origami/webcapture.rb
|
83
|
-
- origami/
|
76
|
+
- origami/parsers/fdf.rb
|
84
77
|
- origami/parsers/pdf/linear.rb
|
85
78
|
- origami/parsers/ppklite.rb
|
86
|
-
- origami/parsers/fdf.rb
|
87
79
|
- origami/parsers/pdf.rb
|
88
|
-
- origami/
|
89
|
-
- origami/
|
90
|
-
- origami/
|
91
|
-
- origami/
|
92
|
-
- origami/
|
93
|
-
- origami/graphics/xobject.rb
|
94
|
-
- origami/graphics/state.rb
|
95
|
-
- origami/graphics/patterns.rb
|
96
|
-
- origami/graphics/colors.rb
|
97
|
-
- origami/graphics/instruction.rb
|
98
|
-
- origami/graphics/path.rb
|
99
|
-
- origami/graphics/text.rb
|
100
|
-
- origami/trailer.rb
|
101
|
-
- origami/adobe/ppklite.rb
|
102
|
-
- origami/adobe/fdf.rb
|
80
|
+
- origami/encryption.rb
|
81
|
+
- origami/stream.rb
|
82
|
+
- origami/outline.rb
|
83
|
+
- origami/reference.rb
|
84
|
+
- origami/metadata.rb
|
103
85
|
- origami/font.rb
|
86
|
+
- origami/string.rb
|
104
87
|
- origami/null.rb
|
105
|
-
- origami/
|
88
|
+
- origami/trailer.rb
|
89
|
+
- origami/filters.rb
|
106
90
|
- origami/dictionary.rb
|
107
|
-
- origami/export.rb
|
108
|
-
- origami/xreftable.rb
|
109
|
-
- origami/linearization.rb
|
110
|
-
- origami/annotations.rb
|
111
|
-
- origami/boolean.rb
|
112
|
-
- origami/3d.rb
|
113
|
-
- origami/signature.rb
|
114
91
|
- origami/functions.rb
|
115
|
-
-
|
116
|
-
-
|
117
|
-
-
|
118
|
-
-
|
119
|
-
-
|
120
|
-
-
|
121
|
-
-
|
122
|
-
-
|
123
|
-
-
|
124
|
-
-
|
92
|
+
- origami/acroform.rb
|
93
|
+
- origami/filters/jbig2.rb
|
94
|
+
- origami/filters/predictors.rb
|
95
|
+
- origami/filters/jpx.rb
|
96
|
+
- origami/filters/ccitt.rb
|
97
|
+
- origami/filters/lzw.rb
|
98
|
+
- origami/filters/dct.rb
|
99
|
+
- origami/filters/crypt.rb
|
100
|
+
- origami/filters/ascii.rb
|
101
|
+
- origami/filters/runlength.rb
|
102
|
+
- origami/filters/flate.rb
|
103
|
+
- origami/array.rb
|
104
|
+
- origami/obfuscation.rb
|
105
|
+
- origami/pdf.rb
|
106
|
+
- bin/pdfencrypt
|
107
|
+
- bin/pdfdecompress
|
125
108
|
- bin/gui/imgview.rb
|
126
|
-
- bin/gui/
|
109
|
+
- bin/gui/hexdump.rb
|
110
|
+
- bin/gui/walker.rb
|
111
|
+
- bin/gui/file.rb
|
127
112
|
- bin/gui/treeview.rb
|
128
113
|
- bin/gui/hexview.rb
|
129
|
-
- bin/gui/
|
114
|
+
- bin/gui/signing.rb
|
115
|
+
- bin/gui/menu.rb
|
116
|
+
- bin/gui/about.rb
|
117
|
+
- bin/gui/properties.rb
|
118
|
+
- bin/gui/config.rb
|
119
|
+
- bin/gui/textview.rb
|
130
120
|
- bin/gui/xrefs.rb
|
131
|
-
- bin/
|
121
|
+
- bin/pdf2graph
|
122
|
+
- bin/pdfmetadata
|
132
123
|
- bin/pdfwalker
|
133
|
-
- bin/pdfdecrypt
|
134
|
-
- bin/config/pdfcop.conf.yml
|
135
|
-
- bin/pdfcop
|
136
124
|
- bin/pdfextract
|
137
|
-
- bin/pdfmetadata
|
138
|
-
- bin/pdfencrypt
|
139
125
|
- bin/pdf2ruby
|
126
|
+
- bin/pdfdecrypt
|
140
127
|
- bin/pdfcocoon
|
128
|
+
- bin/config/pdfcop.conf.yml
|
141
129
|
- bin/pdfsh
|
130
|
+
- bin/shell/hexdump.rb
|
131
|
+
- bin/shell/console.rb
|
132
|
+
- bin/pdfcop
|
142
133
|
- tests/tc_pdfsig.rb
|
143
|
-
- tests/tc_pdfnew.rb
|
144
|
-
- tests/tc_streams.rb
|
145
|
-
- tests/tc_pdfattach.rb
|
146
134
|
- tests/dataset/test.dummykey
|
147
135
|
- tests/dataset/test.dummycrt
|
148
|
-
- tests/
|
149
|
-
- tests/ts_pdf.rb
|
150
|
-
- tests/tc_pdfencrypt.rb
|
151
|
-
- tests/tc_pdfparse.rb
|
136
|
+
- tests/tc_streams.rb
|
152
137
|
- tests/tc_pages.rb
|
153
138
|
- tests/tc_annotations.rb
|
139
|
+
- tests/tc_pdfattach.rb
|
140
|
+
- tests/ts_pdf.rb
|
141
|
+
- tests/tc_pdfparse.rb
|
142
|
+
- tests/tc_pdfnew.rb
|
143
|
+
- tests/tc_pdfencrypt.rb
|
144
|
+
- tests/tc_actions.rb
|
154
145
|
- templates/xdp.rb
|
155
146
|
- templates/patterns.rb
|
156
147
|
- templates/widgets.rb
|
157
148
|
- bin/shell/.irbrc
|
158
149
|
has_rdoc: true
|
159
|
-
homepage: http://
|
150
|
+
homepage: http://esec-lab.sogeti.com/dotclear/index.php?pages/Origami
|
160
151
|
licenses: []
|
161
152
|
|
162
153
|
post_install_message:
|
@@ -169,7 +160,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
169
160
|
requirements:
|
170
161
|
- - ">="
|
171
162
|
- !ruby/object:Gem::Version
|
172
|
-
hash: 3
|
173
163
|
segments:
|
174
164
|
- 0
|
175
165
|
version: "0"
|
@@ -178,7 +168,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
168
|
requirements:
|
179
169
|
- - ">="
|
180
170
|
- !ruby/object:Gem::Version
|
181
|
-
hash: 3
|
182
171
|
segments:
|
183
172
|
- 0
|
184
173
|
version: "0"
|
data/origami/docmdp.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
|
3
|
-
= File
|
4
|
-
docmdp.rb
|
5
|
-
|
6
|
-
= Info
|
7
|
-
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
-
Copyright (C) 2010 Guillaume Delugr� <guillaume@security-labs.org>
|
9
|
-
All right reserved.
|
10
|
-
|
11
|
-
Origami is free software: you can redistribute it and/or modify
|
12
|
-
it under the terms of the GNU Lesser General Public License as published by
|
13
|
-
the Free Software Foundation, either version 3 of the License, or
|
14
|
-
(at your option) any later version.
|
15
|
-
|
16
|
-
Origami is distributed in the hope that it will be useful,
|
17
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
-
GNU Lesser General Public License for more details.
|
20
|
-
|
21
|
-
You should have received a copy of the GNU Lesser General Public License
|
22
|
-
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
|
-
|
24
|
-
=end
|
25
|
-
|
26
|
-
module Origami
|
27
|
-
|
28
|
-
class Null
|
29
|
-
def to_docmdp_str
|
30
|
-
"\000"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class Integer
|
35
|
-
def to_docmdp_str
|
36
|
-
[ 1, self.value & 0xFFFFFFFF ].pack("CN")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Real
|
41
|
-
def to_docmdp_str
|
42
|
-
[ 2, self.value.round & 0xFFFFFFFF ].pack("CN")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class Boolean
|
47
|
-
def to_docmdp_str
|
48
|
-
[ 3, (self.false?) ? 0 : 1 ].pack("CN")
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class Name
|
53
|
-
def to_docmdp_str
|
54
|
-
[ 4, self.to_s.length, self.to_s ].pack("CNA*")
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
class String
|
59
|
-
def to_docmdp_str
|
60
|
-
[ 5, self.to_s.length, self.to_s ].pack("CNA*")
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class Dictionary
|
65
|
-
def to_docmdp_str(*fields)
|
66
|
-
if fields.empty?
|
67
|
-
self.each_pair { |key, value|
|
68
|
-
|
69
|
-
}
|
70
|
-
else
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
class Array
|
77
|
-
def to_docmdp_str
|
78
|
-
str = [ 7, self.length ].pack("CN")
|
79
|
-
|
80
|
-
self.each do |obj|
|
81
|
-
str << obj.to_docmdp_str
|
82
|
-
end
|
83
|
-
|
84
|
-
str
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
class Stream
|
89
|
-
def to_docmdp_str
|
90
|
-
[ 8, self.dictionary.size ].pack("CN") +
|
91
|
-
self.dictionary.to_docmdp_str(:DecodeParms, :F, :FDecodeParms, :FFilter, :Filter, :Length) +
|
92
|
-
[ self.rawdata.length, self.rawdata ].pack("NA*")
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|