I recently bought a phone from ebay that was password locked, and linked to RingCentral, but I didn’t know it at the time. It wasn’t mentioned in the listing, so I just assumed it wasn’t locked. If I had paid attention, I would have seen the stickers on the phone pictured though. I contacted the seller, and he had found another phone that was able to be reset to factory, and he graciously just sent it to me, not wanting the old phone back, so I wasn’t out anything.
Later though, I realized that I needed another phone, so I contacted the seller to see if he had more that could be reset, and he told me that he was having trouble with getting any of the other 50 phones he had to reset, so I started thinking about what I could do to remedy that problem.
Wireshark to the rescue
Knowing that these phones communicate with a server, I decided to find out what server they were communicating with. I fired up Wireshark, and set my router to send all packets from the interface where the phone was to my computer, and had a peek.
Here we see that the phone is making DNS requests to find ntp1.ringcentral.com, and sip.ringcentral.com. We can make some assumptions about these servers based on their prefix. We likely have a time server at ntp1.ringcentral.com, and we likely have sip traffic going to sip.ringcentral.com. Neither of these servers are likely to be interesting to us, so we continue on.
Here, we see that there is a DNS query for ipphone.ringcentral.com. This one is less obvious. DNS returned 199.255.120.251, so the phone now knows where to find that address. I assumed that I would see some traffic destined to that address, but I don’t. When I try and download a file from the address, it comes back with a 404 error, but I don’t even see the phone requesting that from the server. What I do see is this:
This shows a syslog being sent to a strange server. 10.1.1.3 is not a node on my network, and is not routed, so it’s really just going to the ether. It does show me what the phone is trying to do though.
It appears to be looking for an rsync update from
http://ipphone.ringcentral.com/httpreg/rchttpreg.dll?ipeprov&sn=CCQ18491027&pn=SPA303
This is where the phone gets the xml file to provision the phone. This is how we are going to reset the phone.
I’m not too excited yet. I don’t know if there is any kind of authentication that takes place to make sure nobody else can upload a provisioning file. The only way I’ll find out is to try, so our next step is to make sure that calls to ipphone.ringcentral.com are routed to a server we control. For this, we first create a virtual machine that will serve as our “DNS server”. In reality, all we need to do is interfere with calls to ringcentral addresses, and pass through any other DNS requests to a real DNS server.
Using dnsmasq to spoof ip addresses
I fired up an Ubuntu server VM, and installed dnsmask.
sudo apt install dnsmasq-base
Next, we needed to make two files. /etc/dnsmasq.conf and /etc/dnsmasq.hosts.
/etc/dnsmasq.conf:
no-dhcp-interface=
server=8.8.8.8
no-hosts
addn-hosts=/etc/dnsmasq.hosts
no-dhcp-interface= tells dnsmasq to not setup a DHCP interface. The second line tells it to pass through DNS queries to 8.8.8.8, which is Google’s DNS server. no-hosts tells dnsmasq not to use the /etc/hosts file, which is default behavior, and addn-hosts=/etc/dnsmasq.hosts tells it to use the host file we will create, called dnsmasq.hosts.
/etc/dnsmasq.hosts:
10.0.1.55 ntp1.ringcentral.com
10.0.1.55 sip.ringcentral.com
10.0.1.238 ipphone.ringcentral.com
This file is in the same format as your /etc/hosts file, where the ip address of the server is first, followed by the domain of the server. Anything we put in here will be passed to whatever node asks this one for DNS information, instead of being passed on to Google’s DNS server. My PBX server is at 10.0.1.55, and I decided to pass both sip and ntp traffic to that server. 10.0.1.238 is the server where we will serve the XML file from, which is going to also be our Ubuntu virtual machine.
Now we run the following two lines to kill any dnsmasq daemon running, and to start dnsmasq with our new settings.
sudo killall -9 dnsmasq
sudo dnsmasq --no-daemon --log-queries
A small webserver to spoof RingCentral’s provisioning server
Now we need to spin up a web server. This can be any web server, and I considered just installing Apache, and writing rewrite rules, but I decided that was way more than we needed at the moment. Instead, I opted to use a little used library in Python that allows us to spin up a very light webserver with a few lines of code. Since we have dnsmasq running in the window we are in, we need to open another terminal window to setup the web server.
First, we install python 3:
sudo apt install python3
Make sure you are using python 3. This code won’t work in python 2.
Now we create a new directory to put all our server stuff in. I just created ~/server, and changed to that directory. I uploaded a configuration file for the Cisco SPA303 to that directory, and named it index.html. Since each phone is different, I won’t be providing a provisioning file, but there are multiple ways to get one. You can download one, you can make a backup of one from a phone you have access to, or you can get one from a provisioning server like I did. The way I got mine was from the file FreePBX makes for the phone using the Endpoint Manager. I uploaded it to the ~/server folder and named it index.xml. Just make sure that you have one without an admin password set, or you know what password it is set to.
Now we create a file called server.py and edit it with whatever editor you choose. I choose nano, because I can’t be bothered learning vi/vim.
server.py:
from http.server import SimpleHTTPRequestHandler, HTTPServer
class RequestHandler(SimpleHTTPRequestHandler):
def translate_path(self, path):
return '/path/to/server/index.xml'
def run():
server_address = ('', 80)
httpd = HTTPServer(server_address, RequestHandler)
print('Starting httpd...')
httpd.serve_forever()
if __name__ == "__main__":
run()
Make sure to change the path on line 6 to the path you have index.xml in, and amazingly, that’s all there is to it. Instead of trying to figure out how to recreate the path and serve the dll file as a web page, we just subclass RequestHandler and override the translate_path method. All that method does is clean up the path entered into the web browser and feed it out to the server to feed back to the browser. Instead of using anything passed in the path, we return the path to index.xml for any request.
Now, we need to run this server:
sudo python3 server.py
Our spoofing server is now complete. Only one thing left to do.
Pass our spoofing server to the phone as a DNS server
Now that we have a server set up, it’s time to setup our router. Luckily for us, we don’t have to worry about setting up DHCP option 66, or 150. Any router will allow you to manually enter the DNS server address(es). For me, that is 10.0.1.238. You will enter whatever the IP address is of the spoofing server we just created. If you are required to enter two addresses, just enter the address twice. If it won’t do that, enter an IP address that you know doesn’t have a DNS server on it. That’s it. Time to implement the hack.
Final steps
Now comes the really hard part. Reboot the phone. I found that on the Cisco phones, they don’t always attempt to rsync when you reboot them through the menu, so it’s best to just unplug the power and power it back on. You will watch it boot up, and it may reboot a few times, but when it finally settles down, it will have the new provisioning software installed. If you got it from somewhere like the Endpoint Manager, there is nothing you have to do, but just to make sure everything is gone, you might want to do a factory reset from the phone menu, and reprovision it. Otherwise, you should be done.
Lessons learned
I wrote this with the idea in mind that people could use it to learn different ways to look at problems, instead of just giving a list of steps to blindly follow. If you know how to see what’s going on behind the scenes, you can often figure out how to fix problems that might otherwise seem unfixable. This information could possibly be used for nefarious purposes, but for those of us that legitimately own a piece of equipment, there is nothing illegal about doing this procedure.
One thing I did learn that causes things to be insecure for these phones is that passwords are stored in the clear. Because of that, it is possible to get the actual password for these phones from the RingCentral provisioning server. If you enter that address in a web browser, nothing comes up, but it seems like it might be possible to get that server to send down a provisioning file, and if it’s like the ones FreePBX has for Cisco phones, the password isn’t encrypted in any way. You could enter the password found between the <Admin_Passwd> and </Admin_Passwd> tags, and you would be able to reset the phone from there.
Anyway, I hope that helps someone.