Data exfiltration via PSK31 with GNU Radio

Using PSK31 to exfil data – a very basic proof of concept

Purpose
To exfiltrate data from a target computer without using any wired or wireless network which could be caught by network monitoring.

This example uses GNU Radio to transmit over an audio card and receive with a microphone, so no additional radio hardware is required.

Caveats
Please note this is just a basic proof of concept and further work is required to clean out some of the noise.

Hardware
Target computer where data needs to be extracted from.
Raspberry pi 3 with Raspbian installed and a 4G usb dongle for sending out the data.
A USB mini microphone for listening to incoming data on the raspberry pi.
A $5 mini USB microphone was used here:

Software
Transmiting computer with gnuradio installed or just ability to execute javascript.
Receiving raspberry pi with raspbian and gnuradio installed.

PSK31 Protocol
PSK31 is a Phase Shift Keying protocol often used by ham radio operators to send text messages over the air and has a data rate very close to typing speed. ASCII letters and numbers are encoded using a varicode, where a space is represented by 00. No character contains more than one 0 in a row.

Gnuradio on both sides

Receiving computer (raspberry pi) configuration

Install raspbian e.g. dd the image onto an 8Gb sdcard [1].
Change the default passwords for pi & root users.

Install GNU Radio
To install gnu-radio use the following commands:
$ sudo apt-get update
$ sudo apt-get install gnuradio
$ sudo apt-get install gnuradio-dev
$ sudo apt-get install libboost1.55-all-dev
$ sudo apt-get install libcppunit-1.13-0
$ sudo apt-get install libcppunit-dev
$ sudo apt-get install doxygen
$ sudo ldconfig

Install PSK31 graphs
Download and build the PSK31 gnuradio companion graphs from https://github.com/tkuester/gr-psk31 to your project directory
$ cd /home/pi/psk31/gr-psk31-master
$ mkdir build
$ cd build
$ cmake ../
$ make
$ sudo make install
$ sudo ldconfig

Configure the USB microphone
Add these libraries to the GR_BLOCKS_PATH environment variable.
For example, adding to ~/.profile:
GRC_BLOCKS_PATH="/home/sdr/grc-3rdparty-libs/gr-psk31-master/python"
Logout and back in again.

Next, plug in the USB mini microphone and test that it works:
$ arecord -l

Note: this records for 3 secs, make some test noises
$ arecord -D plughw:1,0 -d 3.0 test.wav
$ aplay test.wav

Next adjust the gain on the microphone
“Preferences”->”Audio Device Settings”. Select “USB PnP Sound Device (Alsa mixer)” from dropdown. Choose “Select Controls” and check the “Microphone” box and adjust the gain.

Modify the PSK31 receive graph
Perform the following modifications to the transmit psk gnuradio-companion graph “psk31_rx.grc”:

Replace the “Wav File Source” block with an “Audio Source” block.

Set the “Device Name” parameter within the “Audio Source” block to match your USB microphone address: e.g. to “plughw:1,0”

If this value does not match a valid audio input, the following error will appear when trying the run the graph:
"audio_alsa_source0 - [default]: No such file or directory"

In the “QT GUI Range” block for the “tune_freq” variable, change the “Default Value” to 2000 (or whichever frequency you choose for your situation).

Transmitting computer configuration

This computer will be sending the exfiltrated data to the raspberry pi.

Install GNU Radio
Install gnuradio, e.g. for Ubuntu (for Windows see [2]):
$ sudo apt-get update
$ sudo apt-get install gnuradio
$ sudo apt-get install gnuradio-dev
$ sudo apt-get install python-pkgconfig

Install PSK31 graphs
Download and build the PSK31 gnuradio companion graphs from https://github.com/tkuester/gr-psk31 to /home/pi/psk31
$ cd /home/pi/psk31/gr-psk31-master
$ mkdir build
$ cd build
$ cmake ../
$ make
$ sudo make install
$ sudo ldconfig

Add these libraries to the GR_BLOCKS_PATH environment variable
e.g. for ~/.profile:
GRC_BLOCKS_PATH="/home/sdr/grc-3rdparty-libs/gr-psk31-master/python"
Logout and back in again.

Modify the PSK31 transmit graph
Perform the following modifications to the transmit psk gnuradio-companion graph “psk31_tx.grc”:

In the “QT GUI Range” block for the “tx_freq” variable, change the “Default Value” to 2000 (or whichever frequency you choose for your situation).

Testing transmit and receive
Type in the test message you wish to send in psk31_tx.grc “Vector Source” block as the second parameter within the map variable. For example:

map(ord, 'bank account number: 12121212 bsb: 123456; bank account number: 13131313 bsb: 123456; bank account number: 14141414 bsb: 123456; bank account number: 15151515 bsb: 123456; bank account number: 16161616 bsb: 123456; bank account number: 17171717 bsb: 123456; \n')

Run the psk31_tx.grc graph on the target computer using gnuradio-companion.

Next, run the psk31_rx.grc graph on the raspberry pi computer using gnuradio-companion.

It should be noted that this receive graph is susceptible to noise, experiment with the correct tuning frequency for your hardware, but it should be somewhere around 2000Hz.

Transmitting the data from the target

Receiving the data on the raspberry pi
The incoming (noisy) text is shown in the bottom panel:

Notes
For demonstration here, the host computer is Linux but gnuradio also installs on Windows [2].

All gnuradio-companion graphs can be exported to standalone python code without the need to launch the gnuradio-companion user interface.

It is also possible to generate the PSK31 waveforms using a scripting language without the gnuradio libraries and removing the need to install gnuradio on the host.

Other devices could be used instead of a raspberry pi e.g. the spy devices with a sim which call a number to send the audio to when it hears audio in the room.

Work still remains to clean up the signal and reduce the noise, espcially when using the cheap USB microphones.

References
[1] https://www.raspberrypi.org/documentation/installation/installing-images/
[2] http://gnuradio.org/redmine/projects/gnuradio/wiki/WindowsInstall
[3] https://github.com/tkuester/gr-psk31

Leave a Reply

Your email address will not be published. Required fields are marked *