I decided to take a look at the FusionHub virtual routing appliance from Peplink. Here’s how to open it up and get inside.
FusionHub is a software package designed for Peplink-brand networking equipment. It provides a bandwidth bonding and VPN solution for users of these devices. FusionHub is essentially the host-it-yourself version of Peplink’s cloud offering, SpeedFusion Cloud.
0. Download FusionHub
Fetch the appliance image from the official Peplink site.
$ wget https://download.peplink.com/firmware/fusionhub/fusionhub-8.0.1-build1644.zip
$ unzip -d peplink fusionhub-8.0.1-build1644.zip
$ cd peplink
1. Inspect zip file
After downloading the zip file, we observe that it contains some disk images in various virtualization formats, as well as some documentation.
$ unzip -l fusionhub-8.0.1-build1644.zip
Archive: fusionhub-8.0.1-build1644.zip
Length Date Time Name
--------- ---------- ----- ----
0 2019-11-04 16:23 FusionHub/
239 2019-11-04 16:23 FusionHub/Google Compute Engine download link.txt
0 2019-10-29 10:12 FusionHub/OVF/
119389696 2019-10-29 10:07 FusionHub/OVF/FusionHub.ova
130 2019-10-30 14:44 FusionHub/RAW image download link.txt
0 2019-10-29 10:01 FusionHub/VHD/
419430912 2019-10-29 09:45 FusionHub/VHD/fusionhub.vhd
0 2019-10-29 10:01 FusionHub/VMDK/
123928576 2019-10-29 09:45 FusionHub/VMDK/fusionhub.vmdk
169 2019-10-30 14:48 How to upgrade.txt
77 2015-01-27 14:35 Installation Guide.txt
117352 2019-10-30 14:33 Release Notes.pdf
0 2019-10-29 09:51 Upgrade/
67420386 2019-10-29 09:48 Upgrade/fw-fusionhub-8.0.1-build1644.bin
--------- -------
730287537 14 files
The release notes identify this image as “Firmware 8.0.1” with a release date of Oct 31, 2019.
In addition to the included disk images, there are a few text files which contain URLs for other (assumedly less common) image formats.
2. Inspect disk image
I downloaded the .raw
image using the link provided in the RAW image download link.txt
file for easier inspection.
$ file fusionhub-8.0.1-build1644.raw
fusionhub-8.0.1-build1644.raw: DOS/MBR boot sector, extended partition table
Because it has an MBR partition table, we can use fdisk
to see some basic information about the partitions:
$ fdisk -l fusionhub-8.0.1-build1644.raw
Disk fusionhub-8.0.1-build1644.raw: 400 MiB, 419430400 bytes, 819200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
Device Boot Start End Sectors Size Id Type
fusionhub-8.0.1-build1644.raw1 2048 22527 20480 10M 83 Linux
fusionhub-8.0.1-build1644.raw2 22528 819199 796672 389M 5 Extended
fusionhub-8.0.1-build1644.raw5 24576 270335 245760 120M 83 Linux
fusionhub-8.0.1-build1644.raw6 272384 518143 245760 120M 83 Linux
fusionhub-8.0.1-build1644.raw7 520192 724991 204800 100M 83 Linux
fusionhub-8.0.1-build1644.raw8 727040 819199 92160 45M 83 Linux
Looks like it has some Linux filesystems on it. I wonder what they contain?
3. Inspect partitions
First, we add some device maps for the partitions.
$ sudo kpartx -av fusionhub-8.0.1-build1644.raw
add map loop0p1 (254:1): 0 20480 linear 7:0 2048
add map loop0p2 (254:2): 0 2 linear 7:0 22528
add map loop0p5 (254:3): 0 245760 linear 7:0 24576
add map loop0p6 (254:4): 0 245760 linear 7:0 272384
add map loop0p7 (254:5): 0 204800 linear 7:0 520192
add map loop0p8 (254:6): 0 92160 linear 7:0 727040
Then, we inspect the partitions further.
$ sudo blkid /dev/loop0 /dev/mapper/loop0p*
/dev/loop0: PTTYPE="dos"
/dev/mapper/loop0p1: UUID="c2f2f35b-82b9-45cf-a64d-0c611bcebc9b" SEC_TYPE="ext2" BLOCK_SIZE="1024" TYPE="ext3"
/dev/mapper/loop0p2: PTTYPE="dos"
/dev/mapper/loop0p5: UUID="a36c1423-0ef5-4e89-be54-ad7a80aeaf9b" TYPE="crypto_LUKS"
/dev/mapper/loop0p6: UUID="6915da70-88fd-4a4f-9de8-90ef02349e84" TYPE="crypto_LUKS"
/dev/mapper/loop0p7: UUID="1c53188f-829c-402a-b239-6903b034e1d9" TYPE="crypto_LUKS"
/dev/mapper/loop0p8: UUID="9f421f40-e148-438b-a83a-5a6e7db0fb82" TYPE="crypto_LUKS"
Drat. They’re encrypted. Well, the appliance boots itself without asking for any keys or passwords, so the keys must be in there somewhere.
4. Inspect boot partition
What about that unencrypted boot partition?
$ sudo mount /dev/mapper/loop0p1 /mnt/fusionboot/
$ cd /mnt/fusionboot/
$ find .
.
./lost+found
./boot
./boot/grub
./boot/grub/locale
<snip>
./boot/grub/grubenv
./boot/grub/grub.cfg
Ah yes, the GRUB config will have useful information in it! It must contain a passphrase or something.
$ cat boot/grub/grub.cfg
set default=0
set timeout=5
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
clear
set linux_gfx_mode=text
export linux_gfx_mode
set root='(crypto0)'
menuentry 'Peplink FusionHub v8.0.1 build 1644' {
cryptomount hd0,5
linux /bootdata1.bin root=/dev/ram0 fw=1 crashkernel=32M-1G:32M,1G-:32M
initrd /bootdata2.bin
}
menuentry 'Peplink FusionHub v8.0.1 build 1644' {
cryptomount hd0,6
linux /bootdata1.bin root=/dev/ram0 fw=2 crashkernel=32M-1G:32M,1G-:32M
initrd /bootdata2.bin
}
Guess not. Clearly they have done some clever boot-time key hiding thing that I can’t be bothered to figure out. If you know of a quick and easy way to extract the keys at this stage, please let me know!
As a quick aside, it is interesting to see two virtually identical boot options here. Seems like this could be a nice way to boot a known good firmware if an update goes bad.
With that, we’re off to obtain the keys a different way.
5. Boot the virtual appliance
Import the .ova
file into VirtualBox and boot it up.
$ VBoxManage import ./FusionHub/OVF/FusionHub.ova
$ VBoxManage startvm FusionHub
6. Dump the memory
As we saw in a previous step, the partitions are encrypted with LUKS. Since they automatically unlock themselves, the keys must be in memory.
After the appliance is fully booted, dump the VM’s memory to a file.
$ VBoxManage debugvm FusionHub dumpvmcore --filename=fusionmem.raw
Poweroff the VM (and delete it if you like). We won’t be needing it anymore.
$ VBoxManage controlvm FusionHub poweroff
$ VBoxManage unregistervm FusionHub --delete
7. Install / build FindAES
We need to search the dumped memory for the encryption keys which will unlock the partitions. Fortunately for us, FindAES is a great tool for the job.
Yes, yes. I know. The project is on SourceForge which is yucky. But the actual code for FindAES itself is truly a work of art. The whole thing is 391 lines of C with no dependencies. Trust me on this one, FindAES is the right tool for the job.
If you’re on Arch Linux, you can install FindAES from the AUR. Otherwise, you can fetch the source and build it yourself:
$ wget https://downloads.sourceforge.net/findaes/findaes-1.2.zip
$ unzip findaes-1.2.zip
$ cd findaes-1.2
$ make
8. Identify possible encryption keys
Use FindAES to identify AES keys from the memory dump.
$ findaes fusionmem.raw
Searching fusionmem.raw
Found AES-256 key schedule at offset 0x1df4f30:
6c a4 5c 93 20 6f 07 91 c1 e7 fd bc c6 76 48 ce a5 8c 08 cb da 50 44 02 9f 13 c1 38 c4 f1 65 24
Found AES-256 key schedule at offset 0x1dfb250:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
Found AES-256 key schedule at offset 0x1fcadb0:
58 ee 24 c8 c5 dd 98 c3 13 c8 23 cf 10 9b 05 dc df 58 98 0d c1 60 f2 ec 75 61 30 df f3 85 53 4f
Found AES-256 key schedule at offset 0x7f09830:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
Found AES-256 key schedule at offset 0x358c08c0:
59 80 17 5b d2 5f 72 26 98 f8 bf 0d 3b 6c ce ea fb da 30 0f 2a 59 70 ad f8 98 5f e6 ab 7c 4f 1a
Found AES-256 key schedule at offset 0x358c10c0:
66 ea aa 4e 95 c4 4e ed 6c 20 f0 a7 d7 b2 e4 b6 6a 2a 38 de c3 9e 29 0e 8f cf 0b e0 e2 3c 57 c7
Found AES-256 key schedule at offset 0x358c18c0:
08 f3 76 8c 03 c7 22 11 da 81 ba 79 25 eb 07 eb 8c 63 a4 46 77 1d 32 14 61 19 24 ef 0f 4e cb cf
Found AES-256 key schedule at offset 0x358c20c0:
e7 73 d2 79 1a 5a 7a 13 e0 18 f1 08 9d 41 3a ed bb b2 e7 d7 26 54 8e 2e 02 63 11 50 da 66 20 df
Found AES-256 key schedule at offset 0x3590c8c0:
6a 69 8d d3 be fe ba 7d 24 bd 23 6c 6b c6 a6 0a 1f 31 0d e8 b8 98 74 3b e5 3c e9 22 5c 7a 31 04
Found AES-256 key schedule at offset 0x3590d0c0:
be db 98 6d 64 2a 60 a2 19 68 cd 54 54 dc a3 d0 77 de cd a2 03 15 9a fc 9d 27 39 15 50 a7 6a 7d
Found AES-256 key schedule at offset 0x3f6184c0:
61 de e8 0a e8 f3 a9 6d 49 7b 27 68 a3 6a 97 9f 8a cb 39 bd 84 b8 cc d0 4f 10 af ef a4 73 98 3f
Found AES-256 key schedule at offset 0x3f6188a0:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
Found AES-256 key schedule at offset 0x3f6189f0:
5e f1 25 68 3f 5f 12 f9 2d f5 24 44 3f 79 bc f9 04 ff 26 04 63 95 9b 31 64 87 7d 92 81 da 80 29
Found AES-256 key schedule at offset 0x3f75b950:
95 11 c4 31 2c 97 13 97 c6 0b 07 86 5f 7d 2c 9a 66 4f 69 36 b7 d4 24 18 86 38 76 9c f2 5f 92 2a
Found AES-256 key schedule at offset 0x3fbdacc0:
d5 e6 c8 97 89 fe f0 ab 6c 92 75 6c 5d 5a 1a 60 35 fc 61 04 bd df 9b 53 de 02 a9 ec f2 fe 7f 77
Found AES-256 key schedule at offset 0x3fbdbcc0:
27 e8 c9 8f 96 99 66 3b 63 a6 b3 4a ba 2f 16 3d c2 b1 df 14 4e 97 eb 9f d6 dc ed af b1 50 7e 9c
Found AES-256 key schedule at offset 0x3fc8d0d0:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
9. Try to use the discovered keys
I did a little bit of preprocessing on the keys to make scripting easier. It basically amounts to this:
$ findaes fusionmem.raw | grep -Ev 'Searching|Found' | tr -d ' ' | sort -u
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
08f3768c03c72211da81ba7925eb07eb8c63a446771d3214611924ef0f4ecbcf
27e8c98f9699663b63a6b34aba2f163dc2b1df144e97eb9fd6dcedafb1507e9c
58ee24c8c5dd98c313c823cf109b05dcdf58980dc160f2ec756130dff385534f
5980175bd25f722698f8bf0d3b6cceeafbda300f2a5970adf8985fe6ab7c4f1a
5ef125683f5f12f92df524443f79bcf904ff260463959b3164877d9281da8029
61dee80ae8f3a96d497b2768a36a979f8acb39bd84b8ccd04f10afefa473983f
66eaaa4e95c44eed6c20f0a7d7b2e4b66a2a38dec39e290e8fcf0be0e23c57c7
6a698dd3befeba7d24bd236c6bc6a60a1f310de8b898743be53ce9225c7a3104
6ca45c93206f0791c1e7fdbcc67648cea58c08cbda5044029f13c138c4f16524
9511c4312c971397c60b07865f7d2c9a664f6936b7d424188638769cf25f922a
bedb986d642a60a21968cd5454dca3d077decda203159afc9d27391550a76a7d
d5e6c89789fef0ab6c92756c5d5a1a6035fc6104bddf9b53de02a9ecf2fe7f77
e773d2791a5a7a13e018f1089d413aedbbb2e7d726548e2e02631150da6620df
Place your nicely formatted keys in the following script:
#!/usr/bin/env bash
#
# File: fusion-unlock.sh
#
keys=(
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
057b6fbd9b0970b574227e8a0d9b7ab60340f1f950afb7226ee820aab9a2e910
08f3768c03c72211da81ba7925eb07eb8c63a446771d3214611924ef0f4ecbcf
27e8c98f9699663b63a6b34aba2f163dc2b1df144e97eb9fd6dcedafb1507e9c
5980175bd25f722698f8bf0d3b6cceeafbda300f2a5970adf8985fe6ab7c4f1a
66eaaa4e95c44eed6c20f0a7d7b2e4b66a2a38dec39e290e8fcf0be0e23c57c7
6a698dd3befeba7d24bd236c6bc6a60a1f310de8b898743be53ce9225c7a3104
96f93a36c9cfb7e24c76b043878e9d38ca28b5ded013e622e48fde97d840ab2d
99be9f34762326ba9a1954747777d43897900410607f41dad5fd3d3ad18599be
bedb986d642a60a21968cd5454dca3d077decda203159afc9d27391550a76a7d
ca9e80f1a3340fd9f8349c5d7d2b2c18d4656a78996fa43eea3ed3cb27013035
d5e6c89789fef0ab6c92756c5d5a1a6035fc6104bddf9b53de02a9ecf2fe7f77
dd0df83663c11e76e7f7730cc8c71fe95cacc6d55fc1908441699f6e6c14ee83
e773d2791a5a7a13e018f1089d413aedbbb2e7d726548e2e02631150da6620df
)
for key in "${keys[@]}"
do
echo "Trying $key"
echo $key | xxd -r -ps > fusionhub.key
if sudo cryptsetup open /dev/mapper/loop0p5 fusionvol --master-key-file fusionhub.key;
then
echo "Success! $key"
exit
fi
done
Run the script and it will hopefully unlock the partition using one of the keys we found in memory.
$ ./fusion-unlock.sh
Trying 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Volume key does not match the volume.
Trying 057b6fbd9b0970b574227e8a0d9b7ab60340f1f950afb7226ee820aab9a2e910
Volume key does not match the volume.
Trying 08f3768c03c72211da81ba7925eb07eb8c63a446771d3214611924ef0f4ecbcf
Volume key does not match the volume.
Trying 27e8c98f9699663b63a6b34aba2f163dc2b1df144e97eb9fd6dcedafb1507e9c
Success! 27e8c98f9699663b63a6b34aba2f163dc2b1df144e97eb9fd6dcedafb1507e9c
10. Here are the keys
Repeating the above setup once per partition, we discover which keys belong to their respective partitions. It is worth mentioning, however, that the contents of partition 5 and 6 are identical, and partitions 7 and 8 do not actually have any files on them.
loop0p5: 27e8c98f9699663b63a6b34aba2f163dc2b1df144e97eb9fd6dcedafb1507e9c
loop0p6: 5980175bd25f722698f8bf0d3b6cceeafbda300f2a5970adf8985fe6ab7c4f1a
loop0p7: 08f3768c03c72211da81ba7925eb07eb8c63a446771d3214611924ef0f4ecbcf
loop0p8: 6a698dd3befeba7d24bd236c6bc6a60a1f310de8b898743be53ce9225c7a3104
From this point forward, we will only inspect the contents of partition 5.
11. Inspect the unlocked partition
Now that we have opened the encrypted LUKS volume, we can mount it and inspect it further.
$ sudo mount /dev/mapper/fusionvol /mnt/fusionvol
$ cd /mnt/fusionvol
$ ls -ahl
total 40M
drwxr-xr-x 3 root root 1.0K Oct 28 2019 .
drwxr-xr-x 7 root root 4.0K Aug 3 01:51 ..
-rw-r--r-- 1 root root 3.3M Oct 28 2019 bootdata1.bin
-rw-r--r-- 1 root root 37M Oct 28 2019 bootdata2.bin
drwx------ 2 root root 12K Oct 28 2019 lost+found
-rw-r--r-- 1 root root 17 Oct 28 2019 software-release
Neat! There are those bootdata1.bin
and bootdata2.bin
files we saw earlier in the GRUB config. So the first one is the Linux boot image, and the second one is the actual root filesystem. Apparently the whole thing runs from memory.
$ file *.bin
bootdata1.bin: Linux kernel x86 boot executable bzImage, version 4.9.188-pismolabs+ (buildbot@build) #1 SMP Thu Oct 17 23:29:32 HKT 2019, RO-rootFS, swap_dev 0x3, Normal VGA
bootdata2.bin: gzip compressed data, was "rdisk.e2fs", last modified: Thu Oct 17 16:22:47 2019, max compression, from Unix, original size modulo 2^32 100663296
12. Inspect ramdisk
First, we uncompress the image. There isn’t enough space on the original partition to do this, so we make a copy elsewhere first.
$ cp bootdata2.bin /tmp/rdisk.e2fs.gz
$ cd tmp
$ gunzip rdisk.e2fs.gz
$ file rdisk.e2fs
rdisk.e2fs: Linux rev 0.0 ext2 filesystem data, UUID=00000000-0000-0000-0000-000000000000
Now that we have a regular root filesystem image, let’s take a look around.
13. Inspect the real root filesystem
$ sudo mount /tmp/rdisk.e2fs /mnt/fusionroot
$ cd /mnt/fusionroot
$ ls -ahl
total 34K
drwxr-xr-x 13 root root 1.0K Oct 17 2019 .
drwxr-xr-x 8 root root 4.0K Aug 3 02:12 ..
drwxr-xr-x 2 root root 2.0K Oct 17 2019 bin
lrwxrwxrwx 1 root root 9 Oct 8 2015 dev -> ./tmp/dev
lrwxrwxrwx 1 root root 9 Oct 8 2015 etc -> ./tmp/etc
drwxr-xr-x 2 root root 1.0K Jul 14 2005 fwupmnt
drwxr-xr-x 5 root root 2.0K Oct 17 2019 lib
lrwxrwxrwx 1 root root 3 Oct 17 2019 lib64 -> lib
lrwxrwxrwx 1 root root 11 Oct 17 2019 linuxrc -> bin/busybox
drwx------ 2 root root 16K Jul 6 2005 lost+found
lrwxrwxrwx 1 root root 7 Oct 17 2019 mnt -> tmp/mnt
drwxr-xr-x 2 root root 1.0K Jul 6 2005 proc
drwx------ 3 root root 1.0K Oct 17 2019 root
lrwxrwxrwx 1 root root 7 Oct 17 2019 run -> var/run
drwxr-xr-x 2 root root 1.0K Oct 17 2019 sbin
drwxr-xr-x 2 root root 1.0K Jul 20 2009 sys
drwxr-xr-x 9 root root 1.0K Oct 17 2019 tmp
drwxr-xr-x 9 root root 1.0K Oct 17 2019 usr
lrwxrwxrwx 1 root root 7 Oct 8 2015 var -> tmp/var
drwxr-xr-x 9 root root 1.0K Oct 17 2019 web
We’re finally in! This is basically a choose-your-own-adventure at this point. There are so many things to look at. Here are a few bits which I considered to be interesting:
14. Notes
I was not able to detect any telltale signs of a specific Linux distribution. It appears to be a custom Busybox-based Linux build using classic SYSV init scripts. /sbin/init
points to busybox, which uses /etc/inittab
to start the system’s services.
$ cat etc/inittab
null::sysinit:/etc/rc.sysinit
null::sysinit:/usr/local/ilink/bin/sysinit_prepare
null::syslog:/usr/bin/metalog -C /var/run/ilink/metalog.conf
null::wait:/usr/local/ilink/bin/sysinit
null::respawn:/usr/bin/runsvdir /var/service
null::once:/usr/local/ilink/bin/start_activate
null::respawn:/usr/local/ilink/bin/timesyncd
null::respawn:/usr/sbin/crond -f
null::respawn:/usr/local/ilink/bin/wtpmon
null::respawn:/usr/local/ilink/bin/wan_link_usage_hourly
tty1::respawn:/usr/local/ilink/bin/fh_console
The bulk of the web interface resides in the /web
directory. A handful of small CGI binaries are present there. Their file size leads me to believe that they are probably written in C. I hope these web-facing binaries written in memory unsafe languages have been sufficiently fuzzed! 😈️
$ cd web/cgi-bin/MANGA
$ find . -mindepth 1 -maxdepth 1 -type f -exec file {} \;
./cgibox.cgi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 4.9.141, stripped
./wwan_status_daemon: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 4.9.141, stripped
./chkupgrade.cgi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 4.9.141, stripped
./firmware.cgi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 4.9.141, stripped
./index.cgi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 4.9.141, stripped
./extap_fwb.cgi: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 4.9.141, stripped
These files are dynamically linked and refer to some custom libraries which are present in the /lib
directory. My research environment is unaware of this library path, so they appear as “not found” here.
$ ldd cgibox.cgi
linux-vdso.so.1 (0x00007ffcb3700000)
libcgi.so => not found
libstatus.so => not found
libpepinfo.so => not found
libpepmodule.so => not found
libstrutils.so => not found
libssl.so.1.1 => /usr/lib/libssl.so.1.1 (0x00007f477ea91000)
libcrypto.so.1.1 => /usr/lib/libcrypto.so.1.1 (0x00007f477e7b1000)
libroutedb.so => not found
libvpnstatus.so => not found
libpepos.so => not found
librt.so.1 => /usr/lib/librt.so.1 (0x00007f477e7a6000)
libsqlite3.so => /usr/lib/libsqlite3.so (0x00007f477e661000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f477e63e000)
libjansson.so.4 => /usr/lib/libjansson.so.4 (0x00007f477e62e000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f477e462000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f477e45b000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f477e317000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f477eb5d000)
The web server on the appliance is Nginx, version 1.12.2. Somehow, this particular version has avoided having any critical security issues. …yet.
$ ./nginx -v
nginx version: nginx/1.12.2
15. Cleanup
Unmount and unmap the raw image partitions, if you feel inclined to do so. If not, a reboot will clear this right up for you.
$ sudo kpartx -v -d fusionhub-8.0.1-build1644.raw
Conclusion
In this post, we jumped through the necessary hoops to deobfuscate the software (somewhat), and we learned a lot about the contents of the FusionHub virtual appliance.
Future
I briefly attempted to run binary-only fuzzers on these CGI executables, but I clearly have a lot to learn before I surface any meaningful results from doing so. Hopfeully I will find some more time for this and we can discover some really interesting things then!
🙂️