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.

1 Like

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

* 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.

1 Like

There's a wiki page for this device.