Obtaining the firmware for Linksys E4200v2

| firmware | linksys | Linux | router

I recently got a Linksys E4200v2 wireless router. It’s pretty cool, supports IPv6, 2.4Ghz and 5Ghz wifi networks, VPN, etc. The one downside is that the firmware for the router is not available from Linksys’s website, and the GPL code has not been made available, yet… However, the router has been able to pull updates itself from the Internet.

So I wanted to acquire the firmware to see if I could do something fun with the router. I set about to figure out how the router does this. My plan was to set my laptop up between Internet interface on the router, and the cable modem. Since my laptop doesn’t have two network cards, I plugged into a switch and used Ethercap to ARP poison to redirect traffic via the laptop.

Then using Wireshark I could see the traffic coming out of the router. All I needed to do now was to hit the “check for updates button”.

Firstly I saw two DNS requests, one for the AAAA (IPv6) record for update.linksys.com, then a A request for update.linksys.com. Clearly the updates are coming from there. Secondly I saw a HTTPS connection form to that domain. That makes this a little more complex, as I am unable to see the encrypted traffic, and thus see what is being transferred.

So, I grabbed a simple DNS server, and set up a simple SSL server following these instructions.

Now with DNS spoofing, and a fake SSL server, I could intercept encrypted traffic from the router, as long as it does not validate the SSL certificate. Luckily it didn’t check the validity, and thus I was able to capture the request: (BTW Not checking the cert completely defeats the point of using SSL… bad Linksys!).

POST /cds/update HTTP/1.1
Host: update.linksys.com
Accept: */*
Content-Type: text/xml
Content-Length: 573

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <ns:GetFirmwareFromDeviceRequest xmlns:ns="http://cisco.com/schemas">
      <ns:LanguageCode>en</ns:LanguageCode>
      <ns:CountryCode>us</ns:CountryCode>
      <ns:MacAddress>12:34:56:78:90:ab</ns:MacAddress>
      <ns:ModelNo>E4200</ns:ModelNo>
      <ns:HardwareVersion>2</ns:HardwareVersion>
      <ns:CurrentFirmwareVersion>2.0.36.126507</ns:CurrentFirmwareVersion>
    </ns:GetFirmwareFromDeviceRequest>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

and the response:

HTTP/1.1 200 OK
Content-Language: en-US
Content-Type: text/xml
SOAPAction: ""

<soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Header/>
  <soapenv:Body>
    <ns:GetFirmwareFromDeviceResponse xmlns:ns="http://cisco.com/schemas">
      <ns:FirmwareList xmlns:ns="http://cisco.com/schemas">
        <ns:Firmware xmlns:ns="http://cisco.com/schemas">
          <ns:Version xmlns:ns="http://cisco.com/schemas">2.0.36.126507</ns:Version>
          <ns:Revision xmlns:ns="http://cisco.com/schemas">D</ns:Revision>
          <ns:ReleaseDate xmlns:ns="http://cisco.com/schemas">2012-01-06T16:48:08Z</ns:ReleaseDate>
          <ns:DownloadURI xmlns:ns="http://cisco.com/schemas">http://download.linksys.com/updates/to0037258865.pdx/FW_E4200_2.0.36.126507.SSA</ns:DownloadURI>
          <ns:DateFormat xmlns:ns="http://cisco.com/schemas">yyyy-MM-dd';T';HH:mm:ss';Z';</ns:DateFormat>
          <ns:Checksum xmlns:ns="http://cisco.com/schemas">1958710861</ns:Checksum>
        </ns:Firmware>
      </ns:FirmwareList>
    </ns:GetFirmwareFromDeviceResponse>
  </soapenv:Body>
</soapenv:Envelope>

(I slightly modified portions of the request and response to hide the identify of my router.).

I might write a script to make fake requests, but until then you can easily create a request with curl:

curl -d @request.raw https://update.linksys.com/cds/update

Then you just extract the DownloadURI and

curl http://download.linksys.com/updates/to0037258865.pdx/FW_E4200_2.0.36.126507.SSA

Voila I now have the firmware. Now I need to figure out what to do with it.

Update: As requested I fetched the more recent version of the file:
2.0.37.131047 – http://download.linksys.com/updates/to0040829450.pdx/FW_E4200_2.0.37.131047.SSA