Acer predator connect W6x

The firmware runs /sbin/check-image 2>&1 > /dev/null on firmware upload, which is basicaly just fwhandle -x /tmp/image_enc.img -y /tmp/image_dec.img -r /tmp/img_decode_result -i "$model_name" -t kernel_pad_fs. fwhandle is a binary which I haven't yet checked in detail.

After if check-image succeeds, it runs /sbin/sysupgrade -F -v /tmp/image_dec.img &

There is also telnet functionality in the firmware, which can be activated with a script. Unfortunately accessing the router via telnet requires a login which I do not know.

enableTelnet.py
#!/bin/python
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
from base64 import b64decode, b64encode
import argparse
import json
import requests

# Replace here with your own
ADMIN_PASSWORD = "TEMPLATE"
ROUTER_IP = "192.168.76.1" # Default is 192.168.76.1

#-----------------------------
parser = argparse.ArgumentParser(
    prog = "enableTelnet.py",
    description = "Script to enable telnet access on Acer Predator Connect W6x router",
    epilog = "Password & IP can be set by editing values of ADMIN_PASSWORD and ROUTER_IP")

if ADMIN_PASSWORD == "TEMPLATE":
    parser.add_argument("password", help="The admin password for the webui", type=str)
else:
    parser.add_argument("password", nargs='?', help="The admin password for the webui", type=str)
parser.add_argument("IP", nargs='?', help="Router's IP address, leave blank for 192.168.76.1", type=str)
args = parser.parse_args()

if args.password:
    ADMIN_PASSWORD = args.password
if args.IP:
    ROUTER_IP = args.IP

# ----------------------------
key_X = "L6bb2tAt3oxzCGwkSfsqtzOALHJLJ1MB".encode('utf-8') 
iv_X = "hobh264Tk21UfDPM".encode('utf-8')

template_login = f'{{"action":"login_telnet","aesLocalRandomKey":"bkcx1z2uoqrepfrlj3mylqdwmqlz34wp51da1a0e5de3qe1wv39wpg5pn8f6j1h7","loginpwd":"{ADMIN_PASSWORD}","accesstoken":null}}'
template_telnet = '{{"action":"set_telnet_config","enable":true,"accesstoken":"{0}"}}'
template_enDataX = '{{"enDataX":"{0}"}}'

router_url = f"http://{ROUTER_IP}/cgi-bin/web_cgi"

def decode(data, key, iv):
	cipher = AES.new(key, AES.MODE_CBC, iv)
	data_bytes = b64decode(data)
	dec_data = cipher.decrypt(data_bytes)
	unpadded_data = unpad(dec_data, AES.block_size)
	return unpadded_data.decode('utf-8')

def encode(data, key, iv):
	cipher = AES.new(key, AES.MODE_CBC, iv)
	pad_data = pad(data.encode('utf-8'), AES.block_size)
	enc_data = cipher.encrypt(pad_data)
	return b64encode(enc_data).decode('utf-8')

# Login request
login_enDataX = encode(template_login, key_X, iv_X)
login_request_data = template_enDataX.format(login_enDataX)
login_request = requests.post(router_url, data=login_request_data)

if login_request.status_code == 502:
    print(f"Login request failed - malformed request")
    print(login_request_data)
    exit()
elif login_request.status_code != 200:
    print(f"Login request failed - {router_url} returned http code {login_request.status_code}")
    exit()

login_response_encoded = login_request.text
login_response_json_string = decode(login_response_encoded.strip(), key_X, iv_X)
login_response_json = json.loads(login_response_json_string)

login_request_fail_cause = login_response_json.get('cause')
if login_request_fail_cause:
    if login_request_fail_cause == "Already login":
        print("Login failed - Already logged in")
        print("Wait until auth expires (few minutes)")
    else:
        print(f"Login failed - cause: {login_request_fail_cause}")
    exit()

accesstoken = login_response_json.get('accesstoken')

# Telnet enable request
telnet_enDataX = encode(template_telnet.format(accesstoken), key_X, iv_X)
telnet_request_data = template_enDataX.format(telnet_enDataX)
telnet_request = requests.post(router_url, data=telnet_request_data)

if telnet_request.status_code == 502:
    print("Login request failed - malformed request")
    exit()
elif telnet_request.status_code == 401:
    print("Login request failed - auth somehow failed")
    exit()
elif telnet_request.status_code != 200:
    print(f"Login request failed - {router_url} returned http code {telnet_request.status_code}")
    exit()

telnet_response_encoded = telnet_request.text
telnet_response_json_string = decode(telnet_response_encoded.strip(), key_X, iv_X)
telnet_response_json = json.loads(telnet_response_json_string)

if telnet_response_json.get("result") == 0:
    print("Telnet access enabled for current boot")
1 Like

Using the web gui to upgrade seems doable. fwhandle allows for encoding firmware images, and the decoding the manually encoded firmware also works. Theoretically you can now run sysupgrade -F -v firmware_img.bin on any image uploaded. Here is the newest stock firmware from the fota server:

Encoded: https://www.mediafire.com/file/yuhcuekxg7x0yom/W6x-1.01.000015.bin/file
Decoded: https://www.mediafire.com/file/xj4tu8uyarczvlk/W6x_1.01.000015_DECODED.img/file

The encoded one should directly work in localUpdate. How should the firmware upgrade to normal openwrt proceed as W6x runs OpenWrt 21.02-SNAPSHOT? afaik upgarding directly to 24.10 isn't supported. Or would it be best/easiest to edit the stock firmware to allow for remote root login or something?

Here is also the sysupgrade to normal openwrt for this device encoded by fwhandle: https://www.mediafire.com/file/jw2dlbs2json4jc/openwrt-mediatek-filogic-acer_predator-w6x-stock-squashfs-sysupgrade_ENCODED.bin/file
Whether it works/bricks/does anything is entirely untested.

Telnet login also works with credentials: admin:Admin1234
(activate telnet first with script above)

5 Likes

tried the backup-restore method described earlier in this thread on my Acer Predator Connect W6x (model G2TTA.002), but it seems that newer firmware blocks the modification.

I unpacked the backup file, edited /etc/passwd as described, repacked it, and restored it via the WebGUI. The restore appeared to succeed, but the router did not apply the modified authentication files. After reboot, Telnet still asks for the root password, and the original credentials remain unchanged.

1 Like

Thank you for trying it out, the failure is my bad. I didn't realize that tar includes the backup folder when doing backup/etc and backup/data instead of directly just etc/ and data/. Here's the fixed guide:

Getting root access to stock fw without uart:

  1. Backup settings from the webgui
  2. Enable telnet login with enableTelnet.py
  3. telnet $router_ip
  4. login as admin:Admin1234 (from /#/system/usbStorage)
  5. run cd /tmp
  6. run mkdir backup
  7. run tar -C backup/ -xzf backup_settings.bin
  8. run cd backup
  9. run sed -i '1s/x//' etc/passwd
  10. run tar -czf backup_settings_modified.bin etc/ data/
  11. run fwhandle -s backup_settings_modified.bin -d backup_settings_finished.bin
  12. Start an tftp server on your host machine with upload enabled
  13. run tftp -p -l backup_settings_finished.bin -r backup_settings.bin $tftp_server_ip
  14. Restore settings with the newly recieved backup_settings.bin via the web gui
  15. Wait for the router to restart
  16. Enable telnet again with enableTelnet.py
  17. Login as root

Additionally: How to encode firmware images for them to be accepted by web gui localUpdate: run fwhandle -s fwimage_src_file -d fwimage_result_file -i "W6x" -t kernel_pad_fs

1 Like

Thank you very much. It worked! Now I have root access.
Now I will try to flash openwrt.
Edit.
Now the router is in a state of soft-brick... This is what I did:

After gaining root access I uploaded the renamed acer_predator-w6x-stock-squashfs-sysupgrade.bin to the router using:
cd /tmp
tftp -g -r openwrt.bin 192.168.76.111 and executed sysupgrade -F -v /tmp/openwrt.bin

Now the router has the same ip address 192.168.76.1 but I cannot access it.

How I can fix this? Should I use the USB to TTL method?

2 Likes

It probably is the only option if you are unable to access it otherwise. Someone else with more familiarity with openwrt & such may be able to help more.

try to acess it using ssh as root.
if sucesses you going to have to configure to have internet acess, update packages and install luci for the web gui.

edit:

tried to follow your steps, ended in the same place as you. i will try using usb to uart now.

@MattyStonnie the problem was that you used the sysupgrade command without the -n, so the router upgraded and used the old configurations, with ssh and telnet disabled.

SSH didn’t work because the ports was blocked.

Also I saw there was another partition as a backup, I was able to boot the stock firmware and switch to the first one, the second partition was corrupt.

I used USB to TTL with soldering on the motherboard to unbrick it.

Care to explain how you activated the other partition?

Don't you want to try the same steps but using sysupgrade -n instead? It would be really nice to have a step-by-step to flash Openwrt without uart.

2 Likes

In uboot console, run mkdual set 1 and then reset or 'mkdual set 2', see which one works.

My second partition was corrupt (mkdual set 2).

I selected with ‘mkdual set 2’ (the second partition) and installed here Openwrt. One the first partition I have the original stock working system and I can switch back when I want.

1 Like

How did you fix the wireless? I have no working wireless... build is r32305-52fa3728e5

Edit:

While trying to enable the wireless antennas, I managed to hard-brick the router, and it turned into quite an adventure to recover it using a USB-to-TTL adapter. Everything is fine now — the router is working properly, wireless is up, and I’m getting good speeds.

I’m also considering adding a fan on top of the heatsink for better cooling.

I have one more question: does anyone know how to configure the LED? In the LuCI interface it only works in a light blue color, while the stock firmware supports both blue and red

1 Like

* LEDS:
LED color can be controlled by specifying values in GRB format in `/sys/class/leds/rgb:status/multi_intensity`. Default is `255 255 255` (white).
Example: `echo '75 0 130' > /sys/class/leds/rgb:status/multi_intensity`

LED brightness can be changed by specifying the value from 0-255 in /sys/class/leds/rgb:status/brightness. Default is `255` (full brightness).
Example: `echo 100 > /sys/class/leds/rgb:status/brightness`

For persistence across reboots, put the relevant command(s) in /etc/rc.local.

3 Likes

There's a wiki page for this device.

1 Like

I know how to do that, but what I want is for the LED to be blue when the internet connection is up and red when it’s down. I’ve managed to make it turn blue when the internet is active, but I can’t find any option or trigger for the link-down state.

Probably helpful - [Solved] Changing WAN LED light to amber depending on network status.

Please create a new thread, this isn't really device specific.

Hey folks, does anybody else already tried the encoded firmware image to be accepted by the webgui localupdate ?

I`ve installed via UART and its working amazing, this device is unmatched in price/performance in my region, it would be very nice to have a working method without opening/soldering.

sadly i dont have in my posession my unit anymore.

1 Like

Hi guys! Version 24.10.5 has been released. Any chance we have this stable version available for W6x? In time, snapshot are working fine. Just for the reason of maintaining a more stable version and needing fewer updates.

The PR for 24.10 has been open for a few months with no movement.

25.12 will be out soon (after a few release candidates), and this device will be included in that release. When release candidates drop, please test this device on it if possible.

If being impatient, you can try 25.12-SNAPSHOT here.

2 Likes

Thanks @who_what8. I'll wait for at least the 25.12.0-RC1 build. In time, will I be able to update to it directly from the snapshot (I'm currently on r32346-70a4da1ceb) while maintaining my settings, or will it be necessary to reset to defaults?

Summary

Guys, I played a little with Gemini to make a script that better controlled the LED, emulating the stock firmware (I configured turquoise for wan on and red for wan off), led always on, only changes color. It runs independently of Luci's LED configuration. What I did was create a file /etc/hotplug.d/iface/99-rgb-led with the following code:

#!/bin/sh

(
LED_PATH="/sys/class/leds/rgb:status"
IFACE_NAME="wan"

COLOR_TURQUOISE="75 0 130"

COLOR_RED="0 255 0"

BRIGHTNESS="100"

set_led() {
    local color="$1"
    if [ -d "$LED_PATH" ]; then
        echo default-on > "$LED_PATH/trigger"
        echo "$BRIGHTNESS" > "$LED_PATH/brightness"
        echo "$color" > "$LED_PATH/multi_intensity"
    fi
}

if [ "$INTERFACE" = "$IFACE_NAME" ]; then
    sleep 2

    case "$ACTION" in
        ifup)
            set_led "$COLOR_TURQUOISE"
            ;;
        ifdown)
            set_led "$COLOR_RED"
            ;;
    esac
fi

) &

After creating the script, assign permission:
chmod +x /etc/hotplug.d/iface/99-rgb-led

To test, type the two commands below to simulate wan unavailability:
ifdown wan
ifup wan

Sorry for any errors in communication, I have a more enthusiastic than technical profile.

I do not believe you need to reset to default going from SNAPSHOT to 25.12. However, your mileage may vary.

I have seen some weird behavior with keeping settings across builds. I usually back up settings, flash with defaults, install packages, then restore.

1 Like