Adding OpenWrt support for TP-Link EAP245

I have an TP EA-225-Outdoor(EU) Ver 1.1.
I can not find the serial port. Any idea where it is?

I've done a quick and dirty patch that seems to work.

edit: HERE
edit2: I badly tested it. It doesn't work, if the board is not power down, it keep working if i've done tftpboot
edit3: This time it seems to work fine:

  • serdes initialization must be done at start of probe
  • rgmii-ge0, ge0-sgmii, rxdv-delay and/or rxd-delay need to be set instead I get "eth0: tx timeout" from refused PR
1 Like

No idea, look for R225 and R237.

1 Like

Does someone knows how to remove the cover of the EAP245? heh

You have a v1 right? First remove the screws below the rubber fillers (green circles). Then you need to click open four clips. Easiest to carefully pry a spudger between the top and bottom of the case. If you apply to pressure on the edge of the lid towards the center, it releases a bit more easily. First try the sides and the side of the LED. The connectors side is harder to open first, because of the extra ridges at the side of the lid.

Edit: Note that the antennas are in the lid, so be careful when opening the case. Write down which coax cable leads to which connector when disconnecting them.

1 Like

I did some more digging, and here's my how-to on flashing an EAP245v1 without soldering. This should work on firmware version 1.4.0 (the last version).

It's probably easiest if you have a direct connection between your PC (with a static IP) and the access point. I've used the default address of 192.168.0.254 below.

Step 1: Obtain root a hell
In the web inferface of the EAP245v1, go to the user management page. As new username, enter ;/usr/sbin/telnetd -l/bin/sh&. The password doesn't matter, but doesn't have to be modified. After saving, change the username back to something valid (the old value) by putting ;/usr/sbin/telnetd -l/bin/sh& in the old username field. You have to change it back, because you will need ssh access. I will use 'admin' in the next steps.

By changing the username to the above value, you've exploited an error that runs unescaped user input and started the telnet server. Verify that you can access the root shell by connecting to port 23. For example:
$ nc 192.168.0.254 23

Step 2: Create a writeable target
From your root shell modify /tmp to be world writeable:
# chmod 777 /tmp

Non-working procedure; see post #110 below

Step 3: Patch uclited
Copy the uclited daemon from your AP to your PC:
ssh admin@192.168.0.254 "dd if=/usr/bin/uclited" | dd of=uclited

Using your tool of preference, modify the byte at position 825900 (0xC9A2C) from 0x10 to 0x14. The original file (uclited) and patched file (uclited-norsa) should have the following byte sequences:

$ xxd -g4 -s825892 -l16 uclited
000c9a24: 9222c12c 00000000 10400074 3c100060  .".,.....@.t<..`
$ xxd -g4 -s825892 -l16 uclited-norsa
000c9a24: 9222c12c 00000000 14400074 3c100060  .".,.....@.t<..`

This patch changes:

if (rsa_key[0] != '\0') { 
    [rsa verification]
    [exit if signature invalid]
}
[continue upgrade]

into:

if (rsa_key[0] == '\0') { 
    [ignored code]
}
[continue upgrade]

thus effectively disabling the RSA signature check. Because the code continues with the upgrade if the RSA check didn't cause an exit, having a valid key loaded from flash will now cause the signature check to be disabled instead of enabled.

Copy the patched uclited daemon back to the target device:
$ dd if=uclited-norsa | ssh admin@192.168.0.254 "dd of=/tmp/uclited-norsa"

Step 4: Run the patched web interface
From the root shell again, kill the stock uclited and start the patched uclited-norsa

# uclited -k
# chmod +x /tmp/uclited-norsa
# /tmp/uclited-norsa &

Starting the daemon will result in quite a bit of output being printed to the shell, but after a bit you should be able to log in to your device's web interface again.

Step 5: Upload OpenWrt factory image
The access point won't verify the signature anymore now, but you still need to have a "signature" present to pass some other file length checks. The following works in bash and appends 128 bytes (1024 bits) of zeros to the factory image:

$ cat openwrt-ath79-generic-tplink_eap245-v1-squashfs-factory.bin \
      <(dd if=/dev/zero bs=128 count=1) > factory-padded.bin

You can now finish the process by uploading your padded image via the stock web interface. :partying_face:

1 Like

Alright friend, thanks for your work! I'll try it out tomorrow!

New test builds for EAP245v3, easy flashing instructions included (No soldering required!)
@PolynomialDivision This method would also work for the EAP225v3, and probably the EAP225OD.

1 Like

Unfortunately i'm not able to proceed there.
I receive the following error.

ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 admin@192.168.2.108 "dd if=/usr/bin/uclited" | dd of=uclited
admin@192.168.2.108's password: 
exec request failed on channel 0
0 bytes copied, 2,70497 s, 0,0 kB/s

You have to enable ssh in web interface first.

Thanks, i was surprised, because the port wasn't blocked. Thanks!
Can someone provide a prebuilt image? I got a huge lack of processing power with my T400, quite difficult to compile within a day.

My ath79 build: https://github.com/svanheule/openwrt/releases/tag/f87183f
j-d-r's ar71xx build is linked above (post #66)

1 Like

Thanks! Unfortunately i'm stuck right here.
After issuing these commands, i'm not able to access the web interface anymore, it's not being resolved.
I have resetted the device, and tried everything again, but same behaviour.

That's what i got

# /tmp/uclited-norsa &
/tmp/uclited-norsa &
# 

Monitor Thread pid(14417), tid(5126) created.
[ucGetFactoryMode:167]: enable: 0 
[ucFactoryMode_init:93]: enable: 0 
kill: 1: kill 362: No such process
kill: 1: kill 359: No such process
device br0 already exists; can't create bridge with the same name
device eth0 is already a member of a bridge; can't enslave it to bridge br0.
interface eth1 does not exist!
SIOCGIFFLAGS: No such device
SIOCGIFFLAGS: No such device
SIOCSIFHWADDR: No such device
SIOCGIFFLAGS: No such device
insmod: cannot open module `/lib/modules/3.3.8/kernel/br_dhcp_filter.ko': No such file or directory
Rsa verify success
insmod: cannot insert `/lib/modules/3.3.8/net/adf.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/net/asf.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/net/ath_hal.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/net/ath_rate_atheros.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/net/ath_spectral.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/net/ath_dfs.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/net/ath_dev.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/net/umac.ko': File exists (-1): File exists
Interface doesn't accept private ioctl...
setHwaddr (8BE4): Device or resource busy
Interface doesn't accept private ioctl...
HALDbg (8BE0): Operation not permitted
wlanconfig: ioctl: Invalid argument
[dhcpcStart:493]dhcpc start:status:3 isrouter:0 wanIfName:eth0
info, udhcpc (v0.9.9-pre) started
Interface doesn't accept private ioctl...
ForBiasAuto (8BE0): Operation not permitted
route: SIOC[ADD|DEL]RT: No such process
device ath0 is already a member of a bridge; can't enslave it to bridge br0.
[regwrite 81]ioctl eth0 failed!
ath8      no private ioctls.

Interface doesn't accept private ioctl...
setHwaddr (8BE4): Device or resource busy
Invalid command : HALDbg
Invalid command : chainmasksel
Interface doesn't accept private ioctl...
AMPDU (8BE0): Operation not permitted
Interface doesn't accept private ioctl...
AMPDUFrames (8BE0): Operation not permitted
Interface doesn't accept private ioctl...
AMPDULim (8BE0): Operation not permitted
wlanconfig: ioctl: Invalid argument
Invalid command : ForBiasAuto
Error for wireless request "Set Fragmentation Threshold" (8B24) :
    SET failed on device ath10 ; Invalid argument.
device ath10 is already a member of a bridge; can't enslave it to bridge br0.
[regwrite 81]ioctl eth0 failed!
ath18     no private ioctls.

[_portal_notifySSID,1625] ssid(TP-Link_2.4GHz_2E2856), https(1).
[_portal_notifySSID,1625] ssid(TP-Link_5GHz_2E2857), https(1).
insmod: cannot insert `/lib/modules/3.3.8/kernel/nf_conntrack_proto_gre.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/kernel/nf_conntrack_pptp.ko': File exists (-1): File exists
insmod: cannot insert `/lib/modules/3.3.8/kernel/nf_nat_pptp.ko': File exists (-1): File exists
sh: cannot create /proc/net/tp_mroute/wan_eth_name: Directory nonexistent
sh: cannot create /proc/net/tp_mroute/tp_mroute_enable: Directory nonexistent


raThread pid(14417) tid(16399) created.

TDDP: Socket address bind error. 
tddp initialize failed, create socket error.
bind() failed.


[1] + Done(1)                    /tmp/uclited-norsa

Strange, I can't get it to work any more either. I must have done something subtly different, but I can't really recall :frowning:

1 Like

Hmm okay, i'll try something else, btw. is it somehow possible to get full SSH root access after having root access with telnet?
I'll try to use the uclited commandline way in order to flash it, using the norsa version.
Btw. is -r necessary as well?

./uclited --help
Usage:  ./uclited [-krfhv] [--help] [--version]
        [-k, --kill]    kill all uclited threads
        [-r, --reset]   start uclited, and reset all settings to default
        [-f, --product] update the product-info.
        [-h, --help]    help
        [-v, --version] version
        [-u, --upgrade] upgrade fireware, please save upgrade file in /tmp/upgrade.bin before use this command
        [-p, --partion] show partion table of nvrammngr
        [-s, --showpid] show product-info

Hmm, don't know if it's successfull.

./uclited-norsa -u

Begin Debug Mode Fireware Upgrade
Upgrade fireware size is 5908025 bytes
Upgrade fireware md5 checksum is correct!
Process 11597 Catch signal 11: 
  code = 1      errno = 0
Dump regs:
   pc: 77e0276c  
 zero: 00000000     at: 0103a982     v0: 7f8177a8     v1: 00000000  
   a0: 7f8177a8     a1: 00000000     a2: 00000014     a3: 00000a40  
   t0: 00000014     t1: 00000000     t2: 00000001     t3: 00565eb3  
   t4: fffffffe     t5: 00000001     t6: 00000000     t7: 00000400  
   s0: 7f8177a8     s1: 00000003     s2: 00000020     s3: 00000030  
   s4: 0057a5dc     s5: 007ac580     s6: 00000005     s7: 007ac580  
   t8: 00000010     t9: 77e02720     k0: 0a0a0a0a     k1: 00000000  
   gp: 005b2610     sp: 7f817770  fp/s8: 00000003     ra: 004c05f0  
Dump mem stack: 
 (STACK: 0x7f7f8000 ~ 0x7f819000 SP: 0x7f817770)
 0x7f817770: 00000000 00000000 00000000 00000000 005b2610 00000000 00000000 004c5e2c 
 0x7f817790: 00000000 00000000 00000000 00000000 005b2610 00000000 00000000 00000000 
 0x7f8177b0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8177d0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f8177f0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f817810: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f817830: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f817850: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 0x7f817870: ......
Dump call stack:
  #00  pc 0002d76c  /lib/libuClibc-0.9.30.so (memcpy+76)
  #01  pc 000c05e8  /tmp/uclited-norsa (ucCluster_getCfg+40)
  #02  pc 000c5e24  /tmp/uclited-norsa (swIsClusterMode+64)
  #03  pc 000d1a1c  /tmp/uclited-norsa (nm_checkUpdateContent+668)
  #04  pc 000d2264  /tmp/uclited-norsa (nm_buildUpgradeStruct+1268)
  #05  pc 00137f58  /tmp/uclited-norsa (uclite_upgrade_debug+520)
  #06  pc 00138214  /tmp/uclited-norsa (main+276)
  #07  pc 0004f858  /lib/libuClibc-0.9.30.so (__uClibc_main+600)
Exiting...

Quite funny, 2nd try of issuing the same command.

./uclited-norsa -u
./uclited-norsa -u

Begin Debug Mode Fireware Upgrade
Upgrade fireware size is 5908025 bytes
Upgrade fireware md5 checksum is not correct!

Seems like uclited is destroying the openwrt bin file.

On my device with a v1.4 firmware, I can log in with root:admin from the serial port. But if I try those credentials via telnet (with telnetd instead of telnetd -l/bin/sh) it doesn't work. Maybe something to do with the way newlines are entered...

uclited -u also crashed if you feed it a TP-Link firmware, so that doesn't work sadly enough.

uclited checks the md5sum by writing the checksum seed to start of the file where the calculated checksum is. I'm guessing it actually writes it to the file instead of just to ram. TP-Link's code is... not very good. Also note how it says "fireware" :smiley:

1 Like

Alright heh, i'll try some other things.
Btw. do you know which "arch" we got here? Some kind of arm?
And do you think it might be possible to write the image using a SOIC-8 flasher?

32 bit MIPS, big endian:

# cat /proc/cpuinfo 
system type		: Qualcomm Atheros QCA956X ver 1 rev 0
machine			: TP-LINK EAP245 v1
cpu model		: MIPS 74Kc V5.0

Yes, I've read out the flash with an SOIC-8 clip and a Raspberry Pi. But the 3.3V line draws so much power that my RPi browns out (voltage drop due to current spike) and may have to be rebooted. So be careful with how you wire it up.

Alright, i'll give it a try. I'll also try to get a "passwd" binary somewhere in order to get the SSH access.

TP-Link uses a patched dropbear. The user credentials you enter via the web interface aren't actually for an OS user, but are stored in /tmp/dropbear_info (I think). So I don't think it's even possible to log in as root, but I would have to look at the dropbear sources to be sure.