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.
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
The Minimimum Supported Rust Version of this project is 1.42.0
,
currently limited by the pdf
library used during testing.
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
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:
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
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.
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.
This project uses GPL-v3-or-later license, see file LICENSE.txt