Skip to content

OverkillGuy/qrxfil

Repository files navigation

qrxfil

Exfiltrate files via QR codes.

Splitting files across multiple QR codes for “sending” across air-gapped computer systems. Generates numbered PNG files to scan, can save PDF.

The codes contain metadata about chunk number (e.g. “007 of 103”) to enable out-of-order scanning and reconstruction.

images/qrxfil_description.png

Dependencies

qrxfil is built in Rust, relying mostly on:

  • base64, to encode binary in ASCII characters
  • qrcode, to generate the codes themselves
  • serde for CSV parsing
  • pandoc and LaTeX (optional) for PDF generation

MSRV

The Minimimum Supported Rust Version of this project is 1.42.0, currently limited by the pdf library used during testing.

Installation

Use cargo deb to generate a Debian package on linux that provides the qrxfil command.

cargo deb
sudo dpkg -i target/debian/qrxfil_0.3.1_amd64.deb

Usage

To generate QR chunks for exfiltration:

qrxfil exfil file_to_exfil.txt qr_output_folder/

Now output_folder/ will contain numbered images to scan.

For paper-based backups of important files, we can output a PDF (requires pandoc package and a working \LaTeX compiler):

qrxfil pdfprint file_to_exfil.txt qr_output_folder/

It looks like this:

images/pdf_export_example_pandoc.png

Once these QR images are scanned (on your own), we can reconstruct the file from a newline-delimited chunk file:

qrxfil restore newline_delimited_chunks.txt restored_file.txt

Or using BinaryEye app on Android, use the scan export in “CSV with semicolon delimiters” and restore via

qrxfil restore --csv binaryeye_export.csv restored_file.txt

Development

Because rust, use cargo to build the binary

cargo build

Run tests:

cargo test

This project uses pre-commit to enforce code guidelines, and has a sample Makefile for ease of use; Run all those checks in one go with:

make

Github Actions runs similar checks for Continuous Integration purposes on master and in pull requests.

FAQ

Why build this?

Most simply: To learn Rust with a fun, silly project!

But also because I like local-first solutions: Why upload stuff to The Cloud™ when you’re just trying to move <1MB files across the room?

My usecase started with synchronizing my dotfiles across computers, but without using Github. This led me to learn about how git bundling works, sending file-based dumps of a repo, branch or commit, moving it like files on a USB stick. I looked to using bluetooth for that, which worked OK (had to pretend these were “PDFs” for “security reasons”) and thought “what are other creative ways to send data?”.

There are a lot of options for “covert channels” and other side-channels to exploit for this, but I felt QR codes have the unique advantage of being clearly recognizeable by users (“that thing you’ve seen at the bus stop”), but not always clearly identified as “carrying data” beyond simple links.

I built a prototype in bash in an afternoon, using split and qrencode (see it in scripts/), adding chunk identifying prefix. Another motivation is critical file paper backups, such as GPG key backups on paper for physical copies. See the pdfprint subcommand above.

If I can bring qrxfil inside an air-gapped fence, why not send back data via that channel instead of QR codes?

I don’t have a good answer, you caught me: this isn’t really a security tool, just a fun prototype to send < 1MB of data across two computers in a creative way.

If I really had to defend this, I’d say that my usecase is “work computers” where you’re trusted enough to write code on (including getting a compiler and going on the internet) but with basic network auditing in place to detect foreign network connections, and using SSH to connect to your home computer from local wifi would be too risky.

The “data exfiltration” aspect of this project is just a gimmick to get people to think about security implications of data exfiltration, as it’s a fun mis-application of technology.

License

This project uses GPL-v3-or-later license, see file LICENSE.txt