This post discusses techniques specific to reverse-engineering a device I personally purchased. In the U.S., Section 1201 of the DMCA includes exemptions for security research, right-to-repair, and personal-use modifications. I am not a lawyer; if you’re doing similar work and want professional guidance, the EFF runs a free legal hotline at info@eff.org for security researchers and reverse engineers.
Naked Labs stopped supporting their hardware in October 2023. I own one of their mirrors. I bought it, it sat in my hallway, and the day api.nakedfit.net went dark it became a very expensive aluminium slab. This post is how I made mine work again, and it is written for the small r/3DScanning community of other owners sitting on the same stranded hardware.
The previous post ended with “I need a shell on the mirror, the obvious paths are dead, next session is the SSD pull.” This was that next session. The SSD pull turned out to be unnecessary. A much simpler route gives an owner a root shell on their own device in about 30 minutes if they have the hardware.
The short version: open the case, plug an external monitor into the motherboard’s DisplayPort, plug a USB keyboard into the bottom USB-C port, power on, log in as root with no password.
The login: a manufacturer debug setting left in production
I spent a chunk of this project trying the obvious defaults against the mirror’s open SSH port. Vendor defaults, Yocto defaults, the usual brand and hostname-derived guesses, the Prism Labs variants (Naked Labs was renamed Prism Labs after the shutdown). Dozens of them, across two sessions. None worked.
The reason none worked is that there is nothing to guess. The root password really is empty. This looks like the manufacturer’s debug configuration, the kind of thing an engineer leaves set on the bench, that simply shipped in the production image and was never tightened.
The twist is why I kept missing it. OpenSSH ships with PermitEmptyPasswords no, and Naked Labs left that default in place, so the SSH server flatly refuses an empty password. But the local console login (the tty1 prompt you get on a physically attached keyboard) authenticates through a separate PAM path, and that one does accept the empty password. Same account, same empty password, two different front doors with two different policies.
flowchart TD
A["Log in as root with an empty password"] --> B{"Which front door?"}
B -->|"Over the network (sshd)"| C["PermitEmptyPasswords no, rejected"]
B -->|"Local tty1 console"| D["Console PAM accepts empty, root shell"]For most of this project the blocker was getting a keyboard physically onto the device at all, because the mirror has no consumer-accessible display or input. But once I had the case open anyway (for the eventually unnecessary SSD pull), the motherboard’s internal DisplayPort and the bottom-of-case USB-C port were right there. These are how the device was debugged on the bench, and on my unit they still work.
Hardware you need
Total cost, if you don’t already own this stuff, is under $40.
| Item | Notes |
|---|---|
| Phillips #0 or #1 screwdriver | One screw is hidden under the Naked sticker at the top of the back panel. |
| Plastic pry tool / spudger | For the side divots. A guitar pick or a flat plastic chopstick works in a pinch. Avoid metal, which scratches the case. |
| External monitor with DisplayPort or HDMI input | Most modern monitors. If yours is HDMI-only, you’ll need a DisplayPort to HDMI adapter (DP-side male, HDMI-side female). The motherboard side is DP. |
| DisplayPort cable | Long enough to reach from the mirror’s interior to wherever the monitor is. About 6 ft is comfortable. |
| USB keyboard | Any one. Function keys not required. Bluetooth keyboards won’t work (no driver loaded at boot). |
| USB-A to USB-C adapter | The bottom-of-case port is USB-C. Your keyboard is almost certainly USB-A. A $3 adapter solves it. |
If you don’t have an external monitor capable of DisplayPort, a cheap “portable monitor” off Amazon ($50 to $70, the laptop-companion kind with DisplayPort and HDMI inputs) works fine.
What you don’t need, despite various Reddit suggestions, is an M.2 SSD enclosure. That was my original plan, and I even bought one (a $25 ORICO-style combo). It is not necessary unless this method fails for you. For the record, the mirror’s M.2 SSD is SATA, not NVMe (model Intel SSD E5400s). If you do buy an enclosure for any reason, get one explicitly labelled “M.2 SATA” or “NVMe + SATA combo.” Pure-NVMe enclosures will not detect the drive.
Opening the case
This is already documented well by whoamarcos in the dormant r/3DScanning teardown thread from a few years ago. Briefly:
- Power off and unplug the mirror. Wait a minute for the capacitors to drain.
- Peel the round “Naked” sticker at the top of the back panel. There’s a Phillips screw under it. Remove that screw.
- The back panel is otherwise held by four spring clips along each side. Insert your pry tool at the bottom-most divot on one side, work it about half an inch deep until you feel the rubber seal release, then another quarter inch until the clip pops. Move up to the next divot. Work both sides progressively, not one side fully.
- Lift the back clamshell off and set it aside. You don’t need to disconnect any cables. The back is just a passive cover.
If you’re nervous about prying the case, the worst-case outcome is a broken plastic clip, which is cosmetic. The internal electronics are not at risk from this step.
Finding the ports
Once the back is off, you’re looking at a roughly Mini-ITX-shaped motherboard (an H110-SF100 industrial board, Intel H110 chipset, Skylake/Kaby Lake era Celeron). Two ports matter:
- DisplayPort. There is one DisplayPort connector on the rear I/O area of the motherboard. On my unit it had a cable plugged into it, routed internally. You can either follow that cable to see what it reaches (it goes to a service header, not to any display the user sees) and unplug it, or use a different DP port if your unit has multiple. Connect your external monitor to that port.
- USB-C (bottom of case). The bottom of the mirror has an external USB-C port. It’s data-capable and wired directly to the motherboard. I confirmed this by noting that the scale charges through it. Plug your USB-A-to-USB-C adapter in there, then your keyboard.
Internal USB-A ports also exist on the motherboard and would work, but they’re competing with internal devices (the LED ring, the cameras). The bottom USB-C is the cleanest path.
Don’t unplug any of the existing internal cables. Three of them connect to the Intel RealSense cameras (USB 3.0), one goes to the LED ring, one to internal status sensors. Touching them risks bent pins or a failed boot self-test.
Booting and logging in
- Power on the monitor and select its DisplayPort input.
- Plug the mirror’s power back in (or hit the power button, depending on your unit).
- Watch the monitor. After about 5 seconds you’ll see a lot of
[ OK ]lines streaming past. That’s systemd bringing up Yocto Linux. After about 30 seconds it stops at aSquirrelFit login:prompt. - Type
rootand press Enter. - At
Password:just press Enter, leaving it empty. - You land in a root shell. The prompt looks something like:
root@SquirrelFit:~#That’s it. You’re in.
sequenceDiagram
participant Me
participant Monitor as External monitor (DisplayPort)
participant Mirror
Me->>Mirror: power on
Mirror->>Monitor: kernel log, then systemd [ OK ] lines
Note over Mirror: about 30s to reach the login prompt
Monitor-->>Me: SquirrelFit login:
Me->>Mirror: root
Mirror-->>Me: Password:
Me->>Mirror: (empty) Enter
Mirror-->>Me: root@SquirrelFit:~#If the empty password fails for some reason, it’s worth trying a few obvious vendor defaults at the console: the usual Yocto build-tree password, a brand-derived one, or the unit’s own serial number. My own round of default-guessing ruled out all the obvious ones, but firmware variants exist. Some Naked units shipped on older or newer build trains, and Naked Labs may have changed defaults across versions.
Planting an SSH key so you never need the monitor again
The monitor-plus-USB-keyboard approach gets you in once. To get persistent network access to your own device without keeping the case open, plant your Mac or Linux box’s SSH public key. Three things to know first:
- The rootfs is mounted read-only by default. You need to remount it read-write to add a file:
mount -o remount,rw / - root’s home is
/home/root, not/root./rootliterally does not exist on the filesystem. If you put your authorized_keys file in/root/.ssh/, sshd will silently ignore it, because that is not where the user’s home points. This caught me and cost half an hour of head-scratching. Confirm withecho $HOME, which prints/home/root(itself a symlink to/data/root). - WiFi must be configured for SSH to reach the device. The static IP I set (
<mirror-ip>) only resolves once the wireless interface is associated to the access point. The mirror remembers WiFi profiles in/data/etc/NetworkManager/system-connections/, and the iPhone debug app’s WiFi sheet can configure new ones over BLE.
Sequence from the mirror’s console:
mount -o remount,rw /mkdir -p /home/root/.ssh && chmod 700 /home/root/.sshThen, to get your public key into the file, the easiest approach is an HTTP transfer from the machine that has your key. On your Mac:
cp ~/.ssh/id_ed25519.pub /tmp/key.pubcd /tmp && python3 -m http.server 8765 --bind 0.0.0.0If macOS pops up “Allow Python to receive network access?” click Allow. (This caught me too. The first attempt got “connection refused” until I clicked Allow. macOS shows this even when the Application Firewall reports as disabled.)
On the mirror, with your Mac’s LAN IP substituted in:
curl -o /home/root/.ssh/authorized_keys http://<my-mac-lan-ip>:8765/key.pubchmod 600 /home/root/.ssh/authorized_keysTest from the Mac:
ssh root@<mirror-ip>The whole round-trip, drawn out:
sequenceDiagram
participant Mac as My Mac
participant Mirror
Mac->>Mac: serve id_ed25519.pub over local HTTP
Mirror->>Mac: curl the pubkey into /home/root/.ssh/authorized_keys
Mac->>Mirror: ssh root@<mirror-ip> (key auth)
Mirror-->>Mac: root shell, no monitor neededIf you set up an SSH config entry, ssh mirror works just as well:
Host mirror HostName <mirror-ip> User root IdentityFile ~/.ssh/id_ed25519What goes wrong (the gotchas in chronological order)
These are the dead ends I hit in real time. If you attempt this on your own mirror, hitting one of them shouldn’t ruin your evening.
- “My SSD enclosure doesn’t see the Naked drive.” The mirror’s SSD is M.2 SATA, not NVMe. Confirm by looking at the connector edge: B+M keying (two notches) is SATA, M keying (one notch on the right) is NVMe. Don’t buy an NVMe-only enclosure.
- “My USB keyboard isn’t typing anything.” Test with caps-lock first. Does the keyboard LED toggle when you press caps lock? If yes, USB is alive on that port and you just don’t see output yet. If no, try a different USB port (one of the internal USB-A ones on the motherboard) or a different keyboard.
- “The monitor shows nothing at all.” Boot is fast, about 20 to 30 seconds to the login prompt. If you blink you can miss the kernel log. Wait a full minute before concluding the DP port is dead. If you really see nothing, try the other DisplayPort on the motherboard if your unit has more than one.
- “mkdir fails with ‘Read-only file system’.” You haven’t remounted
/read-write yet. Runmount -o remount,rw /first. - “SSH still rejects my key after I put it in
/root/.ssh/.” Wrong path. Move it to/home/root/.ssh/and verify withecho $HOME. root’s home is/home/root, which symlinks to/data/root. - “curl gets ‘no route to host’ or ‘connection refused’ when fetching the pubkey.” Two separate causes: routing or firewall. On your Mac,
pingthe mirror’s IP first to confirm reachability. Thenlsof -i :8765to confirm the HTTP server is listening. macOS shows a permission dialog the first time Python opens an inbound port. Accept it. - “BusyBox
head -5doesn’t work.” Yocto uses BusyBox 1.27, which doesn’t accept GNU shortcuts. Usehead -n 5. Many other GNU flags will surprise you:tar --exclude=doesn’t work,ssisn’t installed, and so on. Adjust as you go.
Reversibility
Everything above is non-destructive. If you want to undo it:
- The case clips back together. Replace the screw, re-stick the Naked sticker.
- The SSH pubkey can be removed with
rm /home/root/.ssh/authorized_keys(you’d need to be in the shell, of course). - The rootfs remount goes back to read-only on reboot.
The mirror doesn’t notice that any of this happened. It boots, runs the same coordinator service, makes the same (now unanswered) cloud API calls, and reports the same coordinatorStatus: ONLINE to its own internal state file. Nothing is bricked, nothing is changed, you just have a shell on your own device now.
Follow along
Procedure 14-AThe story above has the dead ends left in on purpose. If you own one of these and just want to get back into your own device, here’s the clean sequence:
- 1Power off, unplug, and open the back panel. One hidden Phillips screw under the round Naked sticker, then four spring clips per side worked loose progressively with a plastic spudger. Lift the passive back cover off.
- 2Connect a monitor to the motherboard’s DisplayPort and a USB keyboard to the bottom-of-case USB-C port (via a USB-A to USB-C adapter). Leave every internal cable alone.
- 3Power on and wait about 30 seconds for the
SquirrelFit login:prompt to appear on the monitor. - 4Log in as
rootwith an empty password. Just press Enter at thePassword:prompt. You’re now atroot@SquirrelFit:~#. - 5Plant your SSH key for keyboard-free access later. Remount the rootfs writable (
mount -o remount,rw /), create/home/root/.ssh(not/root/.ssh), and pull your public key in over a one-off local HTTP server. Setchmod 700on the directory andchmod 600onauthorized_keys. - 6Confirm the device is on WiFi, then
ssh root@<mirror-ip>from your own machine. From here on you don’t need the monitor.
That gets you back to a working shell on your own device. Making the device actually useful again is the next post’s problem, and yours can be too.