Deobfuscating the Edimax SP-2101W cloud protocol

As i mentioned in another post, the Edimax SP-2101W sends out packets to the cloud, that are obfuscated somewhat, but not really encrypted.

I don’t really understand why the edimax engieers did that; In my opinion, they chose the worst path they could go. If you’re sending data to the cloud:

  • either, send plain text, and tell everyone what you’re sending and when you’re sending it. That way, nothing is hidden, and anyone can check your claim that nothing harmful is sent.
  • or, use strong encryption for your data, and tell everyone how you’re encrypting it, so people can have confidence that noone will be able to read what you’re sending.

By obfuscating the data in a really primitive way, you don’t protect customer’s data, but you deprive people of checking what’s actually sent. This just builds distrust, and will give you a “XXX’s cloud encryption hacked” headline some day in the – not too far – future.

Anyway, here’s how it works:

  • Every 10 seconds, the device sends a UDP packet to This packet doesn’t contain any “real” data, it’s just 4 bytes payload, and it seems to serve only to keep the udp connection within your firewall/router open.
  • Whenever the cloud and the device communicate data, they use obfuscated XML data. The first byte is always a '<' (hex 3c), just as XML data would assume, plus a random value between 1 and 7. The receiver can retrieve this value by subtracting 0x3c from the 1st byte it receives.
  • Every byte from the 2nd one is bit-rotated by the number retrieved in the first step.

So, for example, the device might send the hex string


The first byte is 0x3d, 0x3c+1, which means the other bytes are rotated to the right by 1 bit.

The second byte, 0x38, must be rotated to the left by one bit, which yields 0x70, or 'p'.

The third byte, rotated to the left, is 0x41, or 'a'.

Continuing with this, the whole message reads

<param><code value="3000" /></param>

A longer example has all bytes rotated by 5 bits:


which decodes to

<code value="1010" />
<model value="SP-2101W" />
<id value="801F02FA64A5" />
<type value="SmartPlug" />
<alias value="Trockner" />
<lanip value="" />
<lanport value="49136" />
<sn value="KKKKKKKK" />
<encryption value="0" />
<nattype value="7" />
<devfwver value="1.03#010001" />
<productid value="EDIMAX#SP-2101W#1.0#1.03" />

I wrote a C program to help in decoding, if anyone is interested. Pass the hex string as argument on the command line; if no argument is present, the test string will be decoded.

char *teststr="41830b930b6bf150e11b7b232b01b30b63ab2be91189818981110179f150"

int main(int argc, char **argv) {
  char *bytes=teststr;
  if (argc>1)
  int rotate=0;
  while (*bytes && bytes[1]) {
    int val;
    sscanf(bytes, "%02x", &val);
    if (rotate==0) {
    } else {
      val=(val&0xff) | ((val&0xff00)>>8);

When your tablet communicates with the edimax, it uses the LAN if it can; if it can’t, it’ll contact as its proxy. The proxy will then send a message via udp, which, decoded, reads:

<param><code value="1040" /><devip value="92.211.XX.YYY" /><devport value="58296" /><reqip value="80.187.XX.YYY" /><reqport value="31228" /><connip value="80.187.XX.YYY" /><connport value="31228" /><samelan value="0" /><relayip value="" /><relaydevport value="8767" /><relayreqport value="8768" /><relayid value="e231d35c.e3b8.fb6abb50.79fc" /><nettype value="D" /><natweight value="14" /><reqfwver value="1.0#010000" /><reqdirport value="0" /><auth value="38f989453c733de4afaf64XXXXXXXXXX" /><seq value="801F02FA70BF141XXXXXXXXXX" /><delay value="500" /><relaytype value="" /><punchingtime value="" /></param>

This will cause the Edimax to open a TCP connection to the ip referenced in the UDP packet, and the cloud will send XML requests which are identical to the HTTP post content to the smartplug.cgi service. For example:

<?xml version="1.0" encoding="UTF8"?><SMARTPLUG id="edimax"><CMD id="get"><NOW_POWER><Device.System.Power.NowCurrent></Device.System.Power.NowCurrent><Device.System.Power.NowPower></Device.System.Power.NowPower></NOW_POWER></CMD></SMARTPLUG>

To which the Edimax responds with:

PnvDataLen: 445

plus a '<' (that has a 1-7 added to it, as above) plus the encoded response of the web server, e.g.:

HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 253
Date: Fri, 05 Dec 2014 21:40:03 GMT
Server: lighttpd/1.4.31

<?xml version="1.0" encoding="UTF8"?><SMARTPLUG id="edimax"><CMD 

If you want to check the protocol yourself, you can add a dissector i've written to wireshark to see the decoded messages directly. Just put the init.lua file into $HOME/wireshark in Linux, or into
in windows.

3 thoughts on “Deobfuscating the Edimax SP-2101W cloud protocol

Leave a Reply

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