#!/usr/bin/ruby
## docxtract v0.1 : Extract files from docx document
## Copyright (C) 2009 Franck GUENICHOT
## franck {dot} guenichot {at} orange {dot} fr
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 3
## of the License, or any later version.
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see .
## Written for the Network Forensic Puzzle #2
## http://forensicscontest.com
require 'rubygems'
require 'zip/zip'
require 'zip/zipfilesystem'
require 'digest/md5'
require 'optparse'
$VERSION = "0.1"
# USeful funcs.
def md5sum(file)
#Calculate md5sum of a file
digest = Digest::MD5.hexdigest(File.read(file))
digest
end
#################################################################################################
# handle command line args
options = {}
opts = OptionParser.new do|opts|
opts.banner = "
docxtract version #{$VERSION}
Copyright (C) 2009 Franck GUENICHOT
docxtract comes with ABSOLUTELY NO WARRANTY;
This is free software, and you are welcome
to redistribute it under certain conditions.
(GPL v3)
Usage: docxtract -x [-i] [-d ] "
options[:xtract] = false
opts.on( '-x', '--xtract', 'xtract files (by default to current dir)' ) do
options[:xtract] = true
end
options[:img_only] = false
opts.on( '-i', '--img_only', '(extract) images only' ) do
options[:img_only] = true
end
options[:md5sum] = false
opts.on( '-m', '--md5', 'Display extracted file MD5 Hash' ) do
options[:md5sum] = true
end
options[:destdir] = nil
opts.on( '-d', '--destdir DIR', 'define destination DIR' ) do|dir|
options[:destdir] = dir
end
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
#parse command line args
opts.parse!
$filename = ARGV[ARGV.length-1]
# if no file in input => display help and exit
if $filename == nil
puts opts
exit(0)
end
unless File.exist?($filename)
puts "File: #{$filename} does not exist."
exit(0)
end
begin
if options[:xtract] then
# open docx file
Zip::ZipFile.open($filename) do |zipfile|
zipfile.each {|file|
if options[:destdir] then
destpath = File.join(options[:destdir],file.name)
else
destpath = file.name.gsub('word/media/',"")
end
if options[:img_only] then
if file.name =~ /word\/media\/.*$/ then
puts "Extracting: #{file.name.gsub('word/media/',"")} (#{file.size} bytes)"
FileUtils.mkpath(File.dirname(destpath.gsub('word/media/',"")))
file.extract(destpath.gsub('word/media/',""),&proc{true})
if options[:md5sum] then
md5 = md5sum(destpath)
puts "MD5: #{md5}"
end
end
else
puts "Extracting: #{file.name} (#{file.size} bytes)"
#create dir
FileUtils.mkpath(File.dirname(destpath))
zipfile.extract(file,destpath)
if options[:md5sum] then
md5 = md5sum(destpath)
puts "MD5: #{md5}"
end
end
}
end
else
puts opts
end
rescue => exception
puts "An error occurred"
puts exception
end
#################################################################################################
# END of docxtract #
#################################################################################################