Under The Covers
Figure 16 shows the main board of the TS-101. It's hard to make out the identity of a couple of the chips, due to them being covered with thermal paste that created a seal between the chips and a bracket connected to the aluminum chassis. The CPU is from the Freescale PowerQUICC family. SATA support is provided by a Silicon Image 3512 chip; the USB controller from NEC is from the µPD720101 family; and the Ethernet controller is an Intel 82540EM.
Figure 16: TS-101 Motherboard (click to enlarge)
When possible, I like to see what is going on inside a NAS under review. To this end, I started looking for a way to get command-line access so I could poke around. A network port-scan turned up nothing promising, so I turned to the web interface. The web file manager allows access to files and directories in the data partition, so I tried a trick I've had success with before. By tacking on a "/../" to the top-level directory URL, I've often been able to pop up into the operating system directories. Not this time - Qnap properly rejected my attempt to break out, so I kept looking.
Since the web server supports PHP, an obvious place to get access was with a PHP script. To try this out, I wrote a simple PHP script that took input from a form, passed the input on to an operating system shell, and printed the output. Success. Using this technique, I could execute arbitrary commands to see all sorts of details (see Figure 17).
Figure 17: Custom PHP shell
Like nearly all consumer-level NAS devices, Busybox was heavily used, and the operating system was based on a Linux 220.127.116.11 kernel. Both Apache and thttpd webservers were in use, Samba and aftpd were employed for network file serving, and rsync was running for backups. The boot messages told me that 64 MB was installed, and the filesystem on the disk was ext3.
When I examined the set of running processes I noticed that the Apache web server, running under the "guest" account, was serving up user pages. According to the password file, which I could view (but not modify), this was an unprivileged account, so any command I executed through my PHP script would be executed as an unprivileged user. Surely I could do better than that! The thttpd web server, on the other hand, ran under the "administrator" user, which was a root (system level) account, giving it full access to the operating system. This server had no PHP support, so it was time to get a bit more creative.
Using this technique, and after a few false starts, I succeeded in adding the guest account to the administrator group. This meant that commands I ran from my PHP script would have administrator group privileges. This was an escalation of privileges, but I still didn't have full access, so I needed to keep looking. Poking around some more with my PHP script, I noticed that the password file was writable by the users in the administrator group - this was an easy path to root using one more level of privilege escalation. Using a command executed from my PHP script, I copied the password file to one of my network shares, edited it so that the guest account had a user-id of 0 (root) and then copied it back. Now the guest user was the same as the root user.
Any command I now executed from my script would have the privilege to do whatever I wanted. I could install new software, modify the configuration of existing software, load new drivers, and more. Note that these steps required administrator access to start with, so this hack didn't expose a vulnerability to standard users.
My success was a bit short-lived, however. I found that the next time I rebooted, the Apache web server failed to start. It evidently wasn't happy starting up under a root-level account. Completing this little hack would have required additional investigation, and more time than I had at the moment, so I reinitialized the TS-101 back to its normal state and moved on.