One Guys Technical Trials and Woes

Pwning/rooting the Cisco Meraki MR18

If you haven’t noticed, in my spare time I really enjoy breaking into embedded devices for the fun of things. Over the past year, I have spent a ton of time rooting the Cisco Meraki MR18, and today I get the chance to publicly disclose my findings.

To start, let me note by saying I have properly disclosed this issue to Cisco Meraki months ago, but due to the fact they are no longer replying to my emails or honoring their own Bug Bounty, I have decided to publicly disclose this after waiting over 90 days since their last reply. Hopefully one of these days I will write up the process I used to find this “exploit”.

Power on the MR18, and hook it up to UART. (No ethernet should be plugged in)

Hold the Reset Button for 10+ seconds until the LEDs on the device turn off, then release.

The device should reboot, at this point pressing Enter on UART should show the following:

<Meraki>

At this point, you will want to enter

odm help

If you get a “UNRECOGNIZED COMMAND LOGGED TO CLOUD SERVERS.” reply, then please try holding the button to do another reset of the device. If you continue to get this message, then sadly your firmware version is NOT rootable using this method. (please comment to this post sharing your results/firmware version)

If you got a “Help” output for the ‘odm’ command, then run the following commands:

odm serial_num write Q2XX-XXXX-XXXV
odm serial_num read

At this point the output should show “Q2XX-XXXX-XXXV” and your device should have it’s LED’s flashing. At this point, pull the power from the device, and hold down “s” on your UART console when you power back on the device.

After a bit, you should then drop to a initramfs root shell, and the device is pwned! Feel free to follow the OpenWRT flashing guide found on the OpenWRT Forums.

Bonus Rooting:

Doing the above gets you root on the initramfs, but what about the stock firmware? No worries, as I have that covered as well!

Once in the root initramfs shell, run the following commands on your device:

Once the above is ran, the firmware should continue to boot, and you will then be back in the stock OS. Once here you will want to restore the Serial Number of your device, which can be done with:

odm serial_num write Q242-1111-111V

Just be sure to make sure to set your serial to the one on the bottom of the device. Changing the serial to any thing else CAN CAUSE ISSUES with the device. Also note that once networking is re-attached, you will lose root access!

Confirmed Working On:

Firmware Build 22-140575

Firmware Build 22-149780

Firmware Build 23-162921

Firmware Build 23-188206

Overall this exploit isn’t much more than taking advantage of an engineering back door, but I got to dock Meraki some serious points for closing all forms of communication with me. The entire point of Bug Bounties is to encourage proper disclosures, and not following through does not reflect well upon the company.

Timeline of Events:

First contact to Meraki’s Security Team (10-20-2015)

Exploit Confirmed by Meraki (10-22-2015)

Reached out to Meraki for an update – No Response (01-06-2016)

Second & Final Reach out to Meraki – No Response (01-27-2016)

Public Disclosure of Exploit (02-09-2016)

Email from Meraki, emails were “lost”, no longer eligible for bounty (04-20-2016)

To get to the Console over UART, this should show up after the device has fully booted, so pressing Enter any time after this should work. If nothing shows up when pressing enter, make sure your TX pin on your UART adapter is wired up correctly.

Once flashed with 1.0 from github, you can then freely install any of the official OpenWRT snapshot releases for the MR18, just note they won’t come with LuCI installed by default so you may just want to wait for the next official OpenWRT release, which will then include LuCI.

Hmm, were you able to go through the process to change the serial number of the device using the “odm” command, or are you unable to access the prompt at all? Also, do you have any other UART adapters you could try and are you using the UART pinout at https://i.imgur.com/McxTAsJ.jpg?

As the MR18 code was not backported, you can only install from the nightly Snapshots at https://downloads.openwrt.org/snapshots/trunk/, which is currently offline. If you need LuCI, then you will want to use the version from my repo until the next major release of OpenWRT.

If you are getting a bad signature error, this just means the nightly you flashed had an issue with the LuCI package. You can either flash one of my older OpenWRT images from my GitHub repo (which include LuCI) or you will want to wait for the next nightly, upgrade, and then try installing LuCI again following the OpenWRT Wiki documentation.

Thank you for your advice. I was finally able to reflash my Meraki with your github repo image, Luci worked, but I was unable to configure network the way that internet worked without hdcp (with static IP).
At the end I killed the network config in the rooter and had to reset the settings via reset button, but from that time something is broken.
Normally via serial console the firmware is not started properly, initialization finished with “Failed to executPlease press Enter to activate this console.”.
I’m uable to access bash and send any commands.

i can access via failsafe mode, but there is no /etc/config/network file and my attempt to reflash the nightly build via sysupgrade finished with error “Failed to connect to ubus”.
Would be very gratefull for advice how to properly reset my device or reflash with setting reset. Thanks

I managed to restore the healthy state of my router 🙂 In failsafe mode i had to mount the root filesys and manually correct the network config file and then(after luci was accessible via 192.168.1.1 address) to re-flash the nightly build.
I still can’t figure why I can’t access internet from the rooter, so I’m unable to do opkg update and install anything.

Thanks so much for a non-destructive way into these things! After following step 8, i was able to get openWRT loaded! However I cannot get the procedure under “bonus rooting” to work. Is this because i followed the openWRT procedure here:

“go to the System Upgrade tab, and select the downloaded sysupgrade image named openwrt-ar71xx-nand-mr18-squashfs-sysupgrade.tar. This will then remove the stock Meraki kernel, flash OpenWRT, fix the caldata partition if needed, and auto-expand rootfs_data to use the rest of the UBI free space.”

Am i out of luck here or should i still be able to hold S and get the meraki console again to use the odm commands?

After doing this to another MR18 I realized how this worked before. If you do the 30s reboot procedure the odm cmd is not found. I then rebooted normally and let it boot. The prompt then has the odm cmd allowing you to change the SN. Now follow the rest of the steps in the guide.

I am on fw version 22-140575 but getting a problem at the odm serial_num change stage, when I try to write the serial_num I am getting:
board_data_config: bad serial given, you can try using -f
board_data_config: bad write

Checking odm help I can see:
mac, seral_num, product_id, hw_rev, hw_minor,
So tried to run odm serial_num write value Q2XX-XXXX-XXXX and still same result.

Tried to set force switch, but not sure where is should go in syntax, tried various but not working either.
Any ideas? Thanks

Hi!. I’m following this procedure and I’m getting stuck.
Could you tell me the right moment to plug in the ethernet to the meraki????
I’m following this guide just fine but when i try to connect to my PC to download the firmware I lost UART connectivity.

Thanks so much for this, ive got so far but hoping for a little assistance…

I’ve completed everything as above which worked great and I’m trying to get files over to the device but the Ethernet does not appear to be working (lights are on port and amber flashing on meraki). if I run ‘ifconfig eth0’ I get device not found. When the device boots the following lines appear at the end.

Hmm. I have seen similar issues on other devices where a UART adapter was used that was either over voltage, or had VCC wired up. Can you confirm you are using a 3.3V UART adapter and only have TX/RX/GRND wired up? It also seems your board is unable to read the UBI partition that contains your board information. Did you ever try the pin jump method, and does your MR18 work normally when you try to let it boot fully?

If you are seeing those messages that is normally a sign that you have passed the boot process where “S” is required, so you may need to keep trying. You can also check out the flashing video I made in the OpenWRT forum post to get an idea of what you should be seeing on the Console.

Note that at this time the MR32 and MR33 do not have LEDE/OpenWRT support. I do have a MR32 in hand ATM that I plan to port over later, but note it does not have GPL driver support for the main AC wireless radios. I am unsure of the situation with the MR33, as I am not sure what radios are used on that board.

Hi Chris! First off, awesome findings and write-up!! My MR-18 is in the mail currently. I’m just curious if there is any benefit of doing this exploit initially upon unboxing to try to ensure root access if I intend to start out using the normal Meraki firmware until my “license” expires? I understand I can always go JTAG, but I’d like to use it without worrying about future firmware downloads breaking UART access if at all possible.

As for your question, note that this method will probably get patched via Cisco/Meraki down the line, so if you have any intentions of using OpenWRT/LEDE on the device it would be best to follow this guide, and flash your device before hooking it up to the internet. This is because on first boot, the Meraki on stock firmware will download and install the latest OTA which may prevent this method from working in the future. If you don’t mind going the JTAG route though, then feel free to use the device as is.

I am able to change the serial number but it will not enter the ‘s’ console even though it accepts the ‘magic key’
Got magic key s [ 1.632000] Bootsh: trying rootfs path:
/dev/mtdblock/rootfs-24-201610261613-Gb6d270c7-onion-1
Attempting to setup root /dev/mtdblock/rootfs-24-201610261613-Gb6d270c7-onion-1…

This is normally a sign you didn’t hold the reset button for 10+ seconds first to reset the device, so please try the process again. With that said though, I have heard that newer firmwares (build 24 and up) may no longer be rootable.

Just dropping by to thank you for your effort, Chris. As I’m writing this, I’m connected to an MR18 running OpenWRT, freed thanks to your instructions.

I received it in November or December 2016 from Cisco running firmware 22-140575 (does everyone get those things with such an old firmware version?). Shipped to Poland after having to remind Cisco that they forgot about me. I was told of some kind of supply shortage. Whatever.

No need to do the pin shortening tricks whatsoever with this firmware, but anyway thanks for putting my serial adapter to use that I got years ago for a never finished project and forcing me to learn serial communication stuff 🙂

Right. Upgrading to the MR18 from my 8 years old TP-Link 1043nd v1 access point (running flawlessly, mind you) is definitely a step up 🙂

I have an old computer with a physical serial port. Can I use that? I have tried but hooking TX to SND, and SND to TX did not work. When I connected SND to SND and TX to TX, it got gibberish ASCII characters that look like bad speed/data/stop/parity configuration but nothing I’ve tried works.

I’d really like to get something usable on this MR18 but it doesn’t seem to be working. I also can’t see what version it is running from the Meraki cloud page. It just says “up to date”

This boots the device into “diagnostic” mode, which is a barebones qualcomm testing environment. While you have a root shell, you are unable to access the NAND that stores the stock firmware due to the ECC differences. Specifically, the stock firmware and environment use BCH ECC, which is not enabled for this environment.

I can get to prompt and have changed serial number.
Also ran ‘odm fw_version read’ which reported back 22-140575
Which seems to tally with the list of compatible firmware versions.
But device will not respond to ‘s’ when powering back on.
Using Putty, I unplug power, press ‘s’ on keyboard then plug power back in.
It boots without LED’s & outputs unreadable characters & just continues to output them. Waited for about 2 minutes.
Any advice offered greatly appreciated

If you are getting junk back, this can be a sign it may be a problem with your UART adapter or wiring. Make sure you are only connecting GND, RX, and TX, and you have a 3.3v adapter. I personally use CP2102 based UART adapters, and have never had any issues.

Thanks Chris, I appreciate your response.
I have this UART adapter http://ebay.eu/2m2f1Dz and have definitely got GND, RX, TX hooked up correctly. I tried switching them around and only got junk. Where as I can get to ODM HELP prompt, but cannot activate magic key press ‘s’

Hi Chris,
After reading the openwrt forum and this post, i’m actually more confused as to how this ‘s’ backdoor actually works.
Firstly, is it lower-case ‘s’ or upper ‘S’ ( or does it not matter) ?

But, eitherway, I can not make it work.
I have firmware 22-130961, which seems to be earlier than other confirmed explotable versions.
I’ve successfully changed the serial number, but no amount of hitting/holding the s key during boot gives me a shell.

The only thing of interest, is I always get junk over the serial at boot-up (soft or hard reboot), the first legible line is:
[ 0.256000] console [ttyS0] enabled, bootconsole disabled

Any clues?
I’d prefer not to have to resort to shorting resistors or buying a jtag…

I’ve got a CP2102 UART adapter. Managed to get the serial changed and up to the point of booting using the special key ‘s’, but it didn’t work. I can confirm I’m running firmware 24.
This has been confirmed as not working.

What I did however manage was to still get root access to the device by holding the reset button for 5 secs or so. The device would reboot me into a root unix prompt. Sadly the ‘wget’ command wouldn’t work……any idea’s guys? Could there be another way to update the device using this method.

I was able to change the IP address of the device when I got this prompt and ping my laptop. just the ‘wget’ command was unrecognized.

Pete,
This means you booted into the diagnostic image on the MR18. Sadly it has the NAND blocked off at a kernel level as it’s hard programmed to use a different ECC mode, so you can’t flash the device from this environment.

Same problem here 115200 N81 – Lots of garbage – If I start with the cable inserted, i get some “half readable” text, but is will not boot, just keeps circling in some kind of startup-diag.
If i connect the cable after initial power-on, I get lots of unreadable garbage like Steeve.

I have a 24-201611211457-G69d4dc09-mantua firmware, initially when performing the
odm serial_num write Q2XX-XXXX-XXXV
the subsequent “odm serial_num read” would either produce nothing or, at times, give the original number. Then I left the machine attached to PoE and serial cable, and when I gave the “odd show_system” command I noticed the line
serial_num Q2XX-XXXX-XXXV
and now having it left again for some time alone, it apparently did a spontaneous reboot, and yet the serial number is stil the one I set! So, I will now proceed with the rest of the process (reboot while pressing s and see how it goes…

(re: my 24-201611211457-G69d4dc09-mantua FW)
No joy…. the boot process still ends, like before, with a
[ 18.544000] warning: key material 0 too short (minimum 16+4+20=40)
and yet the serial number is still set!
What else should I try?

forgot to mention that I solved this problem and posted my findings under the other thread since I followed the method there: https://servernetworktech.com/2017/06/pwning-the-meraki-mr18-again/
It was not devoid of difficulties as the MR18 was not asking for the file indicated in the URL given. But you can read about it there. Thanks

I am trying to root my MR-18 but I am unable to get to a prompt. I can get the console via the uart and see the unit loading, I have firmware 22-140575 wich says will work with above method, but after holding the reset button, I see the unit boot and the prompt flashes by and keeps loading unit keeps loading until it says “Cannot parse product model” and just stops with no prompt.

I had a DHCP server running but the unit did not grab an IP address either. I have tried pressing 2 or s but I am unable to get the unit to a prompt so I can type.

I am also having issues getting this thing flashed. I have tried the all the guides that I can find. Below is the three guides and errors I can find.

I have feeling I am on the wrong firmware version. I don’t know what firmware I am on because when I connect to the mr18 everything on the screen scrolls quickly but I cannot go back and see what version I have (I cannot scroll and normal commands do not work).

I can run the odm command to change the serial, when I try to get into the initramfs root shell I can’t seem to get there very easily. I have to use the reset button to and force into crash the kernel to get in. Once I get into the initramfs root shell, i go to run the command but /storage cannot be found. I can create mkdir storage and it creates, That doesn’t really help since the .configfiles are not there.

I have also tried to follow these guides and https://wiki.openwrt.org/toh/meraki/mr18. I still have to create the /storage and run the script that all finishes properly, but when I run the WGET command it says WGET is not found