Friday, January 20, 2017

Raspberry Pi Console Matrix Screensaver

Overview




While developing on the Raspberry Pi I have long wished to have a screen saver on the console rather than the screen just going blank. One option is to use xscreensaver but I like cmatrix (Console Matrix - a "matrix the movie" like display usually run via the CLI). If you do want to try xscreensaver then you can install using:

sudo apt-get install xscreensaver


Install cmatrix


For those that want to go down the cmatrix path, this is the way to do it. Start by installing cmatrix if you don't already have it.

sudo apt-get install cmatrix

To run cmatrix just type the following in Terminal:

cmatrix

You have the following command line options:

    -a: Asynchronous scroll, more like the movie/original screensaver
    -b: Partial bold text mode
    -B: All bold text mode
    -f: Force the linux $TERM type to on
    -l: Linux support for linux console matrix.fnt font
    -n: No bold text mode
    -o: Use "old-style" scrolling - less like the movie, more like the Win/Mac screensaver.
    -s: "Screen saver" mode.  Any key aborts (default is "eye candy" mode, must abort with control C)
    -x: X window mode, use if your xterm is using mtx.pcf
    -u [update]: Update delay (0-9, default 4).
    -C [color]: Use color for matrix (default green).

While cmatrix is running you can press various keys to adjust the display.

    a: Toggle asynch mode
    b: Enable partial bold text
    B: Enable all bold text
    n: Disable bold text
    0-9: Change update delay

You can change the text colour using the following symbols :

    ! – red
    @ – green
    # – yellow
    $ – blue
    % – magenta
    ^ – cyan
    & – white
    ) – black

Making cmatrix a Screen Saver


At the moment you have to type cmatrix every time you want it to run which isn't really a screensaver. The trick is to combine cmatrix with GNU screen.  Screen enables you to run processes within a “terminal tty instance”. The install command is as you would expect:

sudo apt-get install screen

Type screen to run it and screen -list to see all the screen instances that you have running. Before you do that we need to create the screen configuration file. This will allow us to get the screen saver functionality (more or less).

When it first runs, screen will check its configuration file (.screenrc) in your home directory first. This is normally a hidden file but you can see it if you use:

ls -a

If you have an existing file then edit that, if not create a new one in your home directory.

nano .screenrc

Within the .screenrc file you want to add the following lines:

blankerprg cmatrix -BC blue -s
idle 60 blanker

You can obviously use whatever options you want for cmatrix, these are just the ones I like. Credit to K. Mandla for working this out. Note that blanker is the invocation and blankerprg is the “variable” it starts. You can replace cmatrix with something else if you get board with the matrix (e.g. tty-clock -r).

Idle is a command that is run after the specified number of seconds of inactivity is reached. This command will normally be the blanker command to create a screen blanker, but it can be any screen command. You can change this from 60 seconds if you want.

If you now type "screen" in Terminal then after 60 seconds of no activity cmatrix should run.

We almost have a fully functional screen saver. The last step is to get screen to run automatically whenever the Raspberry Pi reboots. I thought this would be easy but it took me 3 attempts to find a solution that worked. The upside is I learnt a lot about the various start up scripts and screen options.

Auto run GNU Screen on Boot - 1st Attempt


As always in linux there are lots of ways to do anything. I thought the easiest approach would be to edit the rc.local file.

The script /etc/rc.local is for use by the system administrator. It is traditionally executed after all the normal system services are started, at the end of the process of switching to a multiuser runlevel. You might use it to start a custom service, for example a server that's installed in /usr/local.

In order to have a command or program run when the Pi boots, you can add commands to the rc.local file. On your Pi, edit the file /etc/rc.local using the editor of your choice. You must edit with root, for example:

sudo nano /etc/rc.local

Add commands below the comment, but leave the line exit 0 at the end, then save the file and exit. Your file will look something like this:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
    printf "My IP address is %s\n" "$_IP"
fi 
screen -dmS "launch"
exit 0

The only problem is that rc.local runs early in the boot process, before a terminal has been created. So you can only use screen to create a detached screen (i.e. not visible). You can run processes in this detached screen but that is unhelpful for what we are trying to do. Interestingly when researching this I found that the code that should print out your IP address on boot no longer works because rc.local runs before the network is setup.

You will notice in the video that I have a Sense Hat installed on my Pi, so I do use the rc.local file to start a python program which runs on the Sense Hat as a sort of "screen saver". Actually I just like the look of it. The program is a looping version of Conway's Game of Life. Since I can't use rc.local to start an attached screen, I replaced the screen -dmS "launch" line with:

sudo python /home/pi/python_code/intro/SenseConway.py &
Notice the & after the line launching the python app?

WARNING:: If your command runs continuously (perhaps it has an infinite loop) or is likely not to exit, you must be sure to fork the process by adding an ampersand (&) to the end of the command. 

Otherwise, the script will not end and the Pi will lock up - I admit I made this mistake at one stage.  Not even CTRL C will get you out of this. In the end I fixed the issue by swapping the SD card with a new version of Raspbian and mounting the old SD card with a USB Card Reader and then editing the rc.local file. You will find the mounted SD Card under media which wasn't an obvious place and took a bit of searching. You have to use chown to change ownership of the rc.local file to the current yser, which allows you to edit it.

The ampersand allows the command to run in a separate process and continue booting with the process running.

Also, be sure to reference absolute filenames rather than relative to your home folder; for example, /home/pi/myscript.py rather than myscript.py.

Auto run GNU Screen on Boot - 2nd Attempt


An alternative to editing rc.local is to use cron. Cron is the general name for the service that runs scheduled actions. crond is the name of the daemon that runs in the background and reads crontab files. Edit your crontab file using:

sudo crontab -e
A crontab is a file containing jobs in the format:

minute hour day-of-month month day-of-week  command
You can also use cron to schedule a job to run at reboot using @reboot. Perfect I thought, except you run into the same problem as using rc.local, using @reboot you can only add detached screens.

I then tried getting cron to start screen 60 seconds after reboot, using something like:

@reboot sleep 60 && my_script.sh
But this didn't work either.

Auto run GNU Screen on Boot - 3rd Attempt


 ~/.profile (historically referred to as ./bash_profile or ~/bash_login) is another shell script run at login time. This is the script that ended up doing the trick for me. It is obviously run after boot has completed and the terminal shell is in place.

I added the following line to the end of my .profile file. "launch" is just the name of the screen session.

[ -z "$STY" ] && screen -Rd "launch"

Note - STY: Alternate socket name. If screen is invoked, and the environment variable STY is set, then it creates only a window in the running screen session rather than starting a new session.

If .profile hadn't worked, then I would have tried .bashrc - there is always another way with linux!

.bashrc is a shell script that Bash runs whenever it is started interactively. A common thing to put in .bashrc are aliases that you want to always be available.

That's it! Well not quite...

Stop Screen Blanking - 1st Attempt


You will now have cmatrix automatically running as your screen saver but after a preset time your screen will still go blank! Back to the drawing board. If you ask Dr Google you will find a number of proposed solutions.

The first thing I tried was editing the /etc/kbd/config file.

sudo nano /etc/kbd/config
I made the following two changes to the file:

# screen blanking timeout. monitor remains on, but the screen is cleared to
# range: 0-60 min (0==never) kernels I've looked at default to 10 minutes.
# (see linux/drivers/char/console.c)
BLANK_TIME=0 (Was 30)

# Powerdown time. The console will go to DPMS Off mode POWERDOWN_TIME
# minutes _after_ blanking. (POWERDOWN_TIME + BLANK_TIME after the last input)
POWERDOWN_TIME=0 (Was 30)
Then rebooted, but CLI screen blanking still occurred.

Stop Screen Blanking - 2nd Attempt


The next thing I tried was editing:

sudo nano /etc/lightdm/lightdm.conf
In that file, look for: [SeatDefaults] and insert this line:

xserver-command=X -s 0 dpms
Try rebooting again. This didn't work for me.

Stop Screen Blanking - 3rd Attempt


Then I tried adding setterm -powersave off -blank 0 to our old friend rc.local (see autorun GNU screen - 1st attempt above).

This worked!

Saturday, January 14, 2017

Mission Package 2 - Voice Recognition for AVA (Part 2)

USB Microphone


You will of course need a USB microphone in order for the Pi to hear you speak. You can buy a USB adaptor for a standard 3.5mm mic but I went with the SunFounder USB 2.0 Mini Microphone for Raspberry Pi 3, 2 Module B & RPi 1 Model B+/B (figure 1).


Figure 1. SunFounder USB 2.0 Mini Microphone

This is where a Raspberry Pi 3 may be a better choice. With built in WiFi you have an extra free USB port.

Pi AUI Suite




For the voice recognition package our first test was using Steven Hickson's Pi AUI Suite. The thing we like best about this software is the ability to create your own word lists and associated actions. The suite is up to version 3 and you can read about it on Steve's blog. The one caveat is that it appears that the suite is no longer being developed or supported. In particular text to speech (i.e. when the Raspberry Pi responds to a command) appears to be problematic. We will develop an alternative approach to get around this.

A quick summary of Pi AUI Suite. The configuration is done in the commands.conf file (more on this later).
  • The format is voice==command (where voice is the word which AUI Suite looks for)
  • You can use any character except for newlines or == 
  • If the voice starts with ~, the program looks for the keyword anywhere. Ex: ~weather would pick up on "weather" or "what's the weather" 
  • You can use ... at the end of the command to specify that everything after the given keyword should be options to the command. For example: play==playvideo ... This means that if you say "play Futurama", it will run the command playvideo Futurama 
  • You can use $# (where # is any number 1 to 9) to represent a variable. These should go in order from 1 to 9. For example: $1 season $2 episode $3==playvideo -s $2 -e $3 $1 This means if you say "game of thrones season 1 episode 2", it will run playvideo with the -s flag as 1, the -e flag as 2, and the main argument as game of thrones, i.e. playvideo -s 1 -e 2 game of thrones 
  • Because of these options, it is important that the arguments range from most strict to least strict. 
  • This means that ~ arguments should probably be at the end. 
  • You can also put comments if the line starts with # and special options if the line starts with a ! 
  • Default options are shown as follows: 
    • !keyword==pi,
    • !verify==1,
    • !continuous==1,
    • !quiet==0,
    • !ignore==0,
    • !thresh==0.7,
    • !maxResponse==-1 
    • api==BLANK,
    • !filler==FILLER FILL,
    • !response==Yes Sir?,
    • !improper==Received improper command:,
    • !duration==3,
    • !com_dur==2,
    • !hardware==plughw:1,0,
    • !language==en_us 
  • Keyword, filler, and response accept strings. verify, continuous, quiet, and ignore except 1 or 0 (true or false respectively). thresh excepts a floating point number. These allow you to set some of the flags as permanent options (If these are set, you can overwrite them with the flag options). 
  • You can set a WolframAlpha API and maxResponse (the number of branches) like !api==XXXXXX-XXXXXXXXXX amd !maxResponse==3 
  • You can now customise the language support for speech recognition and some text to speech with the language flag. Look up your country code and use that. Ex. For US: !language==en_us, for Spain !language==es, for Germany !language==de.

Installing Pi AUI Suite


The install process is fairly straight forward. Start by installing the dependencies. Open up Terminal or connect via SSH and type the following (all on one line):

sudo apt-get install -y libboost-dev libboost-regex-dev youtube-dl axel curl xterm libcurl4-gnutls-dev mpg123 flac sox

Then download the install files:

git clone https://github.com/StevenHickson/PiAUISuite.git

Change to the install directory:

cd PiAUISuite/Install

Run the install command:

sudo ./InstallAUISuite.sh

Choose y to install any dependencies required and work your way through the installation wizard. If you encounter an error during this process (I did) then install the Boost C++ library:

sudo apt-get install libboost-regex1.49.0

After this library has installed, Run sudo ./InstallAUISuite.sh again.

Alternate Text to Speech Solution


After running the install wizard you can use the setup wizard to generate your command configuration file. To run the setup wizard:

sudo voicecommand -s

As part of this process you have the option to test text to speech (TTS). This appears to be no longer working. The Pi AUI Suite is using the Google TTS API and in early 2016 Google stopped letting automated scripts access the service. You can read about this issue on the Pi AUI Suite GitHub repository.

One workaround is to install the speech synthesis software called Festival:

sudo apt-get install festival

You can test that this is working by typing the following:

echo "Test message" | festival --tts

You will obviously need to have some speakers plugged into the 3.5mm audio out plug. You can adjust the volume using:

alsamixer

Then use the up and down arrows to adjust volume. ESC to save and exit.

Configuring Pi AUI Suite


You can run voicecommand using the default configuration options detailed above, but you will probably want to tweak the available commands. The first thing we need to do is move the configuration file because we are running the program as the root user. To do this type:

sudo mv /home/pi/.commands.conf /root/.commands.conf

To edit the configuration file:

sudo voicecommand -e

or if you prefer using your choice of text editor you can type something like:

sudo nano /root/.commands.conf

You can now change your keyword or add extra commands. For example, if you want the Raspberry Pi to tell you the current time, you could add:

time==echo "The time is " | festival --tts && date | festival --tts

CTRL X to exit, select y to save and then return.

Running Pi AUI Suite


To run voice command:

sudo voicecommand -c

The program will then listen out for your keyword and attempt to respond.

In the next post we will evaluate performance of Pi AUI Suite and look at alternatives.


Tuesday, January 10, 2017

Mission Package 2 - Voice Recognition for AVA (Part 1)

Overview


The next step in AVA's evolution is to add voice recognition. There are many different approaches but I have chosen a Raspberry Pi 2 as the hardware platform because I also want to use it as the master node when implementing ROS (Robot Operating System) down the track. I will then connect the various Arduino's that AVA uses as sub nodes. This will replace the dodgy serial messaging system that I am using to communicate between microprocessors at the moment.

Figure 1. Using Disk Utility to determine SD Card Reader BSD Number.


Install Raspbian on a SD Card


Note that these instructions are for installing Raspbian directly, if you are using NOOBS then replace steps 3-6 with extract the downloaded archive and copy across onto the SD Card. Done.
  1. Download a copy of Raspbian.
  2. For macOS users, place your microSD card in a USB Card Reader. Your microSD needs to be empty and formatted in FAT32. You can format and name your card using SD Card Formatter. Select overwrite format.
  3. We now need the BSD number of our SD Card Reader. The official RPi installation instructions suggests using "About this MAC" but that didn't work for me (I am running El Capitan). So the alternate method is to fire up Disk Utility (see Figure 1). From this we can see that the Device name is disk3s1 and thus the BSD number is disk3. You need Disk Utility for the next step, so you might as well use it to determine the BSD number
  4. Unmount the partition so that you will be allowed to overwrite the disk. To do this, go back to Disk Utility and select the partition and click unmount (top of the screen); do not eject it, or you will have to reconnect it. 
  5. Extract the img file from the file you downloaded in Step 1. This can be harder than it should be. If you have problems with the standard Mac unzip then use The Unarchiver.
  6. From Terminal, run the following command:
sudo dd bs=1m if=path_of_your_image.img of=/dev/diskn

Remember to replace n with the number that you noted before (i.e. 3 in our case). Also, you need to include the complete path of your Raspbian image file. An easy way to find a file’s exact location is to drag and drop the file into the Terminal window. As this is a sudo command you will need to enter your Mac password.


Figure 2. RaspberryPi and 5" Touchscreen.


Writing to the SD Card will take a few minutes and Terminal doesn't indicate progress. You can check the progress by sending a SIGINFO signal (press Ctrl+T). That’s it! You can now eject the microSD card and plug it into your Raspberry Pi.

Adafruit 5" Display



Figure 3. Adafruit 5" Display.

As shown in Figures 2 and 3, we are using the Adafruit 5" touchscreen display as our monitor. This next bit only applies if you happen to be using the same bit of kit.

The display is a mini panel-mountable HDMI monitor with a built-in touchscreen. This backpack features the TFP401 for decoding video, and includes the attached display.

The TFP401 is a DVI/HDMI decoder from TI. It can take unencrypted video and pipe out the raw 24-bit colour pixel data - HDCP not supported! The 5" display is 800x480 resolution, which is just enough to run most software, but still small enough that it can be used in portable or embedded projects without the bulk.

You can power the entire display from a USB port. With the default 5" 800x480 display and 50mA backlight current, the current draw is 500mA total. You can reduce that down to 370mA by running the backlight at half-brightness (25mA). With the backlight off, the decoder and display itself draws 250mA. If you want more backlight control, there's a PWM input, connect that to your microcontroller or other PWM output and you can continuously dim the backlight as desired.

The touch screen shows up as a USB mouse so no special drivers are needed. You can power the driver over USB as long as your computer can supply 500mA on the USB port, and then feed it video via the HDMI port.

Note the TFP401 decoder chip does not contain a video scaler, it will not resize/shrink video! I suspect this is what causes the Raspberry Pi some trouble.

The default installation of Raspbian (and other linux variants) doesn't work with this display. The NOOBS installer works for some reason but once you boot into Raspbian the same problem as a direct install occurs (i.e. wavy lines and unreadable text).

To fix this, you need to update the config.txt file. You will either need to plug in a different display to your Raspberry Pi or do it on your laptop and copy the file onto the SD card. You can download a copy of the required config.txt file from the Reefwing Gist repository.

If you look closely at Figure 2, you will see that we are using a Raspberry Pi 2 Model B V1.1. This should give us sufficient processing power, if not I'll move to a Raspberry Pi 3.

No Sound from the Speakers?


While you are playing around with the config.txt file, it is probably worth testing that your speakers are working. You can do this by typing on your Raspberry Pi (CLI):

speaker-test

You should hear pink-noise hiss from the speakers. If not then add the following line to your config.txt file and reboot.

dtparam=audio=on

To test volume levels, it helps to have human voices for the test. To hear a female voice say "front left" and "front right", from either speaker, you can use:

speaker-test -t wav -c 2

In part 2 we will download the actually voice recognition and test to speech software.

Sunday, January 8, 2017

Amazon Echo Dot - Alexa



It may be a stretch to call the Echo Dot a robot but slap on some wheels and you are getting close. With the acquisition of the Dot there are now 4 "robots" in various state of repair running around the house. In addition to the new Dot, the robot vacuum cleaner "ZAC" from Neato is going strong, we also got a BB-8 for Christmas which likes to patrol around the house and we are working on voice recognition for AVA.

Just like Apple's "Siri" and Microsoft's "Cortana",  the Dot uses the Amazon equivalent "Alexa" as your personal digital assistant. You can ask Alexa all the usual questions "What is the weather like?" "What is the news", etc, but what I like is the ability to read you a book from your Kindle library or to play a song from any bluetooth connected device or Spotify/Pandora.

The equivalent of apps for Alexa are called skills. You can develop your own by signing up for the free Amazon Developers program, which I did. In a subsequent post I will cover how you go about whipping up a skill. It looks fairly straight forward but no doubt there will be some tricks...



Monday, October 17, 2016

Mission Package 1 - Penetration Testing (continued)




1. Kali on the Raspberry Pi


If you want a cheap and portable hacking platform to do some penetration testing of a network then loading Kali Linux on the Raspberry Pi is not a bad option. The caveat is that penetration testing can be quite processor intensive so for some activities, the Raspberry Pi will struggle (even using version 3).

The Kali version of Linux is a Debian-derived distribution designed for digital forensics and penetration testing. It is maintained and funded by Offensive Security Ltd. With its security toolkit you can crack Wi-Fi passwords, create fake networks, and test other vulnerabilities. 

2. Installing Kali on a SD card (Using MacOS)

  • Download the Kali Linux Raspberry Pi image for your hardware and unzip the .img file inside. Note: If you’re not using the touch screen display, download the regular version of Kali Linux for the Raspberry Pi.
  • Download RPi-sd card builder (be sure to pick the appropriate version for your installed version of OS X) and unzip the application.
  • Insert your SD card into your Mac using a card reader.
  • Open RPi-sd card builder. You’ll immediately be asked to choose a Raspbian image. Choose the .img file you downloaded earlier.
  • You’ll be asked if your SD card is connected. Since we inserted it earlier, it is, so go ahead and click Continue. You’ll be presented with SD card options. If you only have one inserted, you won’t see anything else in the list and it’ll be checked. If not, just check only the card you want to use and click OK.
  • Enter your administrator password and click OK.
  • You’ll be asked if the SD card was ejected. This is supposed to happen, as the application needs to unmount it so it can perform a direct copy. Double-check that your SD card is no longer available in the Finder. DO NOT remove it from your USB port. When you’re sure, click Continue.
  • RPi-sd card builder finishes prepping your SD card, safely eject it and insert it into your Raspberry Pi unit.

3. WiFi Penetration Test



The picture above shows Kali running on my Raspberry Pi. To test out the functionality we will test the security of our WiFi network. Once you have performed this exercise you will be convinced of the need for a secure WiFi password! Cracking a WiFi network with WEP encryption is no challenge and realistically most WiFi networks will now use WPA (as ours does), so that will be the challenge.

Step 1 - Determine the name of your WiFi interface. 

To do this type airmon-ng. This program is part of the Aircrack-ng package which is included in Kali. Airmon-ng places the WiFi interface into monitor mode.

Aircrack-ng is a network software suite consisting of a detector, packet sniffer, WEP and WPA/WPA2-PSK cracker and analysis tool for 802.11 wireless LANs. It works with any wireless network interface controller whose driver supports raw monitoring mode and can sniff 802.11a, 802.11b and 802.11g traffic. 

As shown in the image below, the WiFi interface name on our Raspberry Pi is wlan0. 


Once you have the interface name,  you type airmon-ng start wlan0 (from here on replace wlan0 with the name of your WiFi interface). This will indicate any processes that may interfere with the WiFi scanning software. In addition it will place your WiFi interface into monitor mode. The new interface name will be wlan0mon. You can run airmon-ng again to check this.

Step 2 - Use Packet Sniffer to capture WiFi details.

The packet sniffer provided with Aircrack-ng is called airodump-ng. To use it, type airodump-ng wlan0mon. Note that we are analysing the network using the monitored interface.


The packet sniffer will immediately start capturing and displaying packets (image above). Type CTRL c when you want to stop airodump-ng. Airodump-ng will display a list of detected access points, and also a list of connected clients (“stations”). The first line shows the current channel, elapsed running time, current date and optionally if a WPA/WPA2 handshake was detected. Note that encryption for our access point is WPA2.

The information that we need to record is as follows:
  • Channel (CH) = 6
  • MAC address (BSSID) of the Access Point = 2C:30:33:27:4E:BE 
To limit the data capture to a single Access Point (AP) that you are interested in, include the “- -bssid” option and specify the AP MAC address. For example: airodump-ng -c 6 --bssid  2C:30:33:27:4E:BE -w airdump.txt. The output of the scan will be placed in airdump.txt.

Step 3 - Determine the MAC address of the Raspberry Pi WiFi interface

This MAC address is required for Step 4 - the deauthentication attack. There are a number of ways to determine the MAC address of the WiFi interface of the Raspberry Pi. You could check the connections to the router or type ifconfig wlan0mon, but we will use a linux utility called macchanger since this can also be used to change your MAC address should this be required. The command to determine your current MAC address is macchanger - s wlan0mon. The results are shown in the image below. You need to record:
  • MAC address of the Wifi Interface (Client) = 40:A5:EF:05:5E:DF


As an aside, if you do want to change the apparent MAC address of your Penetration Testing rig, the process is:
  • Turn off the network interface: ifconfig wlan0 down
  • Use macchanger to randomly generate new MAC address and assign it to the wlan0 network interface: macchanger -r wlan0
  • Re-enable the network interface: ifconfig wlan0 up

Step 4 - Deauthentication Attack.

This attack sends disassociate packets to one or more clients which are currently associated with a particular access point. Disassociating clients can be done for a number of reasons:
  • Recovering a hidden ESSID. This is an ESSID which is not being broadcast. Another term for this is “cloaked”.
  • Capturing WPA/WPA2 handshakes by forcing clients to reauthenticate
  • Generate ARP requests (Windows clients sometimes flush their ARP cache when disconnected)
Aireplay-ng is used to inject frames and is the tool used for our deauthentication attack. Aireplay-ng implements 10 different attacks:

Attack 0: Deauthentication
Attack 1: Fake authentication
Attack 2: Interactive packet replay
Attack 3: ARP request replay attack
Attack 4: KoreK chopchop attack
Attack 5: Fragmentation attack
Attack 6: Cafe-latte attack
Attack 7: Client-oriented fragmentation attack
Attack 8: WPA Migration Mode
Attack 9: Injection test

We will demonstrate the first one, deauthentication. To capture WiFi handshakes, the command is of the format: aireplay-ng --deauth 1 -a [AP MAC] -c [CLIENT MAC], so for our example the command looks like: aireplay-ng --deauth 1 -a 2C:30:33:27:4E:BE -c 40:A5:EF:05:5E:DF

Note that AP MAC comes from step 2 and AP CLIENT comes from step 3. This program can take a while to run.

Saturday, October 1, 2016

Mission Package 1 - Penetration Testing

1. Mission Packages


We wanted to have a number of different mission packages which AVA could carry. A space has been left for these in the centre of the middle deck. The picture below shows the Raspberry Pi penetration testing package mounted. The top deck has been removed.



2. Arduino WiFi Scanner


The Raspberry Pi penetration testing package will be detailed in another post. Today we will look at a supplementary package, the WiFi Scanner, which will be permanently mounted on AVA.

The Arduino WiFi Scanner will constantly check for available networks and report their relative strength.


The WiFi Scanner has the following features:
  • Displays 5 most powerful WiFi networks nearby.
  • Shows relative strength.
  • Automatic update every 5 seconds.
The Scanner is made up of the following components (part numbers are from Jaycar):

XC4410 Uno Main Board
XC4614 WiFi Shield
XC4616 84x48 Dot Matrix LCD Display
WC6026 Socket-Socket Jumper Leads

This design was put together by Jaycar and assembly instructions are available at: http://www.jaycar.com.au/diy-arduino-wifi-scanner. To save you jumping sites we have reproduced the important sections below.

As with all project involving shields, wiring is straightforward. The shield is plugged into the top of the Uno, and then eight of the jumper leads are run from shield to the display.

UnoWiFiLCDFunctionColour wire
5V5VPower
GNDGNDGround
D0 (RX)RXData from shield
D1 (TX)TXData to shield
D2VCCPower to LCDBlack
D3GNDGround for LCDBrown
D4SCESerial Chip EnableRed
D5RSTResetOrange
D6D/CData/CommandYellow
D7DN(MOSI)Serial DataGreen
D8SCLKSerial ClockBlue

By default, the LED backlight is not set to light up (because it needs 3.3V, but the Uno board runs on 5V). If you would like the LED to light up, connect the LED pin on the LCD to one of the 3V3 pins on the 'ESP13' side of the board.

3. The Arduino Code


There are no external libraries to download- everything is included in the Sketch section below (it's a fairly long sketch because it even includes font bitmap data). Once all the connections are made, ensure that the small switches labelled 1 and 2 on the WiFi shield are switched off by moving them away from the ON label. This frees up the Arduino serial port for uploading. Select the Uno board and correct serial port, load the sketch and press upload. If the upload occurs successfully, turn the small white switches back to on, and reset the Uno. If the screen comes up blank, check the wiring between the screen and the shield. If the screen shows 'No Networks...' or gets stuck on'Starting...', and there are networks in range, then double check the switch positions and try unplugging and replugging the Uno power.

The full sketch is shown at the end of the post, but you can also download it from the Reefwing GIST repository https://gist.github.com/reefwing/3a7471f79d382a0c4be886ffd19486c2.

4. How it Works


The WiFi shield provides most of the smarts in detecting the WiFi networks, the Uno simply tells the shield what to do and displays the results.

The commands that are sent to the shield are as follows:

ATE0:
Tells the shield to not echo back commands that are issued to it. This just simplifies the serial communication because there is less data going back and forth.

AT+CWMODE=1:
This command to tell the shield to only behave as a station, and not an access point. Again, because the shield isn't busy trying to provide an access point, it has more time to do what we want it to do.

AT+CWLAP:
This is the command that does most of the work, and asks the shield to return data about the access points that are nearby. Each line of data looks like below:

+CWLAP:(3,"Arduino",-41,"74:da:38:3c:71:99",1,-47)

The SSID name is that data between the first and second quote marks, and the SSID strength (RSSI) is between the second and third quote marks, which is how the sketch finds it. The sketch waits for five seconds for whatever data comes from the shield, and then processes it. First it separates the SSID name and strength and stores them, then it converts the strength from a negative number between -99 and -1 to a positive number between 1 and 99, and displays the five most powerful networks in order. If no network is found (which is what it will also think if the white switches are turned off), then the 'No Networks...' message is displayed.

Other information that comes from the +CWLAP command includes:
  1. Security type is the first number after the bracket. The number decodes as 0=open, 1=WEP, 2=WPA_PSK, 3=WPA2_PSK, 4=WPA_WPA2_PSK.
  2. MAC address of the access point is between the second pair of quote marks. This can be used to distinguish two access points with the same name.
  3. The channel number and frequency offset are the last two numbers, but we find they aren't really much use in most applications.
You could display more of this information- for example, looking for security=0 so you can sniff out open WiFi hotspots.

Appendix - Arduino Sketch



Wednesday, January 20, 2016

Bluetooth (BLE) Robot Remote Control using an iPhone - Part 2

Introduction


If you want to use an iPhone as your controller then Bluetooth is one of the better communication options for directing your robot / drone / whatever.

In Part 2 we will cover the iPhone app required to control your BLE device. The AVA BLE Remote is available as a free download from iTunes. We will first cover how the app works and then how it was coded. For those who don't want to write their own controller, feel free to use ours. We have included the ability to customise the characters sent in response to a command.

We suggest you read Part 1 to understand the overall design but here is a quick recap.

This app has been designed to work with a Bluno board from DFRobot. The Bluno is a combination of an Arduino and a Bluetooth shield. It uses Bluetooth Low Energy (BLE), which is compatible with iOS 7.0+ devices: iPhone 5+,iPad 3+,iPad Mini,and iPod 5th Gen (note that Bluetooth LE capability is required).




Getting Started: The Connection Screen


When the app starts, it will open the connection tab and display any compatible BLE devices which are within range. To connect to a device just tap on its name. If the connection is successful, the word connected will be displayed and the communication indicator "LEDs" will turn from flashing blue to green. You can start a manual search for BLE devices by tapping the search (magnifying glass) icon in the top right of the connection screen. You can stop the search by tapping the disconnect device button (a cross) in the top left.

If you are already connected to a BLE device, tapping the disconnect device button will disconnect you. You can only attach to one BLE device at a time.



Setting a Task


Tasks are a behavioural robotics concept, but of course you can use them as you wish. You don't need to use tasks at all, if you want you can just use the next tab (Control) to direct your robot. Tasks are useful if you want the robot to do more than one thing. In our case, the robot only responds to remote control commands when the remote task has been set.

The idea is that each task is made up of subset of core behaviours. By combining different behaviours you can create a robot task. For example, the default tasks provided with the app are mapped to the following core behaviours in AVA.

Task ID        Name        Behaviours

     0               Status        BID_STOP
     1               Remote     BID_MANUAL
     2               Patrol        BID_AVOID, BID_ESCAPE, BID_POWER
     3               Follow IR BID_PIR_ATTRACT, BID_AVOID, BID_ESCAPE, BID_POWER
     4               Avoid IR   BID_PIR_REPEL, BID_AVOID, BID_ESCAPE, BID_POWER

By combining simple core behaviours you can get emergent complex task following behaviours which degrade gracefully when the robot faces unexpected situations. In our robot, each of the behaviours are set a priority. This priority decides which behaviour takes precedence. If the priorities are the same then the code will deal with them in the order presented (which gives an implied priority). You can refresh your knowledge on behavioural robotics by reading our earlier post on different approaches to robot AI.

Behaviour                        Priority                      Inputs                               Outputs 

BID_STOP                            1                            cliff, collision sensors       left & right motor stop
BID_MANUAL                    2                            BLE remote                       left & right motor controls
BID_ESCAPE                       3                            distance sensors, heading  left & right motor controls
BID_AVOID                         4                            distance sensors                 left & right motor controls
BID_POWER                        5                            batt voltage, homing          left & right motor controls
BID_PIR_ATTRACT           6                            PIR                                     left & right motor controls
BID_PIR_REPEL                 6                            PIR                                     left & right motor controls

The Task tab in the iPhone app allows you to send a tasking message to your Bluno. It is the responsibility of the robot code to assign current behaviours based on the assigned task.

Tapping a task will transmit the tasking ID (e.g. 1) via Bluetooth. Tap the add button (+) to add your own tasks. Tap Edit to delete or rearrange the tasks. Tapping "Default Tasks" will reload the task list that comes with the app.




Controlling your BLE Device


The Control tab acts as a virtual gamepad for your BLE device. The currently selected task is displayed at the top of the screen. Tapping the function keys (F1 to F4) will send the designated character via Bluetooth to your Bluno. Similarly, tapping the directional dPad or stop button will send the character assigned to those buttons. You can change the characters which are transmitted from the key mapping option in the console tab. The default mappings are:

F1    w
F2    x
F3    y
F4    z

Up Arrow         f
Down Arrow    b
Left Arrow       l
Right Arrow     r
Stop                  s

The speed slider will send the selected speed encapsulated with less than and greater than brackets.

Messages received back from the Bluno are displayed at the bottom of the screen.




The Console


The console tab allows you to send any character strings that you wish to the Bluno. Just type the message in the text field and tap Send. Any received messages will be displayed below.

The console tab also contains the system log which records various events, such as device discovery, connection, data transmission and disconnection. You can email the system log by tapping the mail button in the top right of the screen.

Tap the settings (gear icon) button if you wish to change the keys mapped to the Control buttons.




iOS Code


The iOS code is pretty straight forward and made much easier by the Bluno frameworks provided by DFRobot. You will need to include the following classes in your code.

- BLEDevice
- BLEUtility
- DFBlunoDevice
- DFBlunoManager

The download link for the entire Xcode project is provided below, but here are the highlights. Most of the heavy lifting is done by the DFBlunoManager class. This is a shared instance (singleton), so you just access it in your classes using:

 blunoManager = [DFBlunoManager sharedInstance];

The first step is scanning for and connecting with available Bluetooth LE (BLE) devices. Scanning is as simple as:

[blunoManager scan];

The results of the scan are handled by the DFBlunoDelegate, so you will need to have one of your classes conform to this protocol. We used the TabBarViewController as this is nice and central. Within our TabBarViewController, there are a couple of delegate methods which get notified when a scan is performed.

#pragma mark- DFBlunoDelegate

- (void)bleDidUpdateState: (BOOL)bleSupported
{
    NSString *logString;
    NSString *timeStamp = [formatter stringFromDate: [NSDate date]];
    
    if (bleSupported) {
        logString = [NSString stringWithFormat: @"%@: Scanning for BLE devices\n", timeStamp];
        [blunoManager scan];
    } else {
        logString = [NSString stringWithFormat: @"%@: BLE not supported\n", timeStamp];
    }
    
    [self log: logString];
}

- (void)didDiscoverDevice: (DFBlunoDevice *)device
{
    NSString *timeStamp = [formatter stringFromDate: [NSDate date]];
    NSString *logString = [NSString stringWithFormat: @"%@: New device discovered - %@\n", timeStamp, device.identifier];
    
    [self log: logString];
    
    BOOL bRepeat = NO;
    
    for (DFBlunoDevice *bleDevice in appDelegate.deviceArray) {
        if ([bleDevice isEqual: device]) {
            bRepeat = YES;
            break;
        }
    }
    
    if (!bRepeat) {
        [appDelegate.deviceArray addObject: device];
        
        NSString *logString = [NSString stringWithFormat: @"%@: Device added to BLE list\n", timeStamp];
        
        [self log: logString];
    }
    
    [connectionViewController.tbDevices reloadData];
}

We use these to update the table tbDevices in the ConnectionViewController. Once you have found an eligible device, you connect to it using:

[blunoManager connectToDevice: device];

In particular, since we use a table view to list the devices in range we allow the user to connect to a specific device by tapping on the row in the table that corresponds to that device. The device data is stored in deviceArray (which is a property of the application delegate). We also have a property in the application delegate which points to the currently active device (blunoDevice). The relevant code from the ConnectionViewController is:

#pragma mark- Table View Delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    DFBlunoDevice *device = [appDelegate.deviceArray objectAtIndex:indexPath.row];
    
    if (appDelegate.blunoDevice == nil) {
        appDelegate.blunoDevice = device;
        [blunoManager connectToDevice: appDelegate.blunoDevice];
    } else if ([device isEqual: appDelegate.blunoDevice]) {
        if (!appDelegate.blunoDevice.bReadyToWrite) {
            [blunoManager connectToDevice: appDelegate.blunoDevice];
        }
    } else {
        if (appDelegate.blunoDevice.bReadyToWrite) {
            [blunoManager disconnectToDevice: appDelegate.blunoDevice];
            appDelegate.blunoDevice = nil;
        }
        
        [blunoManager connectToDevice: device];
    }
    
    [self.activityIndicator stopAnimating];
    self.activityIndicator.hidden = YES;
    [tableView deselectRowAtIndexPath: indexPath animated: YES];
}

Once you are connected to the remote device, sending data to it is performed by the following method (found in the application delegate).

#pragma mark - Bluno Communications

- (void)sendString: (NSString *)msg {
    if (self.blunoDevice.bReadyToWrite) {
        NSData *data = [msg dataUsingEncoding: NSUTF8StringEncoding];
        
        [blunoManager writeDataToDevice: data Device: self.blunoDevice];
    }
}

The DFBlunoDelegate will let you know what happens via two methods.

- (void)didWriteData: (DFBlunoDevice*)device
{
    //  NSLog(@"%s", __func__);
    
    NSString *timeStamp = [formatter stringFromDate: [NSDate date]];
    NSString *logString = [NSString stringWithFormat: @"%@: Data written\n", timeStamp];
    
    appDelegate.state = Transmitting;
    [self log: logString];
}

- (void)didReceiveData: (NSData *)data Device: (DFBlunoDevice *)device
{
    //  NSLog(@"%s", __func__);
    
    NSString *timeStamp = [formatter stringFromDate: [NSDate date]];
    NSString *receivedTextString = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
    
    //  NSLog(@"ASCII Rx: %d",[receivedTextString characterAtIndex: 0]);
    
    if (receivedTextString && receivedTextString.length > 0 && ![receivedTextString isEqualToString: @"\n"]) {
        NSString *logString = [NSString stringWithFormat: @"%@: Rx - %@\n", timeStamp, receivedTextString];
        manualViewController.txtReceivedMsg.text = receivedTextString;
        consoleViewController.txtReceivedMsg.text = receivedTextString;
        [self log: logString];
    }
    
    appDelegate.state = Receiving;
    consoleViewController.txtSendMsg.text = @"";
}


In our app we use these to update the log file in the console and print out any data received from the remote device.

Finally, to disconnect a device, just use:

[blunoManager disconnectToDevice: appDelegate.blunoDevice];

You will need to replace appDelegate.blunoDevice with whatever you have called your Bluno Device object.

The complete source code is available at the Reefwing Code Repository.

Bluno Code


The Bluno code was covered in Part 1 of this series. Sample code to allow you to test the app is available from the Reefwing Gist Repository (https://gist.github.com/reefwing/eab05c12b615070732c3).