Acer Aspire One D255: Unusual methods of implementing a desktop Firefox
Posted: Wed Jul 24, 2024 1:40 am
It all started when Morc brought back an Acer Aspire One D255 (PAV70) from TheMrKocour. It has an interesting dual-boot feature, running both Windows XP and Android with synchronization between them. It has an Intel Atom N450 CPU, 1GB of RAM, and a 160GB HDD. We decided to explore it a bit on the TeleviziaŠTB stream and found some interesting stuff.
We explored a bit of Windows XP, but except for the sync utility (which has some interesting options like Google Account sharing, email account syncing, and some file sharing), it was normal. When we booted into Android, at first, we saw a pretty rudimentary installation with nothing fancy. What stood out was the fact that there were two browsers. One was called simply "WWW" and the other was called "Browser." The Browser app was the standard AOSP browser. Nothing fancy. But when we opened the WWW app, our minds were blown. It opened a desktop session of Firefox (with desktop Adobe Acrobat Reader!). At first, we thought it was some sort of weird build for Android, but then we noticed that we could move windows and the user agent was reported as Moblin 3.5.1. We decided to look at the APK, which had a really interesting package name - com.android.firefox. The APK was only 5 KiB and had only a few classes, so we immediately knew that Firefox was hidden somewhere else.
It contained some unusual code with 175 lines of cases. It turned out this was an implementation of a keyboard. For every key, with alt and ctrl, it sends a message through a socket implemented in android.utils.SocketUtil indicating which key was pressed. android.utils.SocketUtil is not a standard Android library, so we had to tinker more to find the actual class. It turned out to be an abstraction of Unix Sockets. The APK communicates using three sockets: Firefox, vfbinput, and hwcursor. We also noticed some strings refering to /x-root/ path in function related to audio, as well as multiple uses of the string xvfb. Xvfb, or X11 Virtual Frame Buffer, is an X11 display utility that renders windows to a virtual output without displaying them on a physical display. This is often used in automated testing of apps. We explored further and used Firefox's download file dialog to compare the filesystem, discovering that this "VMs" filesystem is actually mounted in /x-root. It also contained binaries for IceWM, Acrobat Reader, and Java. This led us to believe that it is, in fact, a chroot container. When we booted back to Windows XP, we noticed that on the Android partition (which is NTFS and is mounted by default in Windows), there are three hidden files: firefox.img, q2l.img, and var.img. We copied those files and booted back to Android. Morc installed a terminal emulator and saw that the Firefox process is visible from Android. He also noticed, that there was a send\_hwcursor. Then, we decided to check which processes communicate with what sockets. The vfbinput was communicating with a process named xvfbinputd. Since this socket is used for sending keys, xvfbinputd has to communicate somehow with the chroot container. We haven't figured this out yet (the binary looks obfuscated), but we think it's connecting with the container's X11 session. The sockets Firefox and hwcursor are being handled by the hwcursor process. Those sockets are being used for control (shutting down) and cursor manipulation.
We explored a bit of Windows XP, but except for the sync utility (which has some interesting options like Google Account sharing, email account syncing, and some file sharing), it was normal. When we booted into Android, at first, we saw a pretty rudimentary installation with nothing fancy. What stood out was the fact that there were two browsers. One was called simply "WWW" and the other was called "Browser." The Browser app was the standard AOSP browser. Nothing fancy. But when we opened the WWW app, our minds were blown. It opened a desktop session of Firefox (with desktop Adobe Acrobat Reader!). At first, we thought it was some sort of weird build for Android, but then we noticed that we could move windows and the user agent was reported as Moblin 3.5.1. We decided to look at the APK, which had a really interesting package name - com.android.firefox. The APK was only 5 KiB and had only a few classes, so we immediately knew that Firefox was hidden somewhere else.
It contained some unusual code with 175 lines of cases. It turned out this was an implementation of a keyboard. For every key, with alt and ctrl, it sends a message through a socket implemented in android.utils.SocketUtil indicating which key was pressed. android.utils.SocketUtil is not a standard Android library, so we had to tinker more to find the actual class. It turned out to be an abstraction of Unix Sockets. The APK communicates using three sockets: Firefox, vfbinput, and hwcursor. We also noticed some strings refering to /x-root/ path in function related to audio, as well as multiple uses of the string xvfb. Xvfb, or X11 Virtual Frame Buffer, is an X11 display utility that renders windows to a virtual output without displaying them on a physical display. This is often used in automated testing of apps. We explored further and used Firefox's download file dialog to compare the filesystem, discovering that this "VMs" filesystem is actually mounted in /x-root. It also contained binaries for IceWM, Acrobat Reader, and Java. This led us to believe that it is, in fact, a chroot container. When we booted back to Windows XP, we noticed that on the Android partition (which is NTFS and is mounted by default in Windows), there are three hidden files: firefox.img, q2l.img, and var.img. We copied those files and booted back to Android. Morc installed a terminal emulator and saw that the Firefox process is visible from Android. He also noticed, that there was a send\_hwcursor. Then, we decided to check which processes communicate with what sockets. The vfbinput was communicating with a process named xvfbinputd. Since this socket is used for sending keys, xvfbinputd has to communicate somehow with the chroot container. We haven't figured this out yet (the binary looks obfuscated), but we think it's connecting with the container's X11 session. The sockets Firefox and hwcursor are being handled by the hwcursor process. Those sockets are being used for control (shutting down) and cursor manipulation.
Approximate diagram of communication
We decided to mount the image files offline on our local machines. The file firefox.img contained the filesystem of the chroot container, q2l.img contained the kernel and Android root, and var.img contained the userdata. Morc decided to modify firefox.img, enabling IceWM's taskbar in the configuration. This, in fact, worked, and now we had an entire desktop. We looked around and found uxterm, java, Adobe Acrobat reader and other tools.Morc running Adobe Acrobat Reader
We then decided to look into how this container starts. When we enabled debug tools and overlaid them with running processes, we saw that as soon as Android booted, the Firefox and Xvfb processes started. We then looked at init.rc and saw some commands chroot-ing and starting the Firefox process. We also saw some references to a webmail process that started in a similar way. After all, who knows what other features could've been possible with this approach? After all of this, we decided to look into Java. It was standard 1.6, so we decided to run a Minecraft server. For fun.Morc running Minecraft Server
Thanks to Adam for helping with reverse engineering and Morc for bringing this machine home