Meross MSS310

Part 1: Meross MSS310 Smart Wi-Fi Plug

Recently I “accidentally” bought one of those WiFi controllable power outlets: a Meross MSS310. Idea was to flash Sonoff-Tasmota on it. I should have googled for it before purchasing: it doesn’t contain an ESP8266 or compatible module.

After a bit of disappointment I decided to dig a bit into the hardware and see how far I can get. Here’s what I could find out so far:

Update: this seems to be hardware revision 1. With hardware revision 2, Meross uses an MT7682SN SoC, which contains an ARM core.

When the plug is powered on, it acts as an access point with IP address 10.10.10.1, giving out IP address 10.10.10.100 via DHCP.

A quick nmap scan showed open ports 80 and 23, and you can actually connect to the device via telnet. Add

10.10.10.1
    mode character
    set crlf

to your ~/.telnetrc, telnet to the device, login as admin with an empty password and you’re in. Who needs passwords when your WiFi connection is unencrypted anyway?

You now have some simple command line interface to control and explore various settings of the device. Use “help”, “ls”, “cd” or “?” for getting some help, enter “up”, “cd ..” for navigating one level back and “logout” to disconnect.

Securing the telnet access

By default, there’s no password on the telnet account. To get some minimal security (the WiFi access is still unencrypted), you can set at least a password:

CMD>
cfg
CFG>
set SYS_ADMPASS top-secret
CFG>
prof save
CFG_save: write 4168 bytes to flash:CFG_CHKSUM=953ad97f, len=4168
CFG_save: old offset=20cc, new=3114

The telnet access, however, will vanish as soon as the device has been set up via the Meross application.

Dumping the SPI flash

Using the command line, it’s actually easy to dump the content of the external flash chip. The “os” section has a command to read via SPI. Reading the full 2MB in one step didn’t work (“out-of-memory”), but splitting it into two 1MB reads worked (spi r 0 1048576 and spi r 100000 1048576).

100000ff 00000000 100000fd 00000000
...
ffffffff ffffffff ffffffff ffffffff

Converting this data back into a binary file is trivial (the hex values are little endian).

Running binwalk -t on the resulting binary showed, that it’s obviously booting from “U-Boot 1.1.3 (Jan 24 2018 - 12:18:18)”:

DECIMAL       HEXADECIMAL     DESCRIPTION
---------------------------------------------------------------------------------------------
74560         0x12340         U-Boot version string, "U-Boot 1.1.3 (Jan 24 2018 - 12:18:18)"
202744        0x317F8         Ubiquiti firmware header, third party, ~CRC32: 0x4000000,
                              version: ";OPEN;OPEN;OPEN"
206936        0x32858         Ubiquiti firmware header, third party, ~CRC32: 0x4000000,
                              version: ";OPEN;OPEN;OPEN"
211104        0x338A0         Ubiquiti firmware header, third party, ~CRC32: 0x4000000,
                              version: ";OPEN;OPEN;OPEN"
327680        0x50000         uImage header, header size: 64 bytes, header CRC: 0x47F13CC1,
                              created: 2018-04-11 02:29:36, image size: 741932 bytes, Data
                              Address: 0x80500000, Entry Point: 0x80500000, data CRC:
                              0xF8DE8099, OS: Linux, CPU: MIPS, image type: Standalone
                              Program, compression type: none, image name: "zxrouter"
337024        0x52480         LZMA compressed data, properties: 0x5D, dictionary size:
                              8388608 bytes, uncompressed size: 2179948 bytes

Let’s extract the compressed image:

dd if=data.bin of=zxrouter.lzma bs=1 skip=337024
xzcat zxrouter.lzma > zxrouter.bin

and run binwalk on the resulting bin file (shortened):

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
116           0x74            eCos kernel exception handler, architecture: MIPSEL, exception
                              vector table base address: 0x80018200
256           0x100           eCos kernel exception handler, architecture: MIPSEL, exception
                              vector table base address: 0x80018200
1680403       0x19A413        eCos RTOS string reference: "eCosAP"
1682040       0x19AA78        HTML document header
1682227       0x19AB33        HTML document footer
1789914       0x1B4FDA        Unix path: /../os/ecos/rt_profile.c
1789921       0x1B4FE1        eCos RTOS string reference: "ecos/rt_profile.c"
1795786       0x1B66CA        Unix path: /../os/ecos/rt_rbus_pci_util.c
1795793       0x1B66D1        eCos RTOS string reference: "ecos/rt_rbus_pci_util.c"
1797406       0x1B6D1E        Unix path: /../../hw_ctrl/cmm_asic_mt.c
1799686       0x1B7606        Unix path: /BW/MCS/STBC/SGI=%d/%d/%d/%d/%d
1800650       0x1B79CA        Unix path: /../../mac/mt_mac.c
1801181       0x1B7BDD        Unix path: /STBC/Nsts/PhyMode/TxRate (RawData)
1807491       0x1B9483        eCos RTOS string reference: "ecos_deliver()"
...