Lucene search

K
packetstormJay Turla, metasploit.comPACKETSTORM:181210
HistorySep 01, 2024 - 12:00 a.m.

Portmapper Amplification Scanner

2024-09-0100:00:00
Jay Turla, metasploit.com
packetstormsecurity.com
27
metasploit
udpscanner
drdos
cve-2013-5211
us-cert
ntp monlist
ddos
portmapper
amplification
attack

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

AI Score

7.1

Confidence

Low

`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Auxiliary::Report  
include Msf::Auxiliary::UDPScanner  
include Msf::Auxiliary::DRDoS  
  
def initialize  
super(  
'Name' => 'Portmapper Amplification Scanner',  
'Description' => %q{  
This module can be used to discover Portmapper services which can be used in an  
amplification DDoS attack against a third party.  
},  
'Author' => ['xistence <xistence[at]0x90.nl>'],  
'License' => MSF_LICENSE,  
'References' =>  
[  
['CVE', '2013-5211'], # see also scanner/ntp/ntp_monlist.rb  
['URL', 'https://www.cisa.gov/uscert/ncas/alerts/TA14-017A'],  
['URL', 'http://blog.level3.com/security/a-new-ddos-reflection-attack-portmapper-an-early-warning-to-the-industry/']  
],  
)  
  
register_options( [  
Opt::RPORT(111),  
])  
end  
  
def rport  
datastore['RPORT']  
end  
  
def xid_summary  
@xid_summary ||= [Rex::Text::rand_text_numeric(8).to_i].pack('N')  
end  
  
def xid_dump  
@xid_dump ||= [Rex::Text::rand_text_numeric(8).to_i].pack('N')  
end  
  
def xid_metrics  
@xid_metrics ||= [Rex::Text::rand_text_numeric(8).to_i].pack('N')  
end  
  
def setup  
super  
  
# RPC DUMP (Program version: 3) request: rpcinfo -T udp -s <IP>  
@portmap_summary = ''  
@portmap_summary << xid_summary # Random ID  
@portmap_summary << "\x00\x00\x00\x00" # Message Type: 0 (Call)  
@portmap_summary << "\x00\x00\x00\x02" # RPC Version: 2  
@portmap_summary << "\x00\x01\x86\xa0" # Program: Portmap (10000)  
@portmap_summary << "\x00\x00\x00\x03" # Program version: 3  
@portmap_summary << "\x00\x00\x00\x04" # Procedure: DUMP (4)  
@portmap_summary << "\x00\x00\x00\x00" # Credentials Flavor: AUTH_NULL (0)  
@portmap_summary << "\x00\x00\x00\x00" # Credentials Length: 0  
@portmap_summary << "\x00\x00\x00\x00" # Verifier Flavor: AUTH_NULL (0)  
@portmap_summary << "\x00\x00\x00\x00" # Verifier Length: 0  
  
# RPC DUMP (Program version: 2) request: rpcinfo -T udp -p <IP>  
@portmap_dump = ''  
@portmap_dump << xid_dump # Random ID  
@portmap_dump << "\x00\x00\x00\x00" # Message Type: 0 (Call)  
@portmap_dump << "\x00\x00\x00\x02" # RPC Version: 2  
@portmap_dump << "\x00\x01\x86\xa0" # Program: Portmap (10000)  
@portmap_dump << "\x00\x00\x00\x02" # Program version: 2  
@portmap_dump << "\x00\x00\x00\x04" # Procedure: DUMP (4)  
@portmap_dump << "\x00\x00\x00\x00" # Credentials Flavor: AUTH_NULL (0)  
@portmap_dump << "\x00\x00\x00\x00" # Credentials Length: 0  
@portmap_dump << "\x00\x00\x00\x00" # Verifier Flavor: AUTH_NULL (0)  
@portmap_dump << "\x00\x00\x00\x00" # Verifier Length: 0  
  
# RPC GETSTAT request: rpcinfo -T udp -m <IP>  
@portmap_metrics = ''  
@portmap_metrics << xid_metrics # Random ID  
@portmap_metrics << "\x00\x00\x00\x00" # Message Type: 0 (Call)  
@portmap_metrics << "\x00\x00\x00\x02" # RPC Version: 2  
@portmap_metrics << "\x00\x01\x86\xa0" # Program: Portmap (10000)  
@portmap_metrics << "\x00\x00\x00\x04" # Program version: 4  
@portmap_metrics << "\x00\x00\x00\x0c" # Procedure: GETSTAT (12)  
@portmap_metrics << "\x00\x00\x00\x00" # Credentials Flavor: AUTH_NULL (0)  
@portmap_metrics << "\x00\x00\x00\x00" # Credentials Length: 0  
@portmap_metrics << "\x00\x00\x00\x00" # Verifier Flavor: AUTH_NULL (0)  
@portmap_metrics << "\x00\x00\x00\x00" # Verifier Length: 0  
end  
  
def scanner_prescan(batch)  
print_status("Sending Portmap RPC probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")  
@results_summary = {}  
@results_dump = {}  
@results_metrics = {}  
end  
  
def scan_host(ip)  
if spoofed?  
datastore['ScannerRecvWindow'] = 0  
scanner_spoof_send(@portmap_summary, ip, rport, datastore['SRCIP'], datastore['NUM_REQUESTS'])  
scanner_spoof_send(@portmap_dump, ip, rport, datastore['SRCIP'], datastore['NUM_REQUESTS'])  
scanner_spoof_send(@portmap_metrics, ip, rport, datastore['SRCIP'], datastore['NUM_REQUESTS'])  
else  
scanner_send(@portmap_summary, ip, rport)  
scanner_send(@portmap_dump, ip, rport)  
scanner_send(@portmap_metrics, ip, rport)  
end  
end  
  
def scanner_process(data, shost, sport)  
if data =~ /#{@xid_summary}\x00\x00\x00\x01/  
@results_summary[shost] ||= []  
@results_summary[shost] << data  
elsif data =~ /#{@xid_metrics}\x00\x00\x00\x01/  
@results_metrics[shost] ||= []  
@results_metrics[shost] << data  
elsif data =~ /#{@xid_dump}\x00\x00\x00\x01/  
@results_dump[shost] ||= []  
@results_dump[shost] << data  
else  
vprint_error("Skipping #{data.size}-byte non-Portmap response from #{shost}:#{sport}")  
end  
end  
  
# Called after the scan block  
def scanner_postscan(batch)  
@results_summary.keys.each do |k|  
response_map_summary = { @portmap_summary => @results_summary[k] }  
what = 'Portmap RPC DUMP (Program version: 3) amplification'  
report_result(k, what, response_map_summary)  
end  
  
@results_dump.keys.each do |k|  
response_map_dump = { @portmap_dump => @results_dump[k] }  
what = 'Portmap RPC DUMP (Program version: 2) amplification'  
report_result(k, what, response_map_dump)  
end  
  
@results_metrics.keys.each do |k|  
response_map_metrics = { @portmap_summary => @results_metrics[k] }  
what = 'Portmap RPC GETSTAT amplification'  
report_result(k, what, response_map_metrics)  
end  
end  
  
def report_result(host, attack, map)  
report_service(  
host: host,  
proto: 'udp',  
port: rport,  
name: 'portmap'  
)  
  
peer = "#{host}:#{rport}"  
vulnerable, proof = prove_amplification(map)  
if vulnerable  
print_good("#{peer} - Vulnerable to #{attack}: #{proof}")  
report_vuln(  
host: host,  
port: rport,  
proto: 'udp',  
name: attack,  
refs: references  
)  
else  
vprint_status("#{peer} - Not vulnerable to #{attack}: #{proof}")  
end  
end  
end  
  
  
`

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

AI Score

7.1

Confidence

Low