James Stanley


Secrets of the Medtronic MyCareLink Patient Monitor

Sun 4 December 2016
Tagged: electronics

I have acquired a "Medtronic MyCareLink Patient Monitor 24950" and have been playing with it a little this weekend. It looks like this:

The device is no longer needed owing to the unfortunate death of its previous owner. Before giving it to me, people did try to return the device to the NHS but they did not want it and didn't seem to know what to do with it. So, game on.

I initially had no idea what the device was for. When you turn it on, it eventually gives a graphical hint that you should hold the handheld piece up to your chest:

I gather it is some sort of pacemaker monitor. In any event, the light did not turn green when I held it up to my chest. (I do not have a pacemaker).

(Update 2016-12-04: alphaoverlord on HN points out it's for an "implantable loop recorder" for heart monitoring, and not for a pacemaker.)

I opened up the base unit, a task complicated by the use of some unusual 5-pointed security screws (fortunately they were made of your standard Chinesium metal and quickly succumbed to my 6-pointed bit). Inside, I found a Huawei USB GSM dongle, with a SIM card inside that.

I also found a suitably-enticing MicroSD card. The only "MicroSD card reader" I have is a Garmin VIRB video camera. So I inserted the MicroSD card into my Garmin VIRB video camera, which I plugged into the laptop.

The MicroSD card has 4 partitions. One is a FAT-formatted boot partition which seems to contain U-Boot (and now also some Garmin-related nonsense thanks to my MicroSD card reader).

The other 3 partitions are all ext3. Two of them contain a bunch of files named things like ECRYPTFS_FNEK_ENCRYPTED.FWYdhbehxfVBr-TWPN4xB6NkyyaRqzxo8mZKbXH2s0PdbqIxnZvdHmm1ok-- (apparently eCyryptfs-encrypted), but the final partition is more promising: it contains a Linux root filesystem. Some investigation revealed that this is specifically a MontaVista Linux system.

I examined a few binaries and found that the device has an ARM CPU, not too surprising. I was more fascinated with what might be on the encrypted partitions. Obviously, since the device boots and runs without asking for a password, the decryption credentials must be in here somewhere.

I grepped the root filesystem for interesting keywords (like "ecryptfs") and came across a script in /etc/init.d/startupservices containing, among other things:

ENCRYPT_DIR=/usr/sbin
ENCRYPT_UTIL=eis3920
...
echo "Try for Decrypting Partition..."
# Add mount utility here
$ENCRYPT_DIR/$ENCRYPT_UTIL 1>/dev/null 2>&1

Aha! So this mysteriously-named /usr/sbin/eis3920 program is responsible for the decryption. eis3920 is an ARM binary, but running strings on it came up with some items of interest:

...
/sys/devices/platform/omap/omap_i2c.2/i2c-2/2-0057/eeprom
%s%s%s%s%s
/home/root
.ecryptfs
sig-cache.txt
ecryptfs_fnek_sig=
%s%s%s%s%s%s%s%s%s%s%s%s
mount -t ecryptfs 
 -o 
key=passphrase:passwd=
,ecryptfs_cipher=aes,
ecryptfs_key_bytes=16,
ecryptfs_passthrough,
no_sig_cache,
ecryptfs_enable_filename_crypto=y,
...

Highlighted in bold, we can see a.) that it has something to do with an eeprom device, b.) that it does indeed appear to mount some filesystem with ecryptfs, and c.) unfortunately the password is not present. The password is most likely hidden in the eeprom. Darn!

I am not enough of a hardware hacker to be able to even identify the eeprom on the circuit board, let alone interact with it and retrieve its contents.

Fortunately I don't have to! On this MicroSD card I have a Linux system that is already setup to run on this hardware, and includes a tool that will conveniently read the password from the eeprom and pass it to mount. So I moved /bin/mount to /bin/mount.orig and wrote a script in /bin/mount that logs its arguments to the filesystem before calling mount.orig:

#!/bin/sh
echo "$@" >> /mount-args.log
mount.orig "$@"

Then I put the MicroSD card back in the Medtronic, switched it on, waited for it to boot up, switched it off again, put the MicroSD card back in the Garmin again, and plugged the Garmin back into the laptop again.

Success! On the first try, no less. /mount-args.log now contained what I wanted to see. Most of the mount invocations were missing because the root filesystem is initially brought up readonly, but I did get:

-t ecryptfs /opt/ /opt/ -o key=passphrase:passwd=REDACTED,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough,no_sig_cache,ecryptfs_enable_filename_crypto=y,ecryptfs_fnek_sig=29b67aadf6b84ddc
-t ecryptfs /data/ /data/ -o key=passphrase:passwd=REDACTED,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough,no_sig_cache,ecryptfs_enable_filename_crypto=y,ecryptfs_fnek_sig=29b67aadf6b84ddc

Both /data and /opt use the same password (though it looks reasonably strong). With the password recovered, I was able to mount the encrypted partitions on my laptop, to peruse at my leisure. Boom.

I did not find any evidence of patient data stored on the device, even in the encrypted partitions. All I could find was the binaries and data for the Medtronic application, and it's not clear to me why it even needs to be encrypted.

From poking around I learnt a little about the architecure of the software. It seems to be a C# application that has been ported from Windows, consisting of a small handful of microservices. Apart from how distasteful it is to be running a C# Windows application on an embedded Linux device, it seems fairly well designed.

To send the data back to Medtronic it speaks to https://mgus.medtronic.com and https://mgnl.medtronic.com (which correspond to the US and the Netherlands, respectively). These servers present self-signed SSL certificates, but the certificate is bundled with the application and there is evidence that it checks it - arguably a more secure setup than relying on CA verification, especially given the recent WoSign shenanigans. They also use HTTP Basic auth, and the credentials are again stored in the eeprom. One of the microservices is called NVMemoryD and exposes access to the eeprom over DBus.

I took a look at /proc/cpuinfo and /proc/meminfo and learnt that it has an "ARMv7 Processor rev 2 (v7l)", and 128M of RAM. It might be interesting to use it like a Raspberry Pi if you could get some sort of interactivity. My current process for getting code executed on this device is far too tedious so I probably won't be using it a lot. Of course, with arbitrary root code execution, doing anything you want is "merely" an engineering exercise. So it ought to be possible to get a console on the display and use a USB keyboard. But I don't know that I have the appetite for that kind of project.

I briefly experimented with the GSM dongle - I wasn't able to make much use of it. I couldn't even ping anything. I haven't checked whether this SIM can only talk to Medtronic's servers, or if it has ran out of credit and can't be used at all.

I did take a look inside the handheld device as well. The FCC ids on the sticker show that it has some Bluetooth hardware inside, and I also found a large coil that seems to be some sort of NFC transceiver (?). From this I gather that the handheld device reads information off the pacemaker over NFC, and then transmits it to the base unit over Bluetooth, which then sends it to the HTTPS service over GSM, which makes it available to the patient's doctor or other medical staff. A chain of devices with increasing communications range and power requirements...

Anyway, that's what I've learnt about the Medtronic MyCareLink Patient Monitor. It was enjoyable to poke around a piece of medical equipment, as I have never had the chance before. Security-wise, perhaps if they had epoxied the MicroSD card to the board that would have kept me out, but a sufficiently-motivated attacker with hardware access will always succeed.



If you like my blog, please consider subscribing to the RSS feed or the mailing list: