Jump to content

Using WiFi as a photo sensor and motion detector


whitenoise

Recommended Posts

Using WiFi as a photo sensor and motion detector

You need a simple solution to detect if someone is crossing a door? Maybe it also would be great to get a notification directly to your smartphone? You want to count cars? You want to ... ?

Let's divert some WiFi stuff!

What you need:

Hardware:

2 WiFi cards i.e ALFA awus036nha + 5dBi dipol antenna + USB cable

Software:

Linux

Python with modules:

- scapy

- xmpppy

Aircrack suite

- airmon-ng

- airbase-ng

Concept:

Basically we need a transmitter and a receiver and analyze the signal strengh of the packets. The transmitter will send Beacon frames at a high rate but low power. The high rate is needed for a good resolution to detect object passing through the barrier. The higher the rate the faster the objects you can detect. Decreasing the txpower will make the system more sensitive.

The receiver sniffs the Beacon frames comming from the transmitter and analyzes the signal strengh. As the signal will be a bit noisy this is compensated by calculating averages of 10 Beacon frames. These values are the actual values the script works with. From these, 100 packets will averaged again to calculate a steady-state signal. The steady-state signal is used to detect events i.e. some one crossing the barrier.

In every case you have to calibrate the system so it works nicely for your personal purpose!

How does it detect events?

You have to set a threshold which is the minimum difference between the steady-state signal and a signal value at time X. If something crosses the barrier the signal value at this moment will drop i.e. from -30dB to -50dB. This difference is noticed and an event is triggered. The threshold needs to be set carefully. If it is too low you will get false-positives as interference might produce peaks that go a bit beyond the average peaks of the noise. Setting the threshold too high events might not be detected any more (you can also play with the txpower of the transmitter here).

So what happens if a barrier-crossing event is detected?

It is up to you (in case you know a bit about Python programming)! At the moment the script is able to send you a message to your Jabber account which you can run on your smartphone (i.e. on Android with GibberBot). The script also has a protection against mass-spamming and always locks the event-detector for a certain amount of packets until the next event can be detected.

Can you visualize what is going on?

Sure. The output is written into a file called signals.csv containing the packet count (actually every 10 packets the counter increases), the average signal (10 packets) and the average signal for 1000 packets.

You can easily plot that in MS Excel or Libre Calc:

30llxqd.png

How do I use this?

First of all check if you have all the requirements listed above. In a next step you would build your physically setup (i.e. placing the antennas onto your desk with a distance about ca. 1m). With the current setup I used 5dBi dipol antennas.

You have to edit the receiver.py and change the following values according to your setup:

jid="" # Jabber account name i.e. myaccount@jabber.com

pwd="" # Password for Jabber account

recipient="" # Receiver i.e. somereceiver@jabber.com

transm_mac ="00:AA:BB:CC:DD:EE" # MAC address of your transmitting device!

You should notice that there also is the »THR« variable which is the threshold.

Don't forget to save the file.

Now open a terminal and login as root. Set the txpower of your transmitter via command line i.e. »iwconfig wlanX txpower 0.1«. Set both interfaces to monitor mode using »airmon-ng start wlanX« (X depending on your interface index). Open a second terminal and login as root as well. Start the transmitter with »python transmitter.py«. Make sure your arms are not inbetween the antennas and carefully start the receiver with »python receiver.py«. Open Pidgin or whatever you use for Jabber and login into your account.

Now you should see that packets are comming in. You see the packet numbers, average for 10 and average for 1000 packets.

If you move your hand through the barrier and you should get a notification to your Jabber account.

You can close both scripts by pressing Ctrl + C.

qx6nux.png

What if nothing happened?

You have to recalibrate the system. Open the CSV file in Excel and plot the data. Check if you can identify peaks. If there are no peaks your signal strengh might be too high. Maybe your resolution is too weak, too. You can test this by holding your hands for several seconds in the barrier of better just sit between them. If you see a broad but weak peak then your resolution might be too low. So you have to open the transmitter.py and change »bashCommand = 'airbase-ng mon0 -I 5 -e %s' %(ESSID)« to i.e. »bashCommand = 'airbase-ng mon0 -I 3 -e %s' %(ESSID)« so airbase-ng will send a Beacon frame every 3ms.

If there are nice peaks but you still get no signal maybe the threshold is too high. You can simply check that by calculating the difference from the average and the current value. You can change the threshold in »THR« in reciver.py.

Have fun!

Attention:

These scripts are proof of concept and meant to illustrate different applications with WiFi. All the features are static and further modification might require knowledge about programming. Also there is no proper error handling to keep things simple. You use these scripts on your own risk. High packet rates might damage your network interface. Don't use this scripts if you are not fine with that.

transmitter.py

#!/usr/bin/env python
#-*- coding: utf-8 -*-

# WLAN photo sensor receives Beacon frames filtered by a specific MAC address and analyzes the signal strengh.
# The Beacon transmitter has to be set up weak so the system is sensitive enough to detect events.
# Also the packet rate should be high to get a nice resolution for detecting events
# Events are stored in a CSV file for plotting i.e. in Libre Calc
# Setting the transmitting antenna to 0.1dB (using a 5dBi dipol antenna) and sending 200 packets per second worked fine for me (1m distance).


import time
import sys
import signal
import subprocess

def signal_handler(signal, frame):
    	print 'You pressed Ctrl+C!'
    	sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
print 'Press Ctrl+C to abort'
ESSID="sensor" # Type in the name of the network
bashCommand = 'airbase-ng mon0 -I 5 -e %s' %(ESSID) # 5 means every 5ms a Beacon frame will be sent. You can decrease this number to get a better resolution.
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output = process.communicate()[0]

receiver.py

#!/usr/bin/env python
#-*- coding: utf-8 -*-

# WLAN photo sensor receives Beacon frames filtered by a specific MAC address and analyzes the signal strengh.
# The Beacon transmitter has to be set up weak so the system is sensitive enough to detect events.
# Also the packet rate should be high to get a nice resolution for detecting events
# Events are stored in a CSV file for plotting i.e. in Libre Calc
# Setting the transmitting antenna to 0.1dB (using a 5dBi dipol antenna) and sending 200 packets per second worked fine for me (1m distance).
from scapy.all import *
import time
import xmpp

# Setting initial values

count=0 # all captured Beacon frames
sig10=0 # sum of 10 packets
sig100=0 # sum of 1000 packets (100 x sig10 -> 1000, as sig10 is already 10 packets)
m10=0 # averaged signal strengh (10 packets)
m100=2 # averaged signal strengh (1000 packets) - is needed for event detection
THR = -10 # threshold, minimum distance from sig10 to sig100, if difference is greater than THR probably some event happened.
memory=1 # How many packets should pass by until next event can be detected? This is to avoid mass notification
filename = "signals.csv"
file = open(filename, "w")
file.write("frames,sig10,sig100\n")
file.close()
jid="" # Jabber account name i.e. myaccount@jabber.com
pwd="" # Password for Jabber account
recipient="" # Receiver i.e. somereceiver@jabber.com
transm_mac ="00:AA:BB:CC:DD:EE" # MAC address of your transmitting device!	

def sendJabberMsg():
	global jid
	global pwd
	global recipient
	msg = time.strftime("%Y-%m-%d_%H%M%S") + ": EVENT" # This is the message sent in case of event beginning with a time code.
	jid=xmpp.protocol.JID(jid)
	cl=xmpp.Client(jid.getDomain(),debug=[])
	file = open(filename, "a")
	if cl.connect() == "": # If there are connection errors it will be logged
		print "not connected"
		msg = msg + ": not connected"
		event = "%s,%s\n" %(count/10, msg)
		file.write(event)
	if cl.auth(jid.getNode(),pwd) == None: # If there are problems with authentication it will be logged as well
		print "authentication failed"
		msg = msg + ": authentication failed"
		event = "%s,%s\n" %(count/10, msg)
		file.write(event)
	else:	# If everything is fine you will be noticed about the event via Jabber
		cl.sendInitPresence()
		cl.send(xmpp.protocol.Message(recipient,msg))
		print "Message sent!"
		event = "%s,%s: Message sent\n" %(count/10, msg)
		file.write(event)
	file.close()
	cl.disconnect()

def PacketHandler(pkt) :
	global count
	global sig10
	global sig100 
	global m10 
	global m100
	global THR
	global memory
	if pkt.haslayer(Dot11) :
		if pkt.type == 0 and pkt.subtype == 8 and pkt.addr2 == transm_mac :	# If there is a Beacon frame and it is from our transmitter
			if count % 10 != 0: # Count 10 packets and sum up signal strengh
				signal = int(-(256-ord(pkt.notdecoded[-4:-3])))
				sig10= sig10 + signal
				count+=1
			if count % 10 == 0: # If we collected 10 packets...
				if (count/10) % 100 == 0: #... or even 1000 packets...
					m100=sig100/1000 # calculate the average
					sig100 = 0
				m10=sig10/10
				event = "%s,%s,%s\n" %(count/10, m10, m100) # print the data
				print event
				if m10-m100 < THR and (memory+50) < (count/10) and (count/10) > 100: # If the current signal is below the average signal by THR and there was no event during the last 500 packets detected and if already 100 packets passed by then classify this as a crossing event. The last condition is to arm the sensor 100 packets after start.
					sendJabberMsg() # Send a notification
					memory = count/10 # Set the memory, so you won't get jammed with notifications.
				file = open(filename, "a")
				file.write(event)
				file.close()
				sig100+=sig10
				sig10 = 0
				count+=1
				
				
sniff(iface="mon1", prn = PacketHandler)


Link to comment
Share on other sites

Interesting concept though easily incapacitated by putting a powerful transmitter on the same frequency sufficiently nearby.

I can for instance imagine that as you walk through the door your mobile is looking for your AP and in doing so is transmitting on the same frequency your detector is looking at, effectively jamming the low-powered beacon.

The motion detection thing i8igmac describes looks more reliable to me. Interesting, unexpected concept nonetheless.

Link to comment
Share on other sites

First of all this is not an AP you want to connect to. At the moment this is based on Beacon frames as it was an easy option using airbase-ng. Of course you could easily write a script in scapy that sends other packets that are then filtered by the receiver or even design your own packets. So basically there are a few options to make it more reliable. I'm not sure if you even could use encryption because at higher packet rates you might get into trouble with CPU speed.

Link to comment
Share on other sites

The problem I see isn't so much identifying the packet but rather being able to receive the packet at all in the presence of a sufficiently powerful transmitter.

Link to comment
Share on other sites

I see. Yes, interference with other signals could be a problem or at least drop the resolution. One could test this. Maybe directional antennas could improve that issue a bit but in general if you more or less 'DoS' the receiver with strong signal packets the system gets disturbed.

Link to comment
Share on other sites

  • 9 months later...

Unless someone has the need to jam it, it's a passive technology, kind of like a motion detector to open doors at the grocery store. I wouldn't want it to be used for something that was meant to be sure or a safety issue, but for general use it would probably come in handy with things like alarm systems on the property since you can setup "sensors" around the property when it might not be feasible to have someone guarding every inch. This would be neat to tie in with a camera to record animals in the wild too since you can send back over a wifi mesh some feeds in the area if you blanket enough out to monitor for critters.

All those damn big foot and paranormal ghost hunter shows should have something like this in place to see what they can catch..lol Practical paranormal research tools to rule out physical objects from the equation.

Link to comment
Share on other sites

  • 4 weeks later...

I saw something kind like this a couple of years ago where they were using two wireless routers basically as a doplar radar and you could see what was in the next room behind closed doors. Application is for close quarters combat in urban environment. So it's something a SWAT team might have. But really you could adapt it for just about anything. Make it turn on a webcam, mic, lights, stereo, or your machine gun turret :grin: kek!

If you are running some kind of physical security application you could also log the client MAC addresses with airodump-ng and sort them by manufacuturer along with the probes. So in the event someone broke into your building you might be able to find them via the wireless access point they've visited and their phone's MAC. most burgalars and probably not going to think to turn of their cell phone, spoofing a MAC, or turning off active probing. Not sure have the terminology right there.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...