"Zero Click" Remote Code Execution in Mycroft AI vocal assistant


#1

Just run into this;

A whole lot worse than MS taking over github! What are your plans? Assume adding user/passwd is a quick fix.


#2

I seen this on /r/netsec. It works… I was able to push a shell in just a few minutes.


#3

That is correct, running what we call a “GitHub install” has been considered developer mode and currently is focused on functionality. This exploit does not apply to the “consumer ready” Mark 1 (or the future Mark 2).

However it is important that we keep in mind that we are rapidly approaching a fully consumer-facing product. I do appreciate Nhoya’s work here and the respectful way he approached me with this concern. For now, the start-mycroft.sh launch mechanism displays a caution that reminds developers of the potential for mischief and suggests using appropriate firewall rules to minimize risk. See: https://github.com/MycroftAI/mycroft-core/pull/1633

We do have plans for both moving this to a WebSocket Secure (WSS) implementation with authentication to connect. I don’t have a specific date yet, but I believe the current risk is minimal with simple precautions by current developers.


#4

Hi :slight_smile: I’m the guy of the disclosure, as @steve.penrod pointed out (and as I wrote in the Notes section of my writeup) this is currently not affecting the Mark-I device since the websocket is behind a firewall just remember that if for any case you have to open it, you will incur in this issue Of course this is just a temporary mitigation (e.g. if you want to use the app you need at least to allow for one connection from the IP of your phone or your entire local network but you will be still exposed)


#5

if you don’t need to connect from the outside at all (most cases) just change the websocket address in config from 0.0.0.0 to 127.0.0.1


#6

Going forward I also want to merge Home Assistant together with MyCroft. With the HA Mycroft skill we can use voice to control HA. However with the Home Assistant Mycroft addon, we can use Mycroft as notify platform for any state changes in HA.

For that to work, we need ofcourse to have the websocket open to 0.0.0.0 instead of 127.0.0.1. This open a door for malicious code execution. Now, my mycroft instance and Home Assistent instance are both behind a proper firewall, but still… No websocket should be open without credentials. To me it just sounds like amateuristic beginners mistake, which does not rime with Mycroft as the business it is now. (no offense).


#7

I know that @btotharye has done an enormous amount of work with the Home Assistant Skill for Mycroft, and I’d like to just flag this with him so that he’s aware of this conversation - as he may have some thoughts.


#8

Thanks @KathyReid!

For current testing; Running Mycroft on my laptop and a Home Assistant install on a small desktop PC (headless debian server). The Home Assistant skill within Mycroft works perfectly, other then with the latest change/commit of using the default port if the port config has been left empty breaks reverse-proxy support. But by the time I get in the final stages I will contact @btotharye again myself for a fix. (just removed the whole port in my local code from the url string)

However, MyCroft -> HA is not the issue here. I was more talking about the other way around; HA -> Mycroft.

Checkout this component;

And a (very) quick demo of it in action (not mine);

Through Home Assistant (and possibly other systems that run in the same network), the vulnerability is open for attack this way. All it needs for configuration is the IP address of Mycroft. Adding a user/passwd and encryption to this is not a big deal. And should be implemented rather sooner than later is you ask me.

However, I personally would like to vote for making a classification attached to the skill. ONLY system/service skill should be allowed to run code or other skill. Notification type of skill should only be allowed to have Mycroft speak something outload, nothin more, nothin less. (If i make any sense as dutchie writing english)

As addition to above, to what I want to do in the long(er) run. I would like to configure Home Assistent with proper presence detection. During the day that I am not at home, but HA has certain state changes that I would like to know of as soon as I walk in the room, I would like MyCroft to save all the notifications and let HA initiate playback of them all as soon as my presence is triggered. (Most likely changing / alternating @forslund his events skill)


#9

I do have plans to add more updates very shortly to the HA mycroft skill. I also have always used my own external means to secure this system as I brought up in the general chat about this.

Most of us developers have already been aware of this and have our own ways of securing things. I have historically used nginx or https://jwt.io/ which I think in this case might be the best option.

If no one has already started on this I don’t mind crafting up a PR with some of the code I already have.

As for your last part with the HA presence I believe this will require some work in mycroft as I don’t think it has a way of saving things like this. The original reason I setup this component in HA (I built it) was initially to get my notifications and such from HA onto my Mark 1 device, I am planning to add a lot more functionality to it as well.

Let me know if you have any specific questions or ask for anything related to HA as I have created both options here to connect Mycroft to Home Assistant and vice versa.

Thanks


#10

Great to hear, and indeed let’s open the discussion about it. By all means, initiate the PR then we can move the more technical discussion over to Github.

I’m running my HA also behind a nginx reverse proxy. I have reverse nat translation, so using the “external” https weburl from within the Mycroft skill does get translated to the internal IP. For ease of configuration I doing it like this for most of my stuff. You must be aware that a reverse proxied addres does not allow the port number to be set. (at least not in my setup)

Works: https://hass.mydomain.com
Doesn’t work: https://hass.mydomain.com:80 (or 443)

Didn’t realise you @btotharye also made the HA addon. Thank you very much for that. Much appreciated.

To comment on your statement about saving things. Indeed MyCroft needs some work or skill, but I believe by utilizing @forslund his event skill;

This could easily been done. Sending “events” to that skill marked as “to be saved” adjusting the config of it. Then we can start with an utterance such as: Hey Mycroft, what did I miss when I was away" which will trigger the events to be spoken and deleted. Step two, would then be to trigger that same utterance remotely from HA as soon as a certain presence is triggered.

Anyhow, will type out what I am trying to do more over the next few days. Started doing that already on a Dutch technical forum;
https://gathering.tweakers.net/forum/list_messages/1852711

Google translate could probably help out understanding most of it.

Secondly, I made more people aware of MyCroft by creating (yet to be updated again) this global thread about MyCroft on the same website;
https://gathering.tweakers.net/forum/list_messages/1852743

I guess we will be speaking more often to each other in the near future @btotharye :wink:


#11

Holy crap! @btotharye you “ARE” geeked-out-solutions! :smiley:


#12

Glad that my old event skill still finds uses :slight_smile:

I think some rework will be needed due to the way intents are registered nowadays. The good thing is that the skill id is somewhat static and easy to get hold of now (before it was a hash).


#13

So if I refactored the current mycroft ha skill to accept a url without a port that should fix the skill for those using a reverse proxy or that don’t use a port right?

And yes I own www.geekedoutsolutions.com :slight_smile:


#14

@btotharye what I did for now, just testing purposes I chenged;

to

self.url = “https://%s” % (host)

However, if we would like to it properly we need to either change the logic on lines; 15 - 17 to allow for “portnum is None” or perhaps, a checkbox next to the SSL one, marking “Behind reverse proxy” is a cleaner solution. Leave that up to you.