Last year I installed an IoT home security system; back then I did not bother to connect it to the internet mostly because of my own laziness but also because IoT most of the times rhymes with: overpriced crap prone to also being a security nightmare.
I am not going to name the brand, but it is fairly well known and its pricing is not on the cheap side (€ 700 for main unit and external keyboard).
Hardware wise it is well made, just by looking at it one could tell that quite some engineering was poured into it, it has all kind of expansion cards and the quality seems more than decent.
Software, hard to say though.
Just to be on the safe side, I have put it into its own network segment which is segregated from the rest of the network.

To add a little bit of context:

  • IoT: 192.168.3.253
  • IoT Network gateway and recursive DNS server for LAN: 192.168.3.1
  • Laptop: 192.168.1.101

Lets start by sniffing network traffic and see what it does:

mikrotik> /tool/sniffer/print
                     only-headers: no
                     memory-limit: 100KiB
                    memory-scroll: yes
                       file-limit: 1000KiB
                streaming-enabled: yes
                 streaming-server: 192.168.0.101:37008
                    filter-stream: yes
                 filter-interface: all
                 filter-direction: any
  filter-operator-between-entries: or
                       quick-rows: 20
                 quick-show-frame: no
                          running: no

A few seconds after firing up Wireshark this pops up:

wireshark1.png

The interesting bits are:

  • DNS queries, packets number 6906, 6907.
  • DNS replies, packets number 6911 and 6912.
  • TCP handshake, packets number 11748, 11753 and 11755.
  • TLS handshake, packets 11758 and onward.

Time to fire up mitmproxy, but first we need to make some changes on mikrotik and laptop:

mikrotik> /ip/firewall/filter/add chain=forward action=accept src-address=192.168.3.253 dst-address=192.168.0.101 log=yes
...
laptop> sudo firewall-cmd --add-port=443/tcp --zone=FedoraWorkstation
success
laptop> sudo firewall-cmd --list-all-zones | grep -A13 active
FedoraWorkstation (default, active)
  target: default
  ingress-priority: 0
  egress-priority: 0
  icmp-block-inversion: no
  interfaces: wlp1s0
  sources: 
  services: dhcpv6-client
  ports: 443/tcp
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 

Since we know what kind of domain the IoT device is trying to connect to, lets poison the DNS so that it is fouled into connecting to out mitmproxy:

mikrotik> /ip/dns/static/add address=192.168.1.101 comment=mitm-iot name=www. type=A

mitmproxy needs to be listening on port 443, obviously it also needs to run as root.

mitmproxy1.png

Unfortunately though the IoT device is clever enough not to trust mitmproxy self signed SSL certificate, resulting in the following error:

[12:22:38.888][192.168.3.253:57754] client connect
[12:22:38.891][192.168.3.253:57754] Client TLS handshake failed. The client may not trust the proxy's certificate for www. (OpenSSL Error([('SSL routines', '', 'no shared cipher')]))
[12:22:38.891][192.168.3.253:57754] client disconnect

I could have played a little bit with SSL, maybe create a certificate with matching common name, subject alternative name and whatnot.
Hopefully it would not have worked since SSL certificate would still be self signed.

Instead I tried to connect to the domain with a regular browser, and to my disbelief I landed on a full blown login page.

web1.png

The domain is protected by cloudflare, but after a few minutes of googlefoo I found the real IP of the server hosting the service.
This server seems like a regular VPS hosted on Digital Ocean with not so strict security hardening nor up to date software:

laptop> telnet 68.* 22
Trying 68.*...
Connected to 68.*.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u4
^]
telnet> quit
Connection closed.

Website footer also reports copyright 2017, which probably also means that the server (running Debian 10) is probably not the only thing that has not seen any update in quite a few years.
Since I have an account on the platform, I fired up mitmproxy again (this time on port 8080), imported its CA into Chromium keystore and started poking around a bit.

chromium1.png

Website is very minimal, almost looks like an high school diploma project.
Authentication is handled using a PHP session cookie. HTTP expires header is set 44 years in the past (19 nov 1981).
User and password are sent in clear in the body of an HTTP POST.
At least TLS certificates is from letsencrypt and webserver supports TLS v1.3.

mitmproxy2.png mitmproxy3.png

I did not uncover anything super nasty, but this is far from ideal still:

  • un-patched server. Most likely also a single machine with no HA.
  • Most likely un-mantained software (copyright 2017 in the footer).
  • Cloudflare is used but is basically useles since the real backend server can be found in 5 minutes.
  • The website appears to provide the same functionalities of the mobile APP, but in a much more hackable way. It is trivial to rebuild a complete API swagger just by fiddling with it.
    What follows for example is the API call to disable a security zone:
    mitmproxy4.png