Path: blob/master/modules/auxiliary/scanner/gprs/gtp_echo.rb
19851 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::Report7include Msf::Auxiliary::UDPScanner89def initialize10super(11'Name' => 'GTP Echo Scanner',12'Description' => %q{13This module sends UDP GTP (GTP-U) echo requests to the target RHOSTS and14reports on which ones respond, thus identifying General Packet Radio15Service (GPRS) servers. This module does not support scanning with SCTP.16},17'References' => [18['URL', 'https://insinuator.net/tag/gtp/'],19['URL', 'https://www.etsi.org/deliver/etsi_ts/129200_129299/129281/08.00.00_60/ts_129281v080000p.pdf']20],21'Author' => [22'Daniel Mende', # original gtp-scan.py script23'Spencer McIntyre' # metasploit module24],25'License' => MSF_LICENSE26)2728register_options([29OptEnum.new('VERSION', [ true, 'The GTP version to use', '1', ['1', '2'] ]),30Opt::RPORT(2152)31])32end3334class GTPv1 < BinData::Record35endian :big3637default_parameter version: 138default_parameter protocol_type: 139default_parameter has_next_extension_header: 040default_parameter has_sequence_number: 041default_parameter has_n_pdu_number: 042default_parameter message_type: 043default_parameter data: ""4445# header46bit3 :version, :initial_value => :version47bit1 :protocol_type, :initial_value => :protocol_type48bit1 :reserved49bit1 :has_next_extension_header, :initial_value => :has_next_extension_header50bit1 :has_sequence_number, :initial_value => :has_sequence_number51bit1 :has_n_pdu_number, :initial_value => :has_n_pdu_number52uint8 :message_type, :initial_value => :message_type53uint16 :len, :value => :calc_length54uint32 :teid5556# body57uint16 :sequence_number, onlyif: -> { has_sequence_number.nonzero? }58uint8 :n_pdu_number, onlyif: -> { has_n_pdu_number.nonzero? }59uint8 :next_extension_header_type, onlyif: -> { has_next_extension_header.nonzero? }60string :data, :initial_value => :data, :read_length => :calc_length_read6162def calc_length63length = data.length64length += 2 if has_sequence_number.nonzero?65length += 1 if has_n_pdu_number.nonzero?66length += 1 if has_next_extension_header.nonzero?67length68end6970def calc_length_read71length = len72length -= 2 if has_sequence_number.nonzero?73length -= 1 if has_n_pdu_number.nonzero?74length -= 1 if has_next_extension_header.nonzero?75length76end77end7879class GTPv1EchoRequest < GTPv180default_parameter has_sequence_number: 181default_parameter message_type: 182end8384class GTPv2 < BinData::Record85endian :big8687default_parameter version: 288default_parameter piggybacking: 089default_parameter message_priority: 090default_parameter message_type: 091default_parameter data: ""9293# header94bit3 :version, :initial_value => :version95bit1 :piggybacking, :initial_value => :piggybacking96bit1 :has_teid97bit1 :message_priority, :initial_value => :message_priority98uint8 :message_type, :initial_value => :message_type99uint16 :len, :value => :calc_length100101# body102uint32 :teid, onlyif: -> { has_teid.nonzero? }103uint24 :sequence_number104uint8 :spare105string :data, :initial_value => :data, :read_length => :calc_length_read106107def calc_length108length = data.length + 4109length += 4 if has_teid.nonzero?110length111end112113def calc_length_read114length = len - 4115length -= 4 if has_teid.nonzero?116length117end118end119120class GTPv2EchoRequest < GTPv2121default_parameter message_type: 1122end123124def build_probe125# the tunnel endpoint identifier (TEID) field must be 0 for echo requests126# per the specification127if datastore['VERSION'] == '1'128@probe = GTPv1EchoRequest.new.to_binary_s129else130@probe = GTPv2EchoRequest.new.to_binary_s131end132end133134def scanner_postscan(batch)135@results.each do |rhost, data|136next unless data.length == 1137138data = data[0]139140if datastore['VERSION'] == '1'141gtp = GTPv1142else143gtp = GTPv2144end145begin146response = gtp.read(data)147rescue EOFError148next149end150151if datastore['VERSION'] == '1'152next unless response.version == 1153next unless response.teid == 0154else155next unless response.version == 2156next unless response.sequence_number == 0157end158159peer = "#{rhost}:#{rport}"160print_good("GTP v#{datastore['VERSION']} echo response received from: #{peer}")161162report_service(163:host => rhost,164:proto => 'udp',165:port => rport,166:name => 'gtp'167)168end169end170end171172173