How to read TP-Link factory wireless pin from flash - art

repost from: https://forum.openwrt.org/viewtopic.php?id=69509

Hi! Someone know hot to read tp-link factory wireless pin from flash?
Since I know that the mac address is readable from flash. There some hints online that says that this data resides on art partition.

I want to know how to read the wireless pin (the same on label in the router).

I want to make a OpenWRT image with same SSID and password as stock firmware uses:

The SSID thing is already resolved with this, but I need to know hot to retrieve the password.

cat <<'__EOF__' > ./files/etc/uci-defaults/99_default.sh
#!/bin/sh
[ "$(uci -q get system.@system[0].zonename)" = "America/New York" ] && exit 0
uci batch <<EOC
    set system.@system[0].zonename='America/Argentina/Buenos Aires'
    set wireless.@wifi-iface[0].ssid="TP-LINK_$(ifconfig eth0 | awk '/HWaddr/ { printf $5 }' | tr -d : | tail -c 6)"
    commit
EOC
__EOF__

that print the last 6 digits of mac address.

Thanks.

Edit: I think that this user found it how: MAC of br-lan and wan interface is not matching the real hardware address (Archer C5 v2)

This advice is not about TP-Link, but general advice...

I have fetched the WPS PIN from my Netgear WNDR3700 art partition with the script below. That is a patch directly for the hostapd init script, so that hostapd uses the OEM factory PIN if the user has not set it in the uci config options.

--- a/package/network/services/hostapd/files/hostapd.sh
+++ b/package/network/services/hostapd/files/hostapd.sh
@@ -351,6 +351,11 @@ hostapd_set_bss_options() {
 		set_default wps_manufacturer "www.lede-project.org"
 		set_default wps_independent 1
 
+		# Set WPS label pin to original Netgear value stored in art partition
+		# Value for wps_pin can be overridden by /etc/config/wireless
+		local PINdefault="$(dd if=/dev/mtdblock6 bs=1 skip=18 count=8 2>/dev/null)"
+		set_default wps_pin "$PINdefault"
+
 		wps_state=2
 		[ -n "$wps_configured" ] && wps_state=1
 

The same approach of fetching data from "art" can be used for other purposes. For example, my router's art contains the MAC addresses (3 items), WPS PIN (34063382) and the serial number...

But naturally you need to first look at the art partition contents with a hex editor / hexdump tool, and identify the correct offset.

root@router2:~# hexdump -C /dev/mtd6 | head
00000000  30 46 9a 1b 4d 36 30 46  9a 1b 4d 37 30 46 9a 1b  |0F..M60F..M70F..|
00000010  4d 38 33 34 30 36 33 33  38 32 32 33 52 34 30 37  |M83406338223R407|
00000020  35 34 30 32 33 46 34 ff  ff ff ff ff ff ff ff ff  |54023F4.........|

root@router2:~# dd if=/dev/mtdblock6 bs=1 skip=18 count=8 2>/dev/null
34063382

As you already know the correct PIN from the label, it is pretty easy find the correct offset and then just test with dd command...

And then it is just up to your scripting skills, what you do with the fetched PIN.

2 Likes

Ok, I tried with some of my routers:

  • WA730RE V2.2
  • WA901ND V3.1
  • WR741ND (ES) V4.23
  • WR841N (ES) V8.0
  • WR841N (ES) V9.0
  • WR841N (ES) V9.2
  • WR841N (ES) V10.0
  • WR842ND V2.1
  • WR842N/ND v3
  • WR843ND V1.5
  • WR941ND (ES) V5.1
  • WR1043ND V1
  • WR1043ND V2.1
  • WDR3600 V1.5
  • WDR4300 V1.7

I just found the offset of those bold (others are disconnected currently), using (thanks @DjiPi) :

root@LEDE:~# hexdump -C /dev/mtd0 -s 0x1fe00 | head -n 1
0001fe00  38 30 30 39 31 39 30 35  ff ff ff ff ff ff ff ff  |80091905........|
root@LEDE:~# echo `hexdump -C /dev/mtd0 -s 0x1fe00 | head -n 1 | cut -c 62-69`
80091905
root@LEDE:~# echo `dd if=/dev/mtdblock0 bs=1 skip=130560 count=8 2>/dev/null`
80091905

echo it's just to add the newline.
I searched using (you may need to try all others mtd numbers if you dont found it):

root@LEDE:~# dd if=/dev/mtdblock0 2>/dev/null | hexdump -C | grep 80091905 
0001fe00  38 30 30 39 31 39 30 35  ff ff ff ff ff ff ff ff  |80091905........|

also I have 3 devices with same info:

root@LEDE:~# ls -lath /dev/mtdblock0
brw-r--r--    1 root     root       31,   0 Dec 31  1969 /dev/mtdblock0
root@LEDE:~# ls -lath /dev/mtd0
crw-r--r--    1 root     root       90,   0 Dec 31  1969 /dev/mtd0
root@LEDE:~# ls -lath /dev/mtd0ro
crw-r--r--    1 root     root       90,   1 Dec 31  1969 /dev/mtd0ro

Have you tried with skip=130559 ?

1 Like

Perfect! It works! actually is 130560:

root@LEDE:~# dd if=/dev/mtdblock0 bs=1 skip=130560 count=8 2>/dev/null | hexdump -C
00000000  36 30 38 39 37 37 32 35                           |60897725|

I don't know why when I tried 130560 it did't work, may be I was trying to read other mtd number or something. :frowning:

I made a uci-defaults script that can be added in image building process to autoconfigure SSID and KEY:

mkdir ./files/etc/uci-defaults/
cat <<'__EOF__' > ./files/etc/uci-defaults/99_default-no-eth.sh
#!/bin/sh

[ "$(uci -q get system.@system[0].init)" = "" ] && exit 0
[ -e /etc/init ] && exit 0
touch /etc/init
uci batch <<EOC
    set system.@system[0].init='initiated'
    # This is a TP-Link Router
    set wireless.@wifi-iface[0].ssid="TP-LINK_$(ifconfig eth0 | awk '/HWaddr/ { printf $5 }' | tr -d : | tail -c 6)"
    set wireless.@wifi-iface[0].key="$(dd if=/dev/mtdblock0 bs=1 skip=130560 count=8 2>/dev/null)"
    set wireless.@wifi-iface[0].encryption='psk2+aes'
    commit
EOC

/etc/init.d/network restart
exit 0 # IMPORTANT, IF WE NO PUT THIS, WILL EXECUTED ENDLESSLY
__EOF__

Thank you so much!