Digging into the Shopify POS Firmware (Part 1)

Hey dear Readers it’s been awhile,

tldr;  found Shopify POS Firmware, included hashed root Password, used some terminal magic to gather more information.

So this Blog post is about the Shopify POS Firmware is was able to analyze. You might wonder what on earth a POS is? A POS is a location where payment is accepted. Those devices look like this :

Screenshot 2015-10-09 16.41.00

Easy as that. You swipe your credit card and sign it, and you’re done. So how did i discover this thing? So i was looking at Shopify’s Bug Bounty Program at Hackerone (Shopify Hackerone) One of the things that was actually in scope was their POS App for iOS.

DISCLAIMER: All Information below was submitted in a Responsible Disclosure Process to Shopify. The Shopify Security Team closed the report on Hackerone as Informative so i think it’s safe to publish.

So the test Scenario was like this, i installed the POS IOS Application, while looking at the requests being sent i found out there is one that looks like this : GET /admin/pos/firmwares.json, this request will issue a call to the Shopify server and get me back the content of the Firmware of the POS Device.

Screenshot 2015-10-09 15.34.24
As you can see in the image there is a lot of JSON included in the Response, if you parse it you will get back the URL’s which will lead to the following files : M000-MPI-V1-37.tar.gz, M000-MPI-Vx-x-CONF49-V1.tar.gz M000-OS-V7-5.tar.gz, M000-OSUPDATE-V1-4.tar.gz, AACDOL.CFG, ARQCDOL.CFG, MPI-Dynamic.cfg, TCDOL.CFG, TDOL.CFG, TRMDOL.CFG, ctls-prompts.txt, emv-fallback.cfg, emv.cfg, contactless.cfg with the corresponding URL’s

cdn.shopify.com/s/assets/firmware/config/emv-fallback-13c4319af8434ebc894e2a0c47a48417.cfg
cdn.shopify.com/s/assets/firmware/app/production/M000-MPI-V1-37.tar-9abe14a6433eb3a5f61870660cdfae81.gz
cdn.shopify.com/s/assets/firmware/app/production/M000-MPI-Vx-x-CONF49-V1.tar-7d4636759624115fc3a6c3dbf57aec8c.gz
cdn.shopify.com/s/assets/firmware/os/production/M000-OS-V7-5.tar-9ed4cd40ad71f234b446264a135972d2.gz
cdn.shopify.com/s/assets/firmware/os/production/M000-OSUPDATE-V1-4.tar-9168025c94814041523c2582f47ba9a7.gz
cdn.shopify.com/s/assets/firmware/config/AACDOL-cbc95df164cf83cc167f1ab3c95c53aa.CFG
cdn.shopify.com/s/assets/firmware/config/ARQCDOL-0f2517d2c7ca6e6f2df1a3b1b2486e2c.CFG
cdn.shopify.com/s/assets/firmware/config/MPI-Dynamic-7bcb6e8d27613d28c98d9dbed994cc11.cfg
cdn.shopify.com/s/assets/firmware/config/TCDOL-2ec49e15bff6a82cf687e0e00adc4cca.CFG
cdn.shopify.com/s/assets/firmware/config/TDOL-6b88dab08c5da95df3b2de4353aa4439.CFG
cdn.shopify.com/s/assets/firmware/config/TRMDOL-43308c530c0e60e24b6bdc88654a5fdd.CFG
cdn.shopify.com/s/assets/firmware/config/ctls-prompts-c395c522f28a5afce99b87930ecf09c4.txt
cdn.shopify.com/s/assets/firmware/config/emv-fallback-13c4319af8434ebc894e2a0c47a48417.cfg
cdn.shopify.com/s/assets/firmware/config/production/US/emv-8065616e6244ffe5d83f2701b3e9c58f.cfg
cdn.shopify.com/s/assets/firmware/config/production/US/contactless-681240ec707cba97232649622e135a95.cfg

So i went one step further and downloaded them all to my PC. In my test case i only looked at the tar.gz files because those seemed to insist the Firmware of the Device. From what i saw the M000-OS-V7-5.tar-9ed4cd40ad71f234b446264a135972d2.gz file was the biggest file and i guessed it could include the whole firmware. If you unzip it you will find a M000-OS-V7-5.mlf file. This file is a so called Miura Loader File that will be used for the boot Process of the Firmware.
So the next thing i did was to run binwalk M000-OS-V7-5.mlf and i got the following output:

DECIMAL HEXADECIMAL DESCRIPTION
——————————————————————————–
9385 0x24A9 eCos RTOS string reference: “eCos : ”
186273 0x2D7A1 Unix home path string: “/home/astanton/workspace/RELEASE/Redboot/packages/redboot/curre”
192389 0x2EF85 Copyright string: ” (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.04 Red Hat, Inc.”
192449 0x2EFC1 Copyright string: ” (C) 2003, 2004, 2005, 2006 eCosCentric LimitedsCentric Limited”
192486 0x2EFE6 eCos RTOS string reference: “eCosCentric Limited”
210073 0x33499 Unix home path string: “/home/astanton/workspace/RELEASE/Redboot/packages/hal/arm/mx25/”
212065 0x33C61 Unix home path string: “/home/astanton/workspace/RELEASE/Redboot/packages/hal/arm/mx25/”
215149 0x3486D Unix home path string: “/home/astanton/workspace/RELEASE/Redboot/packages/hal/arm/mx25/”
216389 0x34D45 Unix home path string: “/home/astanton/workspace/RELEASE/Redboot/packages/hal/arm/mx25/”
218053 0x353C5 Unix home path string: “/home/astanton/workspace/RELEASE/Redboot/packages/hal/arm/mx25/”
225265 0x36FF1 eCos RTOS string reference: “eCos GDB stubs [via RedBoot] – built Sep 18 2014 / 17:47:58”
266566 0x41146 LZMA compressed data, properties: 0xC0, dictionary size: 16777216 bytes, uncompressed size: 32 bytes
506506 0x7BA8A gzip compressed data, maximum compression, from Unix, last modified: Thu Sep 18 16:48:30 2014
1550355 0x17A813 GIF image data
2105380 0x202024 JFFS2 filesystem, little endian

The interesting Part here is the JFFS2 Filesystem which is a Linux filesystem. Once you get at this Point you will need some terminal magic to extract that part out of the Firmware, to do so i used a Unix tool called dd:

dd if=M000-OS-V7-5.mlf of=fs.jffs2 skip=105269 bs=20 this will generate a file called fs.jffs2. In order to actually extract it i found another tool called sumtool,Sumtool is a utility that creates JFFS2 erase block summary images. With sumtool i’ve created a second file with the command „sumtool -l -i fs.jffs2 -o file.sum“. After this step i used a tool called jffs2dump.py with the command “python2.7 jffsdump.py file.sum.” At this Point the jffsdumper will copy all the files from the JFFS2 filesystem to my harddrive. Once i looked on the file structure i found out that they used a arm-none-linux-gnueabi-gcc Linux which special lightweight Linux for semiconductors. So you have a structure like this :
bin dev etc home lastlog lib libexec mnt opt proc root sbin share sys tmp usr var

Which is pretty simmilar to every Linux out there. After digging into the files i discovered the /etc/passwd which revealed that there is a root user with the following permissions set: root:x:0:0:root:/root:/bin/sh of course if you find the /etc/passwd there has to be a /etc/shadow which includes the hashed Passwort of the User. In this case the according Password is stored salted and md5 hashed in the /etc/shadow file with the following value:
root:$1$WWTl/62J$25eq8w6xQFhSUBpUbScRK.:11851:0:99999:7:::

Screenshot 2015-10-06 20.20.42
If we look at it we can see that $1$ is the equivalent for MD5, the following Part WWTl/62J is the Salt for the Hash, 25eq8w6xQFhSUBpUbScRK. is the encrypted md5 value. Actually this seems to be a dead end for me. I can’t replace the root password hash with my own since the firmware is signed cryptographicly and therefore will not allow any changes in the firmware. But how to proceed now?
I started to dig a bit deeper and found the folllowing files which seemed a bit promissing for me: miura-factory-test,miura-monitor, miura-auth

Screenshot 2015-10-09 16.14.21I am absolutely no expert in Reverse Engineering (if somebody is hit me @itsecurityguard Twitter). So the very basic thing i could do was run the command “strings” against the files and see what comes back.  I did this with the miura-factory-test file which seems to be a debugging executable for the Miura Devs. What i found there was a config file for WLAN. As i suspect the device is looking for this particular Network while the executable is running. I wonder what’s being sent while it’s running?

Anyways it seems i reached a dead end here again – The next Part of this BlogPost will be about reversing the miura- files i found on the system, with (hopefully) good results

Stay tuned

PatrikScreenshot 2015-10-09 16.36.49