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”.

Exploit Process:

  1. Power on the MR18, and hook it up to UART. (No ethernet should be plugged in)
  2. Hold the Reset Button for 10+ seconds until the LEDs on the device turn off, then release.
  3. The device should reboot, at this point pressing Enter on UART should show the following:
    <Meraki>
  4. At this point, you will want to enter
    odm help
  5. 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)
  6. 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
  7. 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.
  8. 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!

  1. Once in the root initramfs shell, run the following commands on your device:
    cd /storage/
    rm ./config*
    rm ./odm_test.log
    echo "serial_allow_odm true" > ./config
    echo "serial_access_enabled true" >> ./config
    echo "serial_access_check false" >> ./config
    echo "valid_config true" >> ./config
    cp ./config ./config.local
    exit
    
  2. 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:

  1. First contact to Meraki’s Security Team (10-20-2015)
  2. Exploit Confirmed by Meraki (10-22-2015)
  3. Reached out to Meraki for an update – No Response (01-06-2016)
  4. Second & Final Reach out to Meraki – No Response (01-27-2016)
  5. Public Disclosure of Exploit (02-09-2016)
  6. Email from Meraki, emails were “lost”, no longer eligible for bounty (04-20-2016)
  7. Reached out to Meraki (04-20-2016)

56 thoughts on “Pwning/rooting the Cisco Meraki MR18

  1. Ryan

    Hmm

    I have been trying for a few hours and am unable to get access to the unit.

    When are you supposed to press enter?

    Thanks for any help
    Ryan

    Reply
    1. Chris B - Admin Post author

      Hey Ryan,

      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.

      Reply
    1. Chris B - Admin Post author

      Hey there,

      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.

      Reply
      1. Ben

        I’m unable to send any input to the board.

        Beginning to think it’s my adapter, it’s a six year old eBay special, though when I shorted TX and RX I can confirm data is being sent. Just another excuse to buy a Bus Pirate…

        Reply
        1. Chris B - Admin Post author

          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.

          – Chris B

          Reply
          1. blackie

            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

          2. blackie

            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.

            My etc/config/network :

            config interface ‘loopback’
            option ifname ‘lo’
            option proto ‘static’
            option ipaddr ‘127.0.0.1’
            option netmask ‘255.0.0.0’
            option ipv6 ‘0’

            config globals ‘globals’
            option ula_prefix ‘fd19:445c:44f7::/48’

            config interface ‘lan’
            option type ‘bridge’
            option ifname ‘eth0’
            option proto ‘static’
            option ipaddr ‘10.1.0.45’
            option netmask ‘255.255.255.0’
            option gateway ‘10.1.1.254’
            option dns ‘10.1.0.13 10.1.0.10’
            option ipv6 ‘0’
            option ip6assign ’60’

          3. blackie

            network acceess problem resolved, mea culpa, incorrect network mask…
            opkg worked, Luci online 🙂

  2. chune

    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?

    Thanks!

    Reply
    1. Chris B - Admin Post author

      You got it. If you flashed sysupgrade, then your MR18 will now only boot OpenWRT as the Meraki kernel was removed, so the bonus root has no use/value to your device anymore.

      Reply
  3. Gustavo

    I have this log after change the serial number, cant send the S key 🙁

    If i boot the Meraki with the USB-UART plugged, I get the sequence :
    __________________sri____________________
    944x BootROM Ver. (asic) 1.0 [Nov 8 2011 13:42:57]
    _________________________________________
    find_hif: bootstrap = 0x31459
    Nand Flash init
    hdr: [0xbd000400 : 0xbd000400 : 0x6fb4 : 0xe5c86b84]
    nand_load_fw: read 13 pages
    nand_load_fw: 0x10000 0x800 0xbd000bf0
    nand_load_fw: 0x20000 0x800 0xbd0013f0
    nand_load_fw: 0x30000 0x800 0xbd001bf0
    nand_load_fw: 0x40000 0x800 0xbd0023f0
    nand_load_fw: 0x50000 0x800 0xbd002bf0
    nand_load_fw: 0x60000 0x800 0xbd0033f0
    nand_load_fw: 0x70000 0x800 0xbd003bf0
    nand_load_fw: 0x80000 0x800 0xbd0043f0
    nand_load_fw: 0x90000 0x800 0xbd004bf0
    nand_load_fw: 0xa0000 0x800 0xbd0053f0
    nand_load_fw: 0xb0000 0x800 0xbd005bf0
    nand_load_fw: 0xc0000 0x800 0xbd0063f0
    nand_load_fw: 0xd0000 0x800 0xbd006bf0
    f/w 0 read complete, jumping to 0xbd000400

    Meraki Atheros LinuxLoader MR18 built Jan 31 2014 15:53:22
    qca955x_init_ddr ok
    test_memoryfailed RAM BORKED: (0xa0000000) 0x5a5a5a5a != 0x0
    error booting
    __________________sri____________________
    944x BootROM Ver. (asic) 1.0 [Nov 8 2011 13:42:57]
    _________________________________________
    find_hif: bootstrap = 0x31459
    Nand Flash init
    hdr: [0xbd000400 : 0xbd000400 : 0x6fb4 : 0xe5c86b84]
    nand_load_fw: read 13 pages
    nand_load_fw: 0x10000 0x800 0xbd000bf0
    nand_load_fw: 0x20000 0x800 0xbd0013f0
    nand_load_fw: 0x30000 0x800 0xbd001bf0
    nand_load_fw: 0x40000 0x800 0xbd0023f0
    nand_load_fw: 0x50000 0x800 0xbd002bf0
    nand_load_fw: 0x60000 0x800 0xbd0033f0
    nand_load_fw: 0x70000 0x800 0xbd003bf0
    nand_load_fw: 0x80000 0x800 0xbd0043f0
    nand_load_fw: 0x90000 0x800 0xbd004bf0
    nand_load_fw: 0xa0000 0x800 0xbd0053f0
    nand_load_fw: 0xb0000 0x800 0xbd005bf0
    nand_load_fw: 0xc0000 0x800 0xbd0063f0
    nand_load_fw: 0xd0000 0x800 0xbd006bf0
    f/w 0 read complete, jumping to 0xbd000400

    Reply
      1. Vinay

        Hi,
        I am using this adapter and I am getting an exact same error as soon as I connect the cables.
        And now when I power my device On, the led just blinks and nothing happens.
        Any suggestions?

        Reply
  4. chune

    Gustavo- Be sure you are only hooking up RX, RX and GND. I had the same error when i hooked up VCC on mine. Removing VCC fixed the issue for me

    Reply
    1. PiXEL8

      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.

      -PiXEL8

      Reply
  5. Stinkbug

    Trying to free my Mr-18

    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

    Reply
  6. Alberto

    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 in advance.

    Reply
  7. Sam

    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.

    In write handler ‘device_id’ for wired0_cdpsource ~:: CDPSource’:
    Bad String passed to device_id
    In write handler ‘device_id’ for wired1_cdpsource ~:: CDPSource’:
    Bad String passed to device_id
    In write handler ‘product_model’ for wired0_cdpsource ~:: CDPSource’:
    Cannot parse product model
    In write handler ‘product_model’ for wired1_cdpsource ~:: CDPSource’:
    Cannot parse product model

    Really appreciate your assistance.

    Reply
    1. Chris B - Admin Post author

      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?

      Reply
  8. JD

    Hello

    I have an issue when dd the openwrt.bin file, seems like the mtdblock2 is too small or corrupted ? Any idea ?

    /storage # dd if=/storage/openwrt.bin of=/dev/mtdblock2
    [ 73.312000] ecc unrecoverable error
    [ 73.316000] ecc unrecoverable error
    [ 73.320000] ecc unrecoverable error
    [ 73.324000] ecc unrecoverable error
    [ 73.328000] end_request: I/O error, dev mtdblock2, sector 8960
    dd: writing ‘/dev/mtdblock2’: Input/output error
    8961+0 records in
    8960+0 records out
    4587520 bytes (4.4MB) copied, 2.852310 seconds, 1.5MB/s
    /storage #

    Thanks 😉

    Reply
  9. JD

    Hello Chris,

    yes, that’s what I was afraid of…. I ended up writing to mtdblock1 directly and this worked !
    Now this AP is free 🙂

    Thanks!

    Reply
  10. JayBee

    Hi Chris

    Thanks for the article.

    I am having some trouble. I can get to the step where I unplug the power to the AP and hold down S and power back on, then UART Terminal returns a bunch but ends with:

    In write handler ‘device_id’ for wired0_cdpsource ~:: CDPSource’:
    Bad String passed to device_id
    In write handler ‘device_id’ for wired1_cdpsource ~:: CDPSource’:
    Bad String passed to device_id
    In write handler ‘product_model’ for wired0_cdpsource ~:: CDPSource’:
    Cannot parse product model
    In write handler ‘product_model’ for wired1_cdpsource ~:: CDPSource’:
    Cannot parse product model

    I am using this adapter http://www.ebay.com.au/itm/201505399580

    This is how I am wiring it to the AP
    https://imgur.com/gjkYb4K

    Any ideas?

    Reply
    1. Chris B - Admin Post author

      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.

      Reply
      1. JayBee

        Thanks Chris. I am still having issues with not getting past the hold S and boot. I can’t seem to find your video on the OpenWRT forum. Can you link me?

        Reply
  11. Rob

    Confirmed working on an MR32 also:
    Meraki-build is 24-201607201515

    Board is running a BCM5301X ARMv7. Will take a look at running up Lede/openwrt on it as they do have kernel support.

    Flash layout:
    [ 1.490000] Creating 5 MTD partitions on “nand_iproc.0”:
    [ 1.490000] 0x000000000000-0x000000100000 : “U-boot”
    [ 1.500000] 0x000000100000-0x000000400000 : “bootkernel1”
    [ 1.500000] 0x000000400000-0x000000500000 : “senao_nvram”
    [ 1.510000] 0x000000500000-0x000000800000 : “bootkernel2”
    [ 1.520000] 0x000000800000-0x000007f80000 : “ubi”

    I’ve got a few more Meraki boards so will take a look at these also.

    Reply
  12. 4JB

    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.

    Cheers!

    Reply
    1. Chris B - Admin Post author

      Hey there,

      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.

      Reply
  13. Mooo123123

    Works fine on 23-198280, just reset it until “odm help'” works. You can use SW2 to do that, J2 also does crazy things.

    Reply
  14. Admin

    Hi there,

    I just tried a MR18 and build “24-201609272213-G374d42aa-daybed” – doesn’t work. Anyone else successfully used that version?

    Reply
  15. Admin

    Hi there,

    I just tried a MR18 and build “24-201609272213-G374d42aa-daybed” – doesn’t work. It works until pressing the “s” key. Holding after re-powering doesnt’ bring the root shell..

    Anyone else successfully used that version?

    Reply
  16. Matthew

    I have bootsh build 24-201610261613-Gb6d270c7-onion

    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…

    log here: http://pastebin.com/huUQc9ut

    Reply
  17. areig1979

    Tried to boot into root and continue to get “UNRECOGNIZED COMMAND LOGGED TO CLOUD SERVERS”.

    Firmware: rootfs-22-130961-1
    Is there anyway to bypass this firmware version? or am I stuck with a non-rootable MR18?
    __________________sri____________________
    944x BootROM Ver. (asic) 1.0 [Nov 8 2011 13:42:57]
    _________________________________________
    find_hif: bootstrap = 0x31c58

    Nand Flash init
    hdr: [0xbd000400 : 0xbd000400 : 0x6fb4 : 0xe5c86b84]

    nand_load_fw: read 13 pages

    nand_load_fw: 0x10000 0x800 0xbd000bf0

    nand_load_fw: 0x20000 0x800 0xbd0013f0

    nand_load_fw: 0x30000 0x800 0xbd001bf0

    nand_load_fw: 0x40000 0x800 0xbd0023f0

    nand_load_fw: 0x50000 0x800 0xbd002bf0

    nand_load_fw: 0x60000 0x800 0xbd0033f0

    nand_load_fw: 0x70000 0x800 0xbd003bf0

    nand_load_fw: 0x80000 0x800 0xbd0043f0

    nand_load_fw: 0x90000 0x800 0xbd004bf0

    nand_load_fw: 0xa0000 0x800 0xbd0053f0

    nand_load_fw: 0xb0000 0x800 0xbd005bf0

    nand_load_fw: 0xc0000 0x800 0xbd0063f0

    nand_load_fw: 0xd0000 0x800 0xbd006bf0

    f/w 0 read complete, jumping to 0xbd000400
    Meraki Atheros LinuxLoader MR18 built Jan 31 2014 15:53:22

    Reply
    1. Chris B - Admin Post author

      Hello,

      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.

      Reply
  18. MeMyselfAndI

    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 🙂

    Reply
  19. Knucklebusted

    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”

    Thanks

    Reply
  20. Chip Pierpoint

    Just to confirm what everyone probably already knows …

    /dev/mtdblock/rootfs-24-201611211457-G69d4dc09-mantua-1 won’t respond to ‘s’ on boot.

    Can change serial number though.

    Thanks for all the great work .

    Chip

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *