Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QSW-2104-2T #1

Open
mdsitton opened this issue Jul 5, 2023 · 20 comments
Open

QSW-2104-2T #1

mdsitton opened this issue Jul 5, 2023 · 20 comments

Comments

@mdsitton
Copy link
Contributor

mdsitton commented Jul 5, 2023

I just ordered the very similar switch the QNAP QSW-2104-2T I'd like to look into how different these switches are since the main difference externally is swapping the sfp+ ports for dual rj-45 10g ports.

Do you have any information on how you modified the firmware image to disable the web interface timeout? So that this change can be applied to other switches?

Thanks!

@danieltwagner
Copy link
Owner

The first step will be to create a dump of the flash chip. I did that using a CH341A + SOIC clip and would recommend the same for you. That way you can always go back to stock no matter what happens. If you don’t mind uploading that dump here we can keep them here in the same place for others to find and see how the firmware differs.

The way I modified it is by going through it in Ghidra, which was somewhat painful. Knowing what we’re looking for will likely make things easier the second time around. I’d be happy to lend a hand.

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 7, 2023

Yeah for sure, I ordered a CH341A which should arrive in the next day or two. I've messed around with Ghidra a bit before but it's been a while.

QSW-2104-2T-A-front
QSW-2104-2T-A-back

Here is a couple of images of the board for the switch.

One thing i wouldn't mind attempting to do is making switch configuration a bit more accessible. Either through an external application utilizing the webapi or if there is a route forward with additional firmware modification.

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 7, 2023

winbond-rot

Also a closer image of the flash chip just to show that it is the same one as the others.

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 7, 2023

But as for going though the dump with Ghidra i'm certainly down to give it a shot. I've poked around with Ghidra before but never got super deep into it.

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 8, 2023

I've started experimenting with your flash image for now I've found this which has some helpful tips but I'm going to assume a lot of the memory mapping addresses required are going to be different going based on the info you have in the readme.

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 8, 2023

Also looking over your flash.bin so far:

I believe the actual bootloader start bytes are: F8 FF 00 20 and there seems to always be AA AA AA AA bytes at the end

Which lines up very nicely with what is already known from the output of the bootloader.

bootloader:
10000 - 52300

image 1:
60000 - 34AECC

image 2:
3A0000 - 68AECC

Then there also appears to be a few FAT file system images in the flash.bin as well.

@danieltwagner
Copy link
Owner

danieltwagner commented Jul 8, 2023

Yeah so my interpretation is that there are 3 "images", two bootable and a third one that contains a FAT12 (?) filesystem. It's been a little while since I looked at it but it took a healthy amount of digging around. I didn't dig too much into the filesystem but you could definitely amend the admin page; you can also do that during runtime by saving new content there without having to re-flash, which might help with iteration.

How to find the memory location to disable the login timer:

If you extract an image of your choice (say 0x60000) and in Ghidra use 0x10010000 as start position then that should get you going (load it as ARM Cortex 32 Thumb little endian). Make sure that memory isn't marked as writeable, so that Ghidra can simplify some of the decompiled code for you. Searching for strings has proven to be useful to get your bearings as several will include function names for (inactive) debug logging.

To keep the management API active for longer, I searched for the string I saw on UART: can_login_sec= and found that at 0x1011b584. References to that were in turn in the function at 0x1001149c which I named handle_login() so I could easily find it again. In that print statement it reads the remaining time from a memory location 0x208022ec. 0x20800000 is where RAM is mapped, so that makes sense. We can then label that memory location so we can find it again. Next we find references to that memory address and will find some kind of timer that decrements it as well as the function api_system_logintime_set() (again my name) where it is set when calling the /api/system/logintime/set API.

I didn't find any other location where this was written to, so then went spelunking for some init routine.

After a bunch of searching I found a function at 0x100102c8 that seems to be initializing memory between 0x20800000 and 0x208033d8 with data starting at 0x102f7d7c. Once you add this mapping to the memory map (byte map 1:1 from 0x102f7d7c to 0x20800000, length 0x33d8) you'll see a value show up at the memory location we saved before and can make that significantly larger, like 10 years. I think it's a 32 bit value of seconds so there's plenty of room.

You could in theory also modify it to not decrement but I found that to be more invasive and brittle. It might also conceivably have some side-effects where something else could be driven by that timer and so making the timeout extremely long seemed like the easiest way forward

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 8, 2023

Alright i've dumped the flash and made a pull request for that to be included in the repo

@mdsitton
Copy link
Contributor Author

Also finally got in my ttl serial adapter, so here is the bootup log just for reference:

BCM53158 SWITCH firmware Feb 22 2018
boot_src = M7. Initializing M7


Copyright 2015-2017 Broadcom Limited
         All rights reserved

Unit 0: ChipID: 53161 Rev 17
Unit 0: Straps: 00005041
Unit 0: PLL1 CH1 POSTDIV 13
LED Boot up -> 0s-3s
Unit 0: LED Refresh cycle config
Unit 0: LED Delay config
Unit 0: LED Strap load
Loading LED Firmware
.......
Unit 0: bootloader LED Start
Buffered Logs:
OTP_FLAGS = 0x8c


Broadcom ROBO OS Bootloader Version 2.4

Bootloader: QSPI flash Model: winbond Size: 128 Mbit

DEVFS: Initializing..
DEVFS: Device /dev/ttyS0 registered
DEVFS: Device /dev/flash0 registered
Press any key to interrupt Auto Boot
Autoboot starting...
Bootloader: Loading image at 1
Bootloader: Image Version SW-UT2206QU_1.00-0.05
Watchdog timeout value is 1250000000 (4a817c80)


Copyright 2015-2017 Broadcom Limited
         All rights reserved

ChipId: BCM53161 RevId: 17 
Version Regs: 
Software: ROBO_OS_REL_1_4_8 Build: Mon Nov 8 10:14:13 2021
MPU enabled
Unit 0: ChipID: 53161 Rev 17
Unit 0: Straps: 00005041
Unit 0: PLL1 CH1 POSTDIV 10
LED Boot up -> 3s-6s
Unit 0: LED Start
Buffered Logs:
OTP_FLAGS = 0x8c


Watchdog Setup with timeout 1250000000 (4a817c80)
Reading Primary Avenger OTP...
Starting Dynamic AVS Using ROs on Primary Avenger...
Applying Saved Core Voltage:9939 with saved DAC Code: 673.
dwl......avs.c:AvsSetDac=673, cur_dac=673 delta=0 
........avs.c:SetPVTctrl setting AVS_PVT_MNTR_CONFIG_PVT_MNTR_CTRL from 0x80 to 0x180 
SetAvsVoltage - Final Result: 1
Core Voltage After applying saved AVS results on Primary Avenger: 9921
cbxi_slictcam_init()
QSPI FLASH MPU region re-sized to 16 MB
sal_fs_init_all:114 File system initialized
sal_fs_init_all:122 File system obtained from TOC
sal_fs_init_all:128 File system initialized
cbxi_lin_init()
cbxi_encap_init()
cbx_port_init()
Unit 0 Mac init Ports: 8 9 10 11 12 13 14 15 
cbx_lag_init()
cbx_port_create()
Unit 0: PBMP_ALL(unit)=ff00
cbxi_trap_init()
cbxi_stg_init()
cbxi_vlan_init()
cbxi_l2_init()
cbxi_mcast_init()
cbx_mirror_init()
cbx_meter_init()
cbx_cosq_init()
cbx_stat_init()
cbx_cfp_init()
cbx_auth_init()
cbx_link_scan_init()
cbx_link_scan_enable_set()
cbx_pktio_init()
LWIP successfully initialized
LBD enabled 
QOS disabled 
port 8, pri=0, dp=0 
port 9, pri=1, dp=0 
port 10, pri=2, dp=0 
port 11, pri=3, dp=0 
port 12, pri=4, dp=0 
port 13, pri=5, dp=0 
extPhyIdentify: fport=8, phyaddr=1. id0=0x1c, id1=0xc848, type=3 ! 
rtlPhyInit: phyaddr=1 ! 
phyaddr=1, serdes = 0
extPhyIdentify: fport=9, phyaddr=2. id0=0x1c, id1=0xc848, type=3 ! 
rtlPhyInit: phyaddr=2 ! 
phyaddr=2, serdes = 0
extPhyIdentify: fport=10, phyaddr=3. id0=0x1c, id1=0xc848, type=3 ! 
rtlPhyInit: phyaddr=3 ! 
phyaddr=3, serdes = 0
extPhyIdentify: fport=11, phyaddr=4. id0=0x1c, id1=0xc848, type=3 ! 
rtlPhyInit: phyaddr=4 ! 
phyaddr=4, serdes = 0
extPhyIdentify: fport=12, phyaddr=5. id0=0x3590, id1=0x5081, type=1 ! 
Broadcom Cli Starting....

BCMCLI> Configuration File Description: '1.4.8.0'
bcmPhyInit: PHY BCM_84891 phyaddr=5 completed! 
extPhyIdentify: fport=13, phyaddr=6. id0=0x3590, id1=0x5081, type=1 ! 
bcmPhyInit: PHY BCM_84891 phyaddr=6 completed! 
LED Normal
Setting IP address to : 1.1.1.100
Setting Network Mask to : 255.255.255.0
Setting Gateway IP to : 1.1.1.1
app_user_account_cfg_load:85 Failed to parse userCfg
app_host_cfg_load:64 Failed to load TRUSTHOST configuration
app_sntp_cfg_load:98 Failed to load SNTP configuration
Failed to load Loopback Detection config from 'cfg:/config.jsn'
Loaded default config for Loopback Detection from '/json/config.jsn'
cfg_json_get:426 Invalid parameters
Starting web server on port :80
uport = 0, fport=8, flow =0 
uport = 1, fport=9, flow =0 
uport = 2, fport=10, flow =0 
uport = 3, fport=11, flow =0 
uport = 4, fport=12, flow =0 
uport = 5, fport=13, flow =0 
stop ip/arp traffic ! 

And when interrupting boot:

BCM53158 SWITCH firmware Feb 22 2018
boot_src = M7. Initializing M7


Copyright 2015-2017 Broadcom Limited
         All rights reserved

Unit 0: ChipID: 53161 Rev 17
Unit 0: Straps: 00005041
Unit 0: PLL1 CH1 POSTDIV 13
LED Boot up -> 0s-3s
Unit 0: LED Refresh cycle config
Unit 0: LED Delay config
Unit 0: LED Strap load
Loading LED Firmware
.......
Unit 0: bootloader LED Start
Buffered Logs:
OTP_FLAGS = 0x8c


Broadcom ROBO OS Bootloader Version 2.4

Bootloader: QSPI flash Model: winbond Size: 128 Mbit

DEVFS: Initializing..
DEVFS: Device /dev/ttyS0 registered
DEVFS: Device /dev/flash0 registered
Press any key to interrupt Auto Boot
Bootloader: Auto boot Interrupted, Launching Cli
Broadcom Cli Starting....

BCMCLI> 

BCMCLI> help
config_get [<param>] (get all or given config)
config_set <param> <value> (set given config)
list (List all images)
getreg <register>
reboot (Reboot the system)
rz (receive a file via zmodem)
setreg <register> <value>
save (save boot config)

BCMCLI> 

@mdsitton
Copy link
Contributor Author

And the images available:

BCMCLI> list
+-----------------------------------------------------------------+
| Image | Offset   | Len      |       Version                     |
+-----------------------------------------------------------------+
|  1    | 10060000 | 3083628 | SW-UT2206QU_1.00-0.05 |
|  2    | 103a0000 | 3083628 | SW-UT2206QU_1.00-0.05  |
+-----------------------------------------------------------------+

@danieltwagner
Copy link
Owner

Sorry I was traveling and didn't have time to investigate this. Thanks for the flash dump.
Did you make progress in Ghidra?

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 16, 2023

Yeah a bit, though I've been digging into the bootloader quite a bit for whatever reason. I haven't gotten into the main os image yet. Originally i wanted to dip my feet into things a bit and wanted to figure out for myself more of how the boot process worked out. Then just getting an idea of what code is being used from the open source firmware and other components (such as FreeRTOS/OpenRTOS lwip and CMSIS)

image

And during all of this i've been looking over github for any potentially relevant code that seems to share some lineage with the firmware:
image

@mdsitton
Copy link
Contributor Author

Which through all of this i think there is certainly enough code out there that if someone wanted to spend the time on it, they could probably put together a totally custom bootloader and firmware. Most of the core code is there and seems identical in the final firmware.

I also did find a datasheet publicly that has been somewhat useful for the similar series of chips that the firmware code was originally written for:
https://media.digikey.com/pdf/Data%20Sheets/Avago%20PDFs/BCM53154,BCM53156,BCM53158.pdf

Comparing it with the unmanaged version of the chip that was found on the other thread they are very similar in most of the key areas so the stuff missing from this datasheet can mostly be pulled from the one above:
https://www.mouser.jp/datasheet/2/678/broadcom_limited_avgo-s-a0007199304-1-1683284.pdf

@danieltwagner
Copy link
Owner

Building from source would obviously be great!
I did also just come across the Edimax XGS-5008 firmware which appears to be a web managed switch based on the Broadcom Robo platform. I haven't really looked much into it yet but thought I'd mention it.

@mdsitton
Copy link
Contributor Author

Interesting, looking quickly at that firmware there's not really any shared strings that i can find between this and our switch firmware. So if they are similar it's heavily customized. I would actually be more curious to see a flash dump from the almost identical TRENDnet TEG-S762 switch https://www.trendnet.com/support/support-detail.asp?prod=115_TEG-S762

@mdsitton
Copy link
Contributor Author

mdsitton commented Jul 22, 2023

The main chips that the firmware ours runs on has references to are as follows:
BCM53112
BCM53154
BCM53156
BCM53157
BCM53158
BCM53161
BCM53162

@danieltwagner
Copy link
Owner

I also suspect that the TEG-S762 is virtually identical but it's worth pointing out that many of their switches in that same series are running comparatively beefy Realtek switches and full-blown Linux. Among those are the TEG-S350, TEG-S380, and TEG-S750. Obviously the TEG-S762 could still be a minor variant of the QSW-2104-2T and any differences in Firmware might be interesting.

Seeing as you're looking for more than just the ability to one-off configure that switch, did you try contacting QNAP and request GPL source? I've done this with Trendnet for the TEG-S750 and it's been almost 6 months now with no movement :/

@mdsitton
Copy link
Contributor Author

Well that's the thing i don't think there is actually any GPL licensed code on the device.

@sorphin
Copy link

sorphin commented Jan 16, 2024

An alternative to using a CH341 is if, like me you have a TL866II+ (or these days the T56) it can use the ICSP clip for 25 series chips (and the sw supports it). That's what i'll be using to rip/replace mine shortly. After I did my findings before (and posted on openwrt), kinda gave up and just used it as a switch. It was on a whim that I went back and came across all your findings. Good work. I guess I'm digging back in. lol

@mdsitton
Copy link
Contributor Author

mdsitton commented Jan 16, 2024

Nice! Yeah i was finally forced to use the switch for what i bought it for and haven't had the time to look into it more since. I'd like to give it another shot at some point though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants