-
Notifications
You must be signed in to change notification settings - Fork 11
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
Question - around serial port output #6
Comments
There is nothing useful on the serial port at all. Just the boot message and attached device be it feeder or door etc. |
Is it possible to subscribe to a topic in AWS and get the messages from there (once you have the cert) and avoid the MITM? Are the messages on the MQTT topic in AWS still encrypted, or are they decrypted prior to MQTT transmission? Would this mean that the cert might change whenever the hub did a f/w upgrade? |
The only config you need for MQTT is: That documents the process the hub takes to connect to the local instance. The two main components you need are the Python flask web server to query the official surepet service to get the credentials, alter them then return the credentials file to the hub, and then the MQTT endpoint. Then you have a straight feed of unencrypted MQTT messages on the mqtt topic of your choice. If you have the certificate password by doing the firmware update and getting the password then you can generate your own so you don't even need to connect to the surepet backend to get the credentials file for the first time. But doing the firmware update requires downloading the xor hashed firmware specific for your hub from official surepet service and then caching it locally which the python flask web server also does. |
Sorry been a while since I looked at this. Just trying to understand some of your code. This bit.. I already have MQTT, Node-red, Home assistant, and all my 'logic' in node-red. So I am thinking I might be able to do something with existing components - I am only interested in the in/out messages from the flap (and only have 1 cat) so building some message decode logic in node-red seems like it might be pretty simple. Thanks for you help. |
The http endpoint is hard coded in the hub to be hub.api.surehub.io so you need to poison DNS as part of the setup anyway to get the hub to hit the webserver. So since I already know that DNS name is local I update the AWS MQTT to be the same endpoint. If you look through pethubpacket.py it has all the heavy lifting converting the MQTT messages into something human readable and you will need to look at the 126/127 in the parseframe and parsemultiframe functions and rewrite them. https://github.com/plambrechtsen/pethublocal/blob/main/docker/source/pethubpacket.py#L263 |
I also updated the hub documentation with the debug console commands... but there isn't really much useful to get the certificate password out in there just a bit of debug info's. https://github.com/plambrechtsen/pethublocal/tree/main/docs/Hub |
I have edited some of the personal values here - not sure how sensitive some of this is I think I have made some progress on my goal - but not there. I can't get your web docker image to work for some reason (I am just starting the web container - not everything). It seems to be doing a GET for firmware which seems not to be what is expected from your doc. Get this output: XXX The above however did give me the JSON for the /api/credentials POST, which I have done in a post tool (actually node-red with some javascript) and I get the below output. Can I get the various certs and keys I need from this? The block of data in position (: delimited) 8 seems to be cert files, but I am not sure of the format or what is here and how many??
I have chopped some chunks out of the cert bits above - but it seems to have 6 different blocks that start MII. Do you know how to extract usable certificates from this? |
So it seems my firmware download method has been broken by surepet backend changes and I will try and fix that in the next few days. But the certificate is a PKCS12, it's not multiple different files it is a single payload. You need the password to open the certificate up as it is encrypted with a 32 character / 16 byte string which is the "long_serial" that is stored in the hubs protected flash and is unique per hub. The only way to get the password is to hook up the serial console and do the firmware update process as documented here: https://github.com/plambrechtsen/pethublocal/blob/main/docker/source/fwlogtopw.py You could probably try and brute force it, but it would take years with JTR or similar tools. I have also documented the fields for the credentials file here under credentials, the second field in your above post is your hubs serial number:
But I do highly recommend spending the time to get the certificate password out, all it takes is a bit of soldering and a TTL serial adapter but once it is done you are set to MITM or do whatever you need and who knows if surepet change their backend in the future preventing it. |
Added a stand alone firmware downloader, just takes a command line argument of your serial number: |
more progress. I now have the password from the hub. Still trying to extract the certificate. I have the raw data from the web response, and the password (from the fw upgrade). How do I get the certs. I am trying openssl: I will keep trying different options - but thought i would ask in parallel. Thanks for the help again. |
This should help with the PolarProxy stack. https://github.com/plambrechtsen/pethublocal/blob/main/PolarProxy/gomqtt.sh
|
You can always email me directly if you have some messages you don't want to post publicly as they contain personal information. As I think this case has been covered let me know if there is more help you want otherwise I will just close this ticket. |
I have this nearly working :) It did work briefly. I naively thought that the hub getting the cert might be a one time thing - not a new cert every time it boots :( I am trying to setup mitmproxy (which I use elsewhere) to grab the cert data when the hub boots. I am having issues with the certs for this - I assume that the hub validates the hub.api.sureflap.io cert when it boots?? how did you workaround this in your flask webserver? |
The |
I have loaded the hub.pem and hub.key into mitmproxy but the hub does not seem to like this, fails with a message ‘The client may not trust the proxy's certificate’ – you obviously did not have these issues? I assume those are the certs you are referring to?
From: Peter Lambrechtsen ***@***.***>
Sent: Monday, 2 August 2021 1:16 PM
To: plambrechtsen/pethublocal ***@***.***>
Cc: Chris Henderson ***@***.***>; Author ***@***.***>
Subject: Re: [plambrechtsen/pethublocal] Question - around serial port output (#6)
The hub.api returns the same cert each time the hub boots... or it seems to from my experience and it sometimes gets rolled but the AWS IOT Client Cert is good until 2040 but surepet seem to re-issue it periodically.
Check out the script I created for PolarProxy as that should be easy to alter to download the creds first, but re-using the same cert works fine.
I have created a self signed certificate for hub.api which the hub happily accepts (thankfully, otherwise none of this project would work) and then cache the creds file locally so each subsequent boot from the hub to flask I return the locally cached version as we don't need it afterwards.
Flask doesn't make the backend call back to the real hub.api each time as we don't need to do it more than once, but just returned the cached and modified version copy of the full creds file if it exists locally.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#6 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ASRHCNWTONGTOSGQ375JI23T2XWUVANCNFSM45QT4QKA>.
|
I would stick with PolarProxy rather than mitmproxy, as I had all sorts of problems getting mitmproxy to work correctly as the http headers needed to be returned in the correct order for the hub to accept it. The content-length header needed to be returned last.
That will nicely spit out decrypted pcap files you can easily load into wireshark, or you can even pipe the output somewhere else. |
Maybe I have got myself confused – tried so many things over the last week or so.
What I am trying to use mitmproxy for is to proxy the HTTP (and HTTPS) traffic as the hub boots. But maybe this is a rabbit hole I don’t need to worry about – I started doing this in thinking that the cert is reissued every time.
On the MQTT side I am trying to have the hub connect to my MQTT (mosquito) instance, then that bridge (both ways) to the AWS MQTT. SO desired end state is my broker in the middle just bridging to AWS, so app etc still works but I can pull the messages I am interested in from my broker.
The issue I am stuck on at the moment seems to be getting the hub to connect to my local MQTT – what cert do I need for this? I had this working but can’t seem to get it working again.
I think the way I had it working was to:
I used node red to post an HTTPS request to /api/credential – then decoded the returned cert using the hub password from the serial port firmware upgrade. I am pretty sure this worked – but then I am not sure as this response was never passed back to the hub, so the hub never had this certificate??? I CAN use this cert in MQTT explorer and can connect to AWS and see the messages.
Thanks again for all the help.
If the certs don’t renew on reboot then maybe I don’t need to worry about the HTTP bits – I can just let the hub connect to the web on a reboot. (accepting the risk that it does a firmware upgrade and everything works).
From: Peter Lambrechtsen ***@***.***>
Sent: Monday, 2 August 2021 1:39 PM
To: plambrechtsen/pethublocal ***@***.***>
Cc: Chris Henderson ***@***.***>; Author ***@***.***>
Subject: Re: [plambrechtsen/pethublocal] Question - around serial port output (#6)
I would stick with PolarProxy rather than mitmproxy, as I had all sorts of problems getting mitmproxy to work correctly as the http headers needed to be returned in the correct order for the hub to accept it. The content-length header needed to be returned last.
Are you trying to MITM the hub.api https traffic or the AWS MQTT traffic? As the AWS traffic is really what you care about and if you look in the gomqtt.sh script.
https://github.com/plambrechtsen/pethublocal/blob/main/PolarProxy/gomqtt.sh
And then alter it as needed, and check the last line in the script where it calls PolarProxy:
./PolarProxy -v -p 8883,1883 --autoflush 10 -o mqtt --insecure --clientcert a5kzy4c0c0226-ats.iot.us-east-1.amazonaws.com:$serialnumber.p12:$certpassword --servercert a5kzy4c0c0226-ats.iot.us-east-1.amazonaws.com:iot.p12:password --nosni a5kzy4c0c0226-ats.iot.us-east-1.amazonaws.com
That will nicely spit out decrypted pcap files you can easily load into wireshark, or you can even pipe the output somewhere else.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#6 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ASRHCNXQ2UXFYB4UWJOZHJDT2XZMJANCNFSM45QT4QKA>.
|
To get mosquitto running as a MQTT Broker that the hub can connect to you can either use my docker stack or just this snip from the config plus the associated certs in that folder is what you need. |
Not sure what I am doing wrong here. I have tried to simplify as much as possible.
I have the hub – nothing in the way for HTTP – so it is just going to the Internet.
I have the a5kzy4c0c0226-ats.iot.us-east-1.amazonaws.com URL DNS pointing to my local MQTT.
Simple MQTT config exactly as referenced below.
I have tried with the certs from your docker/web directory on Github – but then realised that you are updating the MQTT endpoint URL in your flask proxy, so I have generated a local self-signed hub.pem and hub.key for a5kzy4c0c0226-ats.iot.us-east-1.amazonaws.com. (where does the aws.pem fit in here?).
Have I misunderstood something? What is the cert passed back in the /api/credentials call used for – is this just for connecting to the AWS MQTT instance?
Error in mosquito logs is:
mosquitto | 2021-08-02T03:51:14: New connection from 172.21.96.103:3166 on port 8883.
mosquitto | 2021-08-02T03:51:14: OpenSSL Error[0]: error:140370E5:SSL routines:ACCEPT_SR_KEY_EXCH:ssl handshake failure
mosquitto | 2021-08-02T03:51:14: Client <unknown> disconnected: Protocol error.
:q!
From: Peter Lambrechtsen ***@***.***>
Sent: Monday, 2 August 2021 3:11 PM
To: plambrechtsen/pethublocal ***@***.***>
Cc: Chris Henderson ***@***.***>; Author ***@***.***>
Subject: Re: [plambrechtsen/pethublocal] Question - around serial port output (#6)
To get mosquitto running as a MQTT Broker that the hub can connect to you can either use my docker stack or just this snip from the config plus the associated certs in that folder is what you need.
https://github.com/plambrechtsen/pethublocal/blob/main/docker/mqtt/default/mosquitto.conf#L22-L28
Needs to be listening on port 8883, and the aws.pem is the public key of the AWS IOT CA, then the hub.pem/key are just self signed certs.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#6 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ASRHCNW55MM3FBKIABDSENDT2YED5ANCNFSM45QT4QKA>.
|
The aws.pem is the public key of the AWS IOT MQTT CA since the hub uses a client certificate which is the PKCS12 certificate passed in credentials to connect to AWS. I assume you're using mosquito MQTT broker? https://github.com/plambrechtsen/pethublocal/blob/main/docker/mqtt/default/mosquitto.conf#L26 Which points to the aws.pem which you can't change. There is the iot.pem/key in the same folder which should work if you're using the AWS endpoint rather than the hub.pem/key. Feel free to email me directly |
Not sure if you got the last mail – not sure which of these reply addresses gets to you.
Repeat below if you did not get it.
Does one of these email addresses reach you without posting back to the issue?
I still can’t see what is not working here. Not sure I can simplify the config any more.
I have got mosquito installed and running in docker – this is my main instance that has lots of stuff running through it. The only change I have made to the default config is to allow anonymous connections. I have added an extra config file in the configured directory (include_dir /mosquitto/config/extra_config/) with the following:
listener 8883
protocol mqtt
#require_certificate true
cafile /mosquitto/config/certs/aws.pem
certfile /mosquitto/config/certs/iot.pem
keyfile /mosquitto/config/certs/iot.key
log_type all
The certs are directly from your Github site from the docker/mqtt/default folder. I have tried both the iot.* and hub.* versions.
For DNS I have a Cisco router that is running Split DNS and for the hub IP it is returning my MQTT local IP for the a5kzy4c0c0226-ats.iot.us-east-1.amazonaws.com url.
Same error as before:
mosquitto | 2021-08-02T03:51:14: New connection from 172.21.96.103:3166 on port 8883.
mosquitto | 2021-08-02T03:51:14: OpenSSL Error[0]: error:140370E5:SSL routines:ACCEPT_SR_KEY_EXCH:ssl handshake failure
mosquitto | 2021-08-02T03:51:14: Client <unknown> disconnected: Protocol error.
Interestingly the source port increases by 1 each failure.
Have I made this too simple? If the MQTT should accept a connection with a ‘generic’ certificate then why did I need to grab the hub private key from the serial/firmware upgrade process?
I have also tried starting up you full docker stack (pethub fails as I have not created a db – but I assume this is not an issue early in the process). Here an even more generic error:
mqtt | 1627881774: New connection from 172.21.96.103 on port 8883.
mqtt | 1627881774: Socket error on client <unknown>, disconnecting.
From: Peter Lambrechtsen ***@***.***>
Reply to: plambrechtsen/pethublocal ***@***.***>
Date: Monday, 2 August 2021 at 4:24 PM
To: plambrechtsen/pethublocal ***@***.***>
Cc: Chris Henderson ***@***.***>, Author ***@***.***>
Subject: Re: [plambrechtsen/pethublocal] Question - around serial port output (#6)
The aws.pem is the public key of the AWS IOT MQTT CA since the hub uses a client certificate which is the PKCS12 certificate passed in credentials to connect to AWS. I assume you're using mosquito MQTT broker?
The broker needs to present a MTLS Client Certificate challenge as per
https://github.com/plambrechtsen/pethublocal/blob/main/docker/mqtt/default/mosquitto.conf#L26
Which points to the aws.pem which you can't change.
There is the iot.pem/key in the same folder which should work if you're using the AWS endpoint rather than the hub.pem/key.
Feel free to email me directly
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#6 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ASRHCNR3T5VSNK63JI2BQ4TT2YMXDANCNFSM45QT4QKA>.
|
were you able to have any thoughts on my issue above. It seems pretty simple that the hub could connect to an internal MQTT broker with just the generic server certs that you have on this site. Not sure where I am going wrong. |
Not sure... it seems very odd since other folks have managed to get it working. I would suspect it is something network related, what is the main host OS you are running, and I assume that you have sorted out the DNS spoofing? Send me an email and I might be able to help diagnose what is going on. |
Does the serial port output anything useful (i.e. can you determine cat going in and out) in normal operations?
I am thinking a possible solution to avoid MITM and hang an ESP32 (or similar) running some custom code off the serial port output.
I am not really bothered about controlling the flap outside the supplied app - just the ability to get cat movements locally without polling unsupported API or delay issues.
The text was updated successfully, but these errors were encountered: