Monthly Archives: September 2013

Arduino and Microwave Sensor

A while back we wrote about the microwave sensor (http://icaruslabs.cysecurity.org/microwave-motion-detection-system). A PoC is ready for demonstration. Once again we are using an Arduino board for this project. For use in the field we will be using a standalone AVR or maybe a Parallax Propeller board. The microwave sensor outputs the data through a single pin. The frequency of the signal being output changes in proportion to the speed it is detecting. The arduino reads the output through findFrequency function. Since the frequency varies along with the speed of movement, findFrequency returns a value that is directly proportional to the speed of the object’s motion that it is detecting. As you can see in the schematic below, we’ve attached 3 LEDs to measure the speed. If no motion is detected, none of the LEDs will light up. If some motion is detected, the first led will light up. If there is a somewhat faster motion, two of the LEDs will simultaneously light up and if there is a very fast motion, all three will light up.

microwave motion

What differentiates this setup from normal motion detectors is the fact that it is capable of penetrating solid objects such as walls and doors. It could be of immense importance during situations where a direct line of sight is impossible or just not viable such as disaster or high risk areas.

working prototype

Here is the Arduino code that we used:

int pin= 7;
int led1= 8;
int led2= 9;
int led3=10;
unsigned long time;
void setup()
{
  Serial.begin(9600);
  pinMode(pin, INPUT);
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
}

void loop()
{
  int out= findFrequency(pin);
  Serial.print(out);
  Serial.print("\n");
 if(out==-1)
 {
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay(100);
 } 
else if(out<30)
 {
digitalWrite(led1,HIGH);
digitalWrite(led2,LOW);
digitalWrite(led3,LOW);
delay(100);
 }
 else if(out<90)
 {
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
digitalWrite(led3,LOW);
delay(100);
 }
 else if(out<2000)
 {
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
digitalWrite(led3,HIGH);
delay(100);
 }

}
 long findFrequency(int pin) {
  long freq = 0;
  freq= 500000/pulseIn(pin, HIGH, 250000);
  return freq;
}

InfraRed replay attacks.

Infrared communication has been around since at least since the late 90s. Right now it exists in a variety of devices including but not limited to cell phones, TV remotes and traffic light displays. Most of the IR communication that takes place currently does so in the remote control rather than in the data transfer field. So basically IR use boils down to TV or laptop remotes. Unlike car keyfobs which use rolling codes so that replay attacks cannot happen, infrared remotes do not have any inbuilt protection mechanism. It is very trivial to build a replay device which will capture the data and then retransmit it whenever we choose to. For the purpose of demonstrating this we’ll use an Arduino Uno along with a TSOP382 IR receiver and an IR led. We’ll use Ken Shirriff’s IR library to replay the IR signals.

The process however is not as straightforward as it seems. IR actually has a number of protocols that differ from each other vastly. The main protocols are Sony, NEC, Philips RC5 and RC-6 and some other less well known protocols. Ken’s code takes care of the different cases associated with all these protocols too.

The wiring diagram is given below as well as some pictures to better understand the wiring. Point the remote that you want recorded at the receiver and press any key. This will lead to the Arduino recording the signal. Later, when you want to replay the signal just press the button on the bread board.

IR Recorder Diagram

Although this might seem like a novelty hack, it actually has some serious implications. Other than the usual TV monitors, some security monitors and CCTV cameras also have IR ports which can lead them to being turned off using this device. All the attacker needs to do is to get close enough to record the poweroff signal once.

* Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include 

int RECV_PIN = 11;
int BUTTON_PIN = 12;
int STATUS_PIN = 13;

IRrecv irrecv(RECV_PIN);
IRsend irsend;

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(BUTTON_PIN, INPUT);
  pinMode(STATUS_PIN, OUTPUT);
}

// Storage for the recorded code
int codeType = -1; // The type of code
unsigned long codeValue; // The code value if not raw
unsigned int rawCodes[RAWBUF]; // The durations if raw
int codeLen; // The length of the code
int toggle = 0; // The RC5/6 toggle state

// Stores the code for later playback
// Most of this code is just logging
void storeCode(decode_results *results) {
  codeType = results->decode_type;
  int count = results->rawlen;
  if (codeType == UNKNOWN) {
    Serial.println("Received unknown code, saving as raw");
    codeLen = results->rawlen - 1;
    // To store raw codes:
    // Drop first value (gap)
    // Convert from ticks to microseconds
    // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
    for (int i = 1; i <= codeLen; i++) {       if (i % 2) {         // Mark         rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
        Serial.print(" m");
      } 
      else {
        // Space
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
        Serial.print(" s");
      }
      Serial.print(rawCodes[i - 1], DEC);
    }
    Serial.println("");
  }
  else {
    if (codeType == NEC) {
      Serial.print("Received NEC: ");
      if (results->value == REPEAT) {
        // Don't record a NEC repeat value as that's useless.
        Serial.println("repeat; ignoring.");
        return;
      }
    } 
    else if (codeType == SONY) {
      Serial.print("Received SONY: ");
    } 
    else if (codeType == RC5) {
      Serial.print("Received RC5: ");
    } 
    else if (codeType == RC6) {
      Serial.print("Received RC6: ");
    } 
    else {
      Serial.print("Unexpected codeType ");
      Serial.print(codeType, DEC);
      Serial.println("");
    }
    Serial.println(results->value, HEX);
    codeValue = results->value;
    codeLen = results->bits;
  }
}

void sendCode(int repeat) {
  if (codeType == NEC) {
    if (repeat) {
      irsend.sendNEC(REPEAT, codeLen);
      Serial.println("Sent NEC repeat");
    } 
    else {
      irsend.sendNEC(codeValue, codeLen);
      Serial.print("Sent NEC ");
      Serial.println(codeValue, HEX);
    }
  } 
  else if (codeType == SONY) {
    irsend.sendSony(codeValue, codeLen);
    Serial.print("Sent Sony ");
    Serial.println(codeValue, HEX);
  } 
  else if (codeType == RC5 || codeType == RC6) {
    if (!repeat) {
      // Flip the toggle bit for a new button press
      toggle = 1 - toggle;
    }
    // Put the toggle bit into the code to send
    codeValue = codeValue & ~(1 << (codeLen - 1));
    codeValue = codeValue | (toggle << (codeLen - 1));
    if (codeType == RC5) {
      Serial.print("Sent RC5 ");
      Serial.println(codeValue, HEX);
      irsend.sendRC5(codeValue, codeLen);
    } 
    else {
      irsend.sendRC6(codeValue, codeLen);
      Serial.print("Sent RC6 ");
      Serial.println(codeValue, HEX);
    }
  } 
  else if (codeType == UNKNOWN /* i.e. raw */) {
    // Assume 38 KHz
    irsend.sendRaw(rawCodes, codeLen, 38);
    Serial.println("Sent raw");
  }
}

int lastButtonState;

void loop() {
  // If button pressed, send the code.
  int buttonState = digitalRead(BUTTON_PIN);
  if (lastButtonState == HIGH && buttonState == LOW) {
    Serial.println("Released");
    irrecv.enableIRIn(); // Re-enable receiver
  }

  if (buttonState) {
    Serial.println("Pressed, sending");
    digitalWrite(STATUS_PIN, HIGH);
    sendCode(lastButtonState == buttonState);
    digitalWrite(STATUS_PIN, LOW);
    delay(50); // Wait a bit between retransmissions
  } 
  else if (irrecv.decode(&results)) {
    digitalWrite(STATUS_PIN, HIGH);
    storeCode(&results);
    irrecv.resume(); // resume receiver
    digitalWrite(STATUS_PIN, LOW);
  }
  lastButtonState = buttonState;
}