{"id":1267,"date":"2016-07-16T16:56:28","date_gmt":"2016-07-16T16:56:28","guid":{"rendered":"https:\/\/zogspat.tk\/blog\/?p=1267"},"modified":"2016-08-15T21:22:03","modified_gmt":"2016-08-15T21:22:03","slug":"ip-camera-security","status":"publish","type":"post","link":"https:\/\/the-plot.com\/blog\/?p=1267","title":{"rendered":"IP Camera Data Privacy"},"content":{"rendered":"<p>I&#8217;ve had a few goes at setting up the <a href=\"https:\/\/the-plot.com\/blog\/?p=807\">Motion package on my Raspberry Pi<\/a>, but I&#8217;ve finally abandoned it. In its stead, we recently bought an IP camera manufactured by a company called Annke which, at the time of writing, is among the best selling surveillance cameras on Amazon. It&#8217;s a nice piece of kit but given that it only cost \u00a340 and has a lot of moving parts, it&#8217;s not one that I expect to survive down the years.<\/p>\n<p>I thought it would be interesting to\u00a0proxy the traffic on my phone to see what&#8217;s happening.<\/p>\n<p>My iPhone isn&#8217;t jailbroken, which would have been a showstopper if the server that the app is talking to was using certificate pinning. It&#8217;s not. The first call is over plain HTTP. I&#8217;m not going to copy it here, because some of the payload is decodes to binary, and there&#8217;s a possibility that I might be broadcasting my own password. Doh!<\/p>\n<p>So the first call is a GET to a server running on Amazon&#8217;s cloud service, listening on port 7080. I checked the IANA registry: while there is something assigned to that &#8216;officially&#8217; [some identity management software called empowerid] I think it&#8217;s a coincidence, and it&#8217;s probably just a web server of some kind running on a non standard port. The response doesn&#8217;t report back the server software name. Included in the GET parameters, there are a series of comma and slash [url encoded] separated parameters which are base64 encoded. These decode into binary, and could be anything. Included among the readable parameters is my username.<\/p>\n<p>The response back is a block of JSON, referencing different URLs on the same server, which a geolocation service reliably informs me is in a data centre operated by an outfit called OVH in Roubaix, northern France. The URLs have helpful prefixes: &#8216;signal&#8217;, &#8216;debug&#8217;, &#8216;ping&#8217;, and &#8216;ntp&#8217; among them. Not all of the URLs are referring to web traffic: there&#8217;s one reference to telnet, which is a blast from the past, and another called &#8216;binnet:\/\/&#8217; which is sufficiently non standard that Google keeps insisting\u00a0on telling me about\u00a0&#8216;bonnets&#8217; :). That final &#8216;binnet&#8217; URL refers back to the original AWS server.<\/p>\n<p>The app then does a second GET to a server, this time in Tampa, Florida. I&#8217;m not going to break this one down in any sort of detail because the server refuses the connection, so it can&#8217;t be too important!<\/p>\n<p>Next, the app opens a TLS connection to the French server, and does 10 separate GETs. The 3rd of these includes my password, which I registered on first run.<\/p>\n<p>Here&#8217;s what I imagine is happening: the camera is going to be polling the server in France cyclically, asking the question, &#8216;do I need to transmit to you yet?&#8217; When I connect to the same server via the phone app, the answer comes back as a &#8216;yes&#8217;. The camera starts to transmit, and the server then relays the stream\u00a0back to my app. WireShark should be able to give me some pointers, but I&#8217;m running out of time to look at it today. If I find anything interesting or contradictory when I do get round to looking at it, I&#8217;ll do a separate post on it.<\/p>\n<p>By the way, the app seems to be using JavaScript to instantiate the video stream in HTML5. Apple have a video from the WWDC in 2013 on exactly this topic.<\/p>\n<p>So in summary, it looks like the video stream of our back garden \/ the cat \/ my wife and I occasionally waving at the camera ends up in France, with the server there &#8216;joining&#8217; the connection from the camera to the app.<\/p>\n<p>The end state with my Raspberry Pi was, well, while not necessary secure in and of its own right, certainly wasn&#8217;t nearly as &#8216;mediated&#8217;, shall we say. I set up our broadband router with\u00a0a port forwarding rule and configuration for a DDNS service. That meant we could connect from our phones to the web server integrated into the Motion package. That was all over vanilla HTTP &#8211; hey, at least I set a 401 password!<\/p>\n<p>While I can&#8217;t do anything about how the camera operates &#8211; a trade-off I&#8217;m willing to make based on pure utility &#8211; I&#8217;m probably going to take a look at partitioning off the network with a proper firewall behind the broadband router [which can be configured to operate as a modem only]. I&#8217;ll put all of the &#8216;less trusted&#8217; devices on their own little segment. Pfsense seems to be the way to go.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve had a few goes at setting up the Motion package on my Raspberry Pi, but I&#8217;ve finally abandoned it. In its stead, we recently bought an IP camera manufactured by a company called Annke which, at the time of &hellip; <a href=\"https:\/\/the-plot.com\/blog\/?p=1267\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-1267","post","type-post","status-publish","format-standard","hentry","category-tech"],"_links":{"self":[{"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1267"}],"version-history":[{"count":2,"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1267\/revisions"}],"predecessor-version":[{"id":1270,"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1267\/revisions\/1270"}],"wp:attachment":[{"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/the-plot.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}