Showing posts with label Internet Of Things. Show all posts
Showing posts with label Internet Of Things. Show all posts

Thursday, 2 February 2017

HOME AUTOMATION: ESP8266, Blynk and OTA Updates

I previously used Blynk to set up remote access to my house via my phone and a electric door strike. Since then I learned of the Arduino Over The Air (OTA) update library that would allow me to remotely update the firmware of my device so naturally I immediately wanted to add this feature.

Arduino OTA Library:

You can read about the library on the Arduino github site here, but basically there are three ways you can implement the OTA update:

  1. Arduino IDE
  2. Web Browser
  3. HTTP Server
I've decided to go for the Arduino IDE scenario that is described here.
The requirements for this process are:
  • Arduino IDE (tested with 1.6.8)
  • Python 2.7


Arduino IDE OTA Update:

Basically all you really is the command "ArduinoOTA.begin();" in the setup routine and the command "ArduinoOTA.handle();" in the loop function. This is the bare minimum you need to get it working, but we'll add some more things like error handling and some basic security.

EDIT: I couldn't get the Arduino IDE security feature working on my windows 10 machine, it seems there are a few bugs still being worked out 


Blynk and OTA Code:


/**************************************************************
 * Blynk is a platform with iOS and Android apps to control
 * Arduino, Raspberry Pi and the likes over the Internet.
 * You can easily build graphic interfaces for all your
 * projects by simply dragging and dropping widgets.
 *
 *   Downloads, docs, tutorials: http://www.blynk.cc
 *   Blynk community:            http://community.blynk.cc
 *   Social networks:            http://www.fb.com/blynkapp
 *                               http://twitter.com/blynk_app
 *
 * Blynk library is licensed under MIT license
 * This example code is in public domain.
 *
 **************************************************************
 * This example runs directly on ESP8266 chip.
 *
 * WARNING! ESP8266 SSL support is still experimental.
 *          More info here: https://github.com/esp8266/Arduino/issues/43
 *
 * Note: This requires ESP8266 support package:
 *   https://github.com/esp8266/Arduino
 *
 * Please be sure to select the right ESP8266 module
 * in the Tools -> Board menu!
 *
 * Change WiFi ssid, pass, and Blynk auth token to run :)
 *
 **************************************************************/

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#define RELAY_PIN D1

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266_SSL.h>
#include <Ticker.h>
#include <ArduinoOTA.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "XXXX";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XXXX";
char pass[] = "XXXX";
char hostOTA[] = "DoorLock";
char passOTA[] = "XXXX";

bool vPinState = false;               // Set the default virtual pin state
int maxRelayOnTime = 10;              // Set the max on time of the relay 
int minRelayOnTime = 1;               // Set the minimum on time of the relay
int vDelayTime = minRelayOnTime;      // Set the initial delay time value
Ticker doorLatch;                     // Callback fuction instance

void setPinLow()
{
  digitalWrite(RELAY_PIN, 0);
  doorLatch.detach();
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, 0);

  ArduinoOTA.setHostname(hostOTA);
  //ArduinoOTA.setPassword(passOTA);
  ArduinoOTA.onStart([]() {
    Serial.println("OTA: Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nOTA: End");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("OTA: Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("OTA: Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("OTA: Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("OTA: Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("OTA: End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("OTA: Ready");
}

void loop()
{
  ArduinoOTA.handle();
  Blynk.run();
}

BLYNK_WRITE(V0)
{
  // Get the virtual input state
  vPinState = param.asInt();

  // If the virtual input went high
  if(vPinState)
  {
    // Open the relay
    digitalWrite(RELAY_PIN, 1);
    // Turn off the relay after the defined delay time
    doorLatch.attach(vDelayTime, setPinLow);
  }
}

BLYNK_WRITE(V1)
{
  // Get the input from the virtual input slider
  vDelayTime = param.asInt();

  // Constrain the virtual slider input to within the preset bounds
  vDelayTime = constrain(vDelayTime, minRelayOnTime, maxRelayOnTime);
}


How to update your device OTA:

Once you get the code loaded on to your device you should see the unit appear in your list of ports under the 'Tools' heading.
I had to reboot my machine to get this to work for me. Now you can upload code to your device over the network as if it was connected via USB.


Saturday, 21 January 2017

Securing IoT Devices from Mirai BotNet Vulnerability

I use the tinyCam Monitor app to view an IP camera I have setup at home. One of the more recent updates introduced a nice initiative to check network devices for the Mirai botnet vunerability by checking known default usernames and passwords that were given when the hackers released the Mirai source code.

I opened the app to change some settings and noticed my network enabled door bell (probably routing through China) was listed as a vulnerable device. Pretty scary!


You can read about it on the wiki page, but here is a quick summary of Mirai: devices infected by Mirai scan the internet for IoT devices with default username and passwords and attempt to gain access and infect other devices. On command the infected devices (bots) can be used to create a massive distributed DDoS attack. Luckily the malware isn't written in to memory so rebooting the device should clear it, but if vulnerable devices are not patched then the malware will quickly reappear.

I did some searching and didn't find any simple tools that would scan my network for vulnerable devices, so I wrote a little python script that checks a given host (I used my router to see what devices were connected on what IPs) against the list of known default usernames and passwords put out when the Mirai hackers released the source code.

import getpass
import sys
import telnetlib

HOST = "192.168.1.17"

#[[Username,Password],]
userPassList = [["666666","666666"],["888888","888888"],["admin",""],
                ["admin","1111"],["admin","1111111"],["admin","1234"],
                ["admin","12345"],["admin","123456"],["admin","54321"],
                ["admin","7ujMko0admin"],["admin","admin"],["admin","admin1234"],
                ["admin","meinsm"],["admin","pass"],["admin","password"],
                ["admin","smcadmin"],["admin1","password"],["administrator","1234"],
                ["Administrator","admin"],["guest","12345"],["guest","guest"],
                ["mother","fucker"],["root","(none)"],["root","00000000"],
                ["root","1111"],["root","1234"],["root","12345"],
                ["root","123456"],["root","54321"],["root","666666"],
                ["root","7ujMko0admin"],["root","7ujMko0vizxv"],["root","888888"],
                ["root","admin"],["root","anko"],["root","default"],
                ["root","dreambox"],["root","hi3518"],["root","ikwb"],
                ["root","juantech"],["root","jvbzd"],["root","klv123"],
                ["root","klv1234"],["root","pass"],["root","password"],
                ["root","realtek"],["root","root"],["root","system"],
                ["root","user"],["root","vizxv"],["root","xc3511"],
                ["root","xmhdipc"],["root","zlxx."],["root","Zte521"],
                ["service","service"],["supervisor","supervisor"],
                ["support","support"],["tech","tech"],["ubnt","ubnt"],
                ["user","user"]]

print "Testing Mirai botnet default usenames and passwords on host:" + HOST

for userPass in userPassList:
    user = userPass[0]
    password = userPass[1]

    try:
        tn = telnetlib.Telnet(HOST, 23, 5)
    
        tn.read_until("login: ")
        tn.write(user + "\n")
        if password:
            tn.read_until("Password: ")
            tn.write(password + "\n")
    
     print "######WARNING###### Connected on port " + portNumber + " with Username:" + user + " Password: " + password
        tn.write("ls\n")
        tn.write("exit\n")
    
        print tn.read_all()

    except:
        print "Unsuccessful attempt Username:" + user + " Password:" + password

It's a work in progress but so far it works well enough for me.

I already knew my wireless door bell had a default username and password for the telnet port so I set out to change this to something else.

Changing the Telnet Password

My device didn't have the usual passwd command in linux that you would use to change the password of a user. I did some hunting and found a command chpasswd in the /usr/sbin/ directory. I followed the instructions here to work out how to use the command, then I changed the password of the root user by doing the following:


  1. Telnet in to the device (I use PuTTY)
  2. Enter the default username and password you discovered earlier
  3. Type the command "chpasswd" in and press enter
  4. Enter the new username and password in the format "username:password" and press enter
  5. Hit ctrl+d to exit the script
That's it! You have gone a long way toward making your device (and the internet) a safer place