File Transfer the Hard Way

I recently moved to a new apartment! There were…quite a lot of growing pains, to say the least.1 One particularly annoying one was that my Internet did not work right away: although Verizon claimed that I’d be able to self-install Fios at my new apartment, I was not able to get it working after plugging my router into either of the coaxial cables in my closet. The router itself was working fine—I could connect to it over WiFi—but I was unable to connect to the broader Internet.2

After spending about two or three hours on the phone with Verizon on Saturday and speaking to about five different people (and many more AI agents), they finally concluded that they would need to send a technician over to do the installation. Until then, I would not have Internet access on my laptop.3

But this posed a bit of a problem. You see, I had recently signed up for a class,4 and I had some assigned reading that I was supposed to finish this weekend, disseminated in the form of a PDF on a website. I could at least access the PDF on my phone thanks to mobile data, but I didn’t want to do the reading on my phone, so I had to figure out a way to get the PDF from my phone (a non-jail-broken iPhone) to my laptop (running Debian Linux). It’s 2026; file-sharing should be a solved problem, right?

My initial plan was to download the PDF on my phone, plug the phone into my computer, and then transfer the file over the same way I usually transfer pictures. (That is, by mounting the phone onto my file system with ifuse, and then copying the PDF over.) Unfortunately, this did not go very smoothly; I soon realized that iPhone file systems are quite locked down, and it’s not easy to get anything other than pictures off the phone this way. Other apps don’t expose their data to connected computers.

So, it was back to the drawing board. After brainstorming various data exfiltration techniques with my good friend Claude, we landed on the following plan: we’d transfer the file over LAN by starting up a web server on my laptop and then uploading it on my phone.

Prompting Claude in the app on my phone, I had it implement a basic file-sharing website as a single Python script. I even had it throw in some bells and whistles, like a nice button and a dark mode theme. Then the problem became: how was I to get this Python script from my phone to my laptop?5

My first idea was to encode this in a QR code, which I’d read with my laptop’s webcam, but unfortunately I didn’t already have any decoders installed on my laptop, and I obviously couldn’t download a new one. I then tried the same thing with OCR, but to no avail.

But then it struck me: since I knew I could transfer images from my phone to my computer, why couldn’t I just smuggle the bytes of the Python script inside an image file?6 (This process is in general known as steganography, and caused my Claude session to trip Anthropic’s cyber-risk safeguards. I had to downgrade to an older model to continue.) The precise details are not super important, but basically the easiest way to do this is just to append your payload after the IEND chunk; this causes image renderers to ignore your data. I had Claude generate a PNG containing a one-by-one white pixel with the server script appended; I saved this Trojan-horse PNG to my phone’s photos library. I then mounted my phone and decoded the script:

$ ifuse ~/iphone
$ cp iphone/DCIM/114APPLE/IMG_4155.PNG server.png
$ ... # eyeball the bits at the end that look base64-ish
$ base64 -d <those bytes> > server.py
$ python server.py

And then Bob’s your uncle, as they say. I grabbed my laptop’s IP address:

$ ip addr show | rg "inet "

Finally, navigating to the site on my phone allowed me to upload the PDF, which immediately appeared in my home directory on my laptop. Success! Now I actually had to do the reading…


  1. Perhaps the most annoying was the leak from the upstairs apartment that happened two days after I moved in. But that’s not really relevant to this post; I just wanted to rant.↩︎

  2. Later, when the technician arrived, he explained that the coax cables were actually owned by Spectrum, and he’d need to install a separate Fios cable because the previous tenant had somehow cut the Fios cable and taken the ONT?↩︎

  3. There were a couple of other ideas I considered. One of them was “paying money to enable mobile hotspots,” but I’m still on my family plan, so that wasn’t something I could unilaterally do. Another was “going to a coffee shop,” but I had procrastinated on my homework until the night before it was due, so this was not an option. Finally, I considered knocking on my neighbor’s door to ask to use their Internet, but I didn’t want to be the crazy new neighbor.↩︎

  4. For the curious, the class is called the Foundations of New York, and discusses New York City’s government, and the history thereof.↩︎

  5. Okay fine, in practice it’s not too hard to manually type out a small program. Archaeologists tell us that in the neolithic age, people used to distribute software by putting the machine code in magazines, which readers would then type into their primitive computers! But I was having fun trying to see if there was a better way to exfiltrate data from the iPhone.↩︎

  6. You might ask: at this point, why not just transfer the whole PDF this way? That’s not a bad idea, but it felt less amusing than LAN, and also meant that I’d have to (1) ask Claude to encode a PNG and (2) plug my phone into my computer each time I wanted to transfer a file. Better to do this once for a script. Plus, the PDF was quite large, so it’d be more annoying.↩︎


Comments

Submit a comment

Your comment will be held for moderation. If needed, I'll reach out to the provided email address with moderation updates. Your email will not be publicly displayed.

Note: comments are still in beta. Let me know if anything is broken!