50
37
First, a confession: no, I didn't do the backups I should have.
Second, the situation:
I have a Dell XPS 9550 with a solid state disk running Fedora 25.
I was working on a file and tried to save it when I was told I was trying to save to a read-only filesystem. Turns out my filesystem is read-only now and there are i/o errors all over the place.
I was able to save some of the files by emailing them to myself through an open web browser, but that crashed and I'm unable to relaunch it. But I still have files of interest open in an editor. I can't seem to save the files anywhere, but I can copy their contents. If only I could find a way to exfiltrate the file contents, I could save myself months of work.
But there are some horrible limitations. I attempted to insert a USB drive, but no device appears to represent it, and the mount
command dies with a segfault. I can attempt to ssh to another computer, but I get "bus error" and it dies. ping
, dmesg
, ifconfig
, none of these work. But I do have vim
and less
and ls
and can spawn new bash
instances.
No lynx
, no firefox
, no google-chrome
. There's no DVD drive.
Basically it seems my SSD has died. Or maybe the whole motherboard. I have documents of great value still in memory, I have an IP address and network connection, I can run a few random commands and have 3500 more on the path that I could try.
cat
and gcc
seem to work. I can write to files in /tmp. I have a running ipython
instance that still seems to work.
So... what I've tried so far has failed. But I feel like there are still a thousand possibilities. What am I not considering? How could I possibly get these files off of my dying computer?
There must be a way.
UPDATE: New stuff:
- I lost my network connection due to my own stupidity.
- I wrote a Python script to replace
cp
andcp -r
- Unless I find some way to create a
/dev
entry for the SD card, or for USB drives, then my best bets for getting data out seem to be the screen and possibly the speakers/audio cable. - I'm writing a script to try reading files and output which ones are readable.
Suggestions still very welcome!
UPDATE 2: Newer stuff:
- On the dying computer I wrote a Python script that will read a file bit by bit and try to convey those bits by flashing the screen one color or another. Right now it's trying to do a two-bit code where red, green, blue, and white all represent a two-bit pair. This isn't working that well, though, so I might just switch to two colors and do one bit at a time.
- On my other laptop (the trusty old Thinkpad that I gave up for this hot new XPS) I wrote a script that reads from the webcam using the OpenCV Python library. The idea is to have it decode the codes sent by the other computer. The trouble is that the framerate from the camera is something like 15 frames per second, which means if I had a perfect, errorless transfer my maximum data rate would be 30 bits per second, i.e. 225 bytes per second. That's 324k per day.
- On the dying XPS I can use
tar
to pack the desired files into a single archive, which is 1.7 MB. Unfortunately,gzip
,bzip2
,xz
,lzop
and whatever compression utilities are unavailable. BUT using Python'szlib
module I can compress this file down to 820KB. Given that size, I could probably get this thing sent over in a couple of days. - Because this transfer method will likely be very error prone, I'm going to implement Hamming codes on the XPS to add some error correction as I transmit the data.
- Likely there will be complications because that's what happens, but at least it seems somehow feasible to get this data out!
- Since this is still a pretty sucky way of sending data, I looked more into USB serial drivers. The modules I've tried to load (
usb-serial-simple
,usb-debug
,safe-serial
) give i/o errors. I don't think it's built in to the kernel, either, because there are no /dev/ttyUSB* devices present.
Thanks for everyone's suggestions thus far---I know this isn't even a well-defined question since you guys don't know in advance which programs/files can be read or not. Still open to better suggestions than this video approach!
UPDATE 3: Newest stuff
- I got a PS3 Eye webcam and, after disabling its automatic gain and exposure, am successfully reading data off of the XPS, albeit at an errorful 1 byte per second. This is a great success---the first data exfiltrated! But the rate is too slow to get my 820KB out in any sort of reasonable time, and the error rate is too high.
- The problem is that writing to the terminal is too slow. The screen updates aren't anything like instantaneous, thanks (I think) to the slowness of the
urxvt
terminal emulator that I have access to. - I discovered that I have access to a Rust compiler on the XPS. I rewrote the transmission script using Rust to see if that would improve the terminal refresh speed, but it didn't help.
- Because I'm unlikely to be able to increase the framerate, I'll have to try to increase how much data I get per frame. My current approach looks something like this:
The right half is still a clock signal, flashing on and off to mark the arrival of new frames. But the left is now a grid where each cell is marked by a red square in the corner, and then the green cell to the right and down from the red square is flashed on and off to indicate a bit. The red squares should let the receiving computer calibrate where the cells are located. I haven't got any data across this way yet, but it's what I'm working on.
- Someone suggested that I look into writing QR codes instead of these ad hoc color patterns. I'm going to look into that, too, and perhaps implement that instead of this grid approach. The error correction would be a nice win, as well as being able to use standard libraries to decode.
- I learned that I have access to libasound (the ALSA sound library), but not to the header files associated with it (
alsa/asoundlib.h
or whatever). If anyone knows how to make use of a shared library without the headers, or can help me write just the right header to let me produce audio output, then I could have an audio-based way of getting the files out. - Alternately, if someone could help me manipulate the USB devices without access to libusb then maybe I could do something with that?
Moving forward!
UPDATE 4: audio output produced!
User Francesco Noferi has done some great work helping me utilize the ALSA library mentioned in the previous update. The C compiler had a problem, but using the Rust compiler I was able to use the FFI to call directly into libasound
. I've now played a bunch of my data over audio and it sounds like music to my ears! Still need to get a real communication channel established, but I'm feeling very hopeful. At this point my job is basically to implement a modem, so if anybody has any guidance on good ways to do that I'm all ears. Ideally modulation that's easy to implement by hand and demodulation for which there's an existing library I can use. Since this can go directly over an audio cable and not through the phone network, theoretically we can do much better than 56kbps or whatever the standard was back in the day, but in practice who knows what we'll get.
Thanks to everybody following along here and at /r/techsupportmacgyver and at /r/rust contributing so many excellent suggestions. Going to get this "modem" implemented soon and then I'll finish this up with an epilogue. I think I might put my code up somewhere for other desperate folks to make use of in the future---maybe even a repository of weird exfiltration tools that are easy to type into a dying machine by hand? We'll see what happens.
UPDATE 5: It took me a long time wrestling with ALSA and my cheap StarTech USB audio capture device (no builtin line in on the receiving laptop), and many false starts trying to roll my own transmission protocol, but finally under the advice of some Ham radio enthusiast friends of mine I implemented the RTTY line protocol running at 150 baud, which in practice gives me maybe about 10 bytes per second. It's not super fast but it's fairly reliable. And I'm very nearly done transferring my 820KB file, verified using CRC32 checksums (using the crc32 functionality from Python's zlib
module, which I have access to). So I'm declaring victory, and want to give my thanks once again! I'll spend some more time finding further files that are readable and which I can transfer, but the foundation is in place. It's been fun working with you all!
FINAL UPDATE:
On the dying machine:
$ tar cf ./files
$ ./checksum.py ./files.tar 9999999
Part 1 checksum: -1459633665
$ ./zlib_compress.py ./files.tar
$ ./checksum.py ./files.tar.z 9999999
Part 1 checksum: -378365928
$ ./transmit_rust/target/debug/transmit ./files.tar.z
Transmitting files.tar.gz over audio using RTTY
Period size: 2048
Sample rate: 44100
Samples per bit: 294
Sending start signal.
Transmitting data.
nread: 2048
nread: 2048
...
nread: 2048
nread: 208
Transmission complete. Sending hold signal.
On the rescue machine:
$ minimodem --rx -8 --rx-one -R 44100 -S 915 -M 1085 --startbits 3
--stopbits 2 --alsa=1 150 -q > ./files.tar.z
$ ./checksum.py ./files.tar.z
Part 1 checksum: -378365928
$ ./zlib_decompress.py ./files.tar.z
$ ./checksum.py ./files.tar
Part 1 checksum: -1459633665
:-)
Do you have a serial port? – Mokubai – 2017-11-16T08:16:19.530
5
Related: Unix Recovery Legend.
– G-Man Says 'Reinstate Monica' – 2017-11-16T08:23:49.3273Go to the directory where you have the files and issue the command
python -m SimpleHTTPServer
.Now you are sharing the files through an http server in port 8000. Open a browser in other device in the same network and type the following :
http://<IP address>:8000
and start to download everything you can. – jcbermu – 2017-11-16T08:36:09.300There's a new and extremely unfortunate wrinkle: I made the stupid, stupid mistake of closing my laptop, which is my habit before going to bed. It went to sleep, and by the time I woke it back up, it had given up its IP address. Now the Network Manager applet simply says "device not ready", and I can't run
iwconfig
or anything like that. – Josh Hansen – 2017-11-16T09:24:46.947I was just getting around to getting Python to serve up my files over a socket connection, but no, I did this and shot myself in the foot. – Josh Hansen – 2017-11-16T09:25:09.563
The good news: I can run
– Josh Hansen – 2017-11-16T09:26:14.967dhclient
. I understand that given the proper configuration dhclient itself can connect to the wifi. See https://unix.stackexchange.com/questions/92799/connecting-to-wifi-network-through-command-lineHere's my current best idea but which sounds like a ton of work: I'm unlikely to get the network back up, and can't seem to write to USB or to the SD card slot. BUT the screen is working just fine. If I can write a python script that essentially flashes the screen on and off, I could make a sort of morse code-ish thing that my other laptop could read through its camera. I have about 1 MB to transfer, so 8 million bits. Or get the network back up somehow and serve the files over the network. – Josh Hansen – 2017-11-16T09:35:04.410
@Mokubai: there are USB ports. Any ideas? – Josh Hansen – 2017-11-16T09:36:02.740
1I was going to suggest
cat
to send the files over a serial port. USB to serial converter might work if drivers are built into the kernel. – Mokubai – 2017-11-16T09:44:59.603boot to a USB drive, and use safecopy to make a disk image to a new drive. http://safecopy.sourceforge.net/
– uSlackr – 2017-11-16T21:51:18.293Encode everything as QR codes and take photos. – Ignacio Vazquez-Abrams – 2017-11-16T23:57:54.643
@Mokubai: it seems I have the usb serial module installed or built-in, but I'm not sure if there's a device for it in /dev. Do I have to specify some parameters for the module? – Josh Hansen – 2017-11-17T01:20:00.170
Not normally, they usually show up as
ttyS0
or something similar. I cannot remember how to configure it though. – Mokubai – 2017-11-17T06:53:29.2232Great piece of geek stuff you've got here. I wish I could upvote twice. – Kamil Maciorowski – 2017-11-29T18:06:35.070
Great geek yet has no backups. :/ – Little Helper – 2017-11-29T21:42:59.983
1
How about cooling the crap out of the RAM to reduce volatility and moving it to an alternate XPS? https://en.wikipedia.org/wiki/Cold_boot_attack
– root – 2017-11-29T23:47:57.940Do you have an Ethernet port and cable? Bringing up wifi using barebone Linux command-line tools is a Sisyphean task, but Ethernet should be doable.
ifconfig eth0 10.0.0.1
on one laptop;ifconfig eth0 10.0.0.2
on the other, and then you can use netcat or Python sockets to transfer files. – Marius Gedminas – 2017-11-30T15:28:15.447This page on urxvt says you can disable the matcher plugin to improve performance: https://wiki.archlinux.org/index.php/Rxvt-unicode
– Jan – 2017-11-30T17:40:25.000First of all, great work so far. This isn't so much a Superuser Q&A anymore as an evenings entertaining read. Keep up the good work, and keep us posted! grabs popcorn. How about grabbing a video recording device of some sort (Camera, Phone, whatever), and record the screen output with higher framerate and resolution than what your PS3 camera can process? That way you actually have a backup to work with if there's an error on the receiving end, plus you get more time to fiddle with the data, you can increase the framerate on the source PC, and apply other methods of reading the data later. – Jarmund – 2017-11-30T19:38:06.343
1@MariusGedminas, alas, no builtin ethernet :-/ – Josh Hansen – 2017-12-01T18:23:42.337
@Jarmund: glad you're enjoying the show! Making a video backup is a good idea. I need to do that. The PS3 Eye can do 640x480 up to 60FPS and 320x240 up to 120FPS. – Josh Hansen – 2017-12-01T18:25:49.843
@Jan: that matcher plugin looks like a likely culprit. If this new audio approach doesn't work out then that will be the first thing I try. – Josh Hansen – 2017-12-01T18:26:41.043
@JoshHansen might want to try frequency-shift keying; that's extremely easy to implement: you could just fill asound frames from a cos() with varying frequency based on the current bit.
– Liam Marshall – 2017-12-02T03:23:56.5071Somewhat off-topic, but it would be great if you could link the related reddit threads so we can see what's been suggested there. – Bob – 2017-12-02T08:53:58.990
@Bob: just added some links in the body of Update 4 above. – Josh Hansen – 2017-12-03T07:41:16.877
1
@LiamMarshall: looking into it. I found https://github.com/casebeer/afsk which seems like a potential model I could follow.
– Josh Hansen – 2017-12-03T07:42:33.9601this was one hell of a ride, congrats! – Francesco Noferi – 2017-12-09T13:37:38.063
1Dude. This is the most epic question I've seen on the site so far. I kinda hope you document this in detail for the edification of the masses - its pretty much the sort of thing I'd expect on hackaday or the like ;p – Journeyman Geek – 2017-12-09T13:40:49.277
@FrancescoNoferi Thanks in no small part to you!
Regarding the final update, that's more or less how it went down, but it was slightly more complicated.
checksum.py
lets you calculate checksums for different chunks of a file, which helped me find some sections I had to retransmit. Then I usedhead
andcat
to reassemble the good chunks from multiple transmissions. – Josh Hansen – 2017-12-09T16:55:11.377