TL-WR1043ND Mass Firmware Flashing (DD-WRT/OpenWRT)

With the latest version of the stock TP-Link TL-WR1043ND firmware it changed its way of authenticating users to the router’s administration page, from Basic AUTH to Form base authentication. This meant that the previous solution for mass flashing these routers from stock to 3rd party wasn’t the same.
Old way : http://wiki.openwrt.org/toh/tp-link/tl-wr1043nd#oem.mass.flashing

After further examing the new firmware’s GUI it seemed they now added two new variables to the authentication process. Variable cmp and session.

My task was to find a way to mass flash many of these as fast as possible, I wrote a small bash script that would do just that. All you need to do is save this script as something like “script.sh” and run through CLI

sh script.sh factory-to-ddwrt.bin

Cookie explanation:

Cookie is composed of a base64-URLEncoded username and password

cookie = "Authorization="+URLencode("Basic "+BASE64("admin:admin"))+";domain=192.168.1.1;path=/";

Script

#!/bin/bash

curl -v
--cookie "Authorization=Basic%20YWRtaW46YWRtaW4%3D;domain=192.168.1.1;path=/"
--header "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
http://192.168.1.1 > "first_output.txt"

cmp = `sed -n 18p "first_output.txt" | awk -F '"' '{print $2}'`
session = `sed -n 18p "first_output.txt" | awk -F '"' '{print $4}'`

curl -v
--cookie "Authorization=Basic%20YWRtaW46YWRtaW4%3D;domain=192.168.1.1;path=/"
--header "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
--referer 'http://192.168.1.1/userRpm/SoftwareUpgradeRpm.htm'
--form "Filename=@$1" -F 'Upgrade=Upgrade' -F 'cmp=$cmp' -F 'session=$session'
http://192.168.1.1/incoming/Firmware.htm > /dev/null

sleep 1

curl -v
--max-time 2
--cookie "Authorization=Basic%20YWRtaW46YWRtaW4%3D;domain=192.168.1.1;path=/"
--header "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
--referer 'http://192.168.1.1/incoming/Firmware.htm'
http://192.168.1.1/userRpm/FirmwareUpdateTemp.htm > /dev/null

  • Guest

    Hi Francisco,

    Thank you very much for the post!

    Somehow I needed to adapt the script, just copy and paste from your script didn’t work with my TL-WR1043ND. I’m using the newest TP-Link firmware version.

    Here my PHP script. I’m sure my script can be optimized, since it probably does more than it needed to and I’m far from being a PHP expert.

    But it worked with my router (sorry I didn’t find how to post scripts nicely as you did).

    “@” . $cfile, “Upgrade” => “Upgrade”, “cmp” => $cmp, “session” => $session);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    curl_setopt($ch, CURLOPT_REFERER, $referer);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    $htmlReturn = curl_exec($ch);
    curl_close($ch);

    sleep(1);

    // send temp request
    // no return here is expected, but it didn’t work without it
    $url = “http://” . $host . “/userRpm/FirmwareUpdateTemp.htm”;
    $referer = “http://” . $host . “/incoming/Firmware.htm”;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    curl_setopt($ch, CURLOPT_REFERER, $referer);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 2);
    $a = curl_exec($ch);
    curl_close($ch);

    ?>

    • Sometimes copy and paste for a shell script fails because of formatting. Try creating the shell script from the cli and pasting it there.

  • Ricardo Carvalho

    let me see if I manage to post the whole script now.

    PHP begin
    ————-

    $host = “192.168.4.100”;

    $userAgent = “Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:12.0) Gecko/20100101 Firefox/25.0”;
    $url = “http://” . $host . “/”;
    $referer = “http://” . $host . “/”;
    // user “admin”, pw “admin”
    $cookie = “Authorization=Basic%20YWRtaW46YWRtaW4%3D”;
    $cfile = realpath(“/var/www/routerconfig/firmware/openwrt-ar71xx-generic-tl-wr1043nd-v1-squashfs-factory.bin”);

    $header[] = “Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8”;
    $header[] = “Accept-Language: en-US,en;q=0.5”;
    $header[] = “Accept-Encoding: gzip, deflate”;
    $header[] = “Connection: keep-alive”;

    // Login page
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    $a = curl_exec($ch);
    curl_close($ch);

    sleep(1);

    // Get cmp and session values
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_REFERER, $referer);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    $htmlReturn = curl_exec($ch);
    curl_close($ch);

    // extract cmp and session values

    // search string “var fileParaFS” and ignore everything before it
    $fileParaFSPos = strpos($htmlReturn, “var fileParaFS”);
    $htmlReturn = substr($htmlReturn, $fileParaFSPos);

    // search first double quotation mark and ignore everything before it
    $pos = strpos($htmlReturn, ‘”‘);
    $htmlReturn = substr($htmlReturn, $pos);

    // get cmp and session values
    $fileParaFS = str_getcsv($htmlReturn, ‘,’, ‘”‘);
    $cmp = $fileParaFS[0];
    $session = $fileParaFS[1];

    sleep(1);

    // upload firmware
    $url = “http://” . $host . “/incoming/Firmware.htm”;
    $referer = “http://” . $host . “/userRpm/SoftwareUpgradeRpm.htm”;
    $data = array(“Filename” => “@” . $cfile, “Upgrade” => “Upgrade”, “cmp” => $cmp, “session” => $session);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    curl_setopt($ch, CURLOPT_REFERER, $referer);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    $htmlReturn = curl_exec($ch);
    curl_close($ch);

    sleep(1);

    // send temp request
    // no return here is expected, but it didn’t work without it
    $url = “http://” . $host . “/userRpm/FirmwareUpdateTemp.htm”;
    $referer = “http://” . $host . “/incoming/Firmware.htm”;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    curl_setopt($ch, CURLOPT_REFERER, $referer);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 2);
    $a = curl_exec($ch);
    curl_close($ch);

    ——————————
    PHP end