Skip to content
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

Unable to ota_unlock using curl on Sonoff Basic R3 #45

Closed
mrcasablr opened this issue Sep 29, 2019 · 74 comments
Closed

Unable to ota_unlock using curl on Sonoff Basic R3 #45

mrcasablr opened this issue Sep 29, 2019 · 74 comments

Comments

@mrcasablr
Copy link

mrcasablr commented Sep 29, 2019

Upgraded firmware to 3.3.0 using eWelink app.

Added the DIY jumper. Created a sonoffDiy network hotspot on my mobile phone.

I can connect to the device and get details
http://192.168.43.24:8081/zeroconf/info -XPOST --data '{"deviceid":"100090f997","data":{} }'

I can also turn on/off the switch using curl and verify using curl again.

However, I cannot unlock using

http://192.168.43.24:8081/zeroconf/ota_unlock -XPOST --data '{"deviceid":"100090f997","data":{} }'

When the above command is sent, I do not get any response and it just hangs. I've tried this a few times. Re-running the /zeroconf/info still says device is locked (otaUnlock: false). I've tried powering on/off yet no luck.

This is stopping me from flashing the device with sonoff-basic.bin firmware and then to sonoff.bin.

Any help is appreciated! Does the device need internet access to unlock?

@mrcasablr mrcasablr changed the title Unable to ota_unlcok on sonoff basic r3 Unable to ota_unlock using curl on Sonoff Basic R3 Sep 29, 2019
@mrcasablr
Copy link
Author

I did a complete reset of the device and used the eWelink app to re-configure the device. I was able to flash the latest sonoff-basic firmware. It's all good now.

@jrbenito
Copy link

@mrcasablr

Could you please share more information how did you managed to get this work? I could flash one out of four Sonoff-mini with the exact same behavior you described, hanging forever in the OTA_unlock.

I tried to link them with eWelink app, all are with latest firmware, put jumper, issue info, OTA is locked, issue ota_unlock and it hangs forever.

Thanks

@ASL07
Copy link

ASL07 commented Apr 17, 2020

@jrbenito I have the same issue as you mention.
Did you find a solution?

@jrbenito
Copy link

@ASL07

Yes, the issue is Sonoff device needs to communicate with Itead cloud during unlock process. I bet that this is to avoid warranty of the device. So, when trying to OTA unlock in a confined SSID network, it fails without explanation. If your SSID (sonoffDIY) has access to the internet, no problem.

I built a docker image that uses a WiFi interface to bring up hotspot sonoffDIY, send OTA unlock and firmware to the device (through http requests) while sharing the internet in this Wifi hotspot. Made my life easy. If you want to check: https://github.com/jrbenito/SonoffDIY-tasmotizer

But any hotspot able to share internet (your android phone for instance) will do.

cheers

@ASL07
Copy link

ASL07 commented Apr 17, 2020

Thanks,
That looks great, I will have a look into it

@Nytish
Copy link

Nytish commented Jan 28, 2021

Upgraded firmware to 3.3.0 using eWelink app.

Added the DIY jumper. Created a sonoffDiy network hotspot on my mobile phone.

I can connect to the device and get details
http://192.168.43.24:8081/zeroconf/info -XPOST --data '{"deviceid":"100090f997","data":{} }'

I can also turn on/off the switch using curl and verify using curl again.

However, I cannot unlock using

http://192.168.43.24:8081/zeroconf/ota_unlock -XPOST --data '{"deviceid":"100090f997","data":{} }'

When the above command is sent, I do not get any response and it just hangs. I've tried this a few times. Re-running the /zeroconf/info still says device is locked (otaUnlock: false). I've tried powering on/off yet no luck.

This is stopping me from flashing the device with sonoff-basic.bin firmware and then to sonoff.bin.

Any help is appreciated! Does the device need internet access to unlock?

Kindly Help me how to control SONOFF switch using Curl request.
I m trying to execute below command but device is not responding.

curl -X POST -H 'Content-Type: application/json' -d '{ "deviceid": "1000c85310", "data": { "switch": "on" } }' -i http://192.168.0.155:8081/zeroconf/switch

@navennn
Copy link

navennn commented Dec 24, 2022

@ASL07

Yes, the issue is Sonoff device needs to communicate with Itead cloud during unlock process. I bet that this is to avoid warranty of the device. So, when trying to OTA unlock in a confined SSID network, it fails without explanation. If your SSID (sonoffDIY) has access to the internet, no problem.

Hi
I was searching for the answer too. Thanks for pointing out that it attempts to connect to internet!
I managed to trick this to work without internet though.

So... If anyone wants to give it a go, here's how you do it.

What you need to know beforehand;
It's important to mention that the device can only handle one connection at a time. If you attempt to connect and it is stuck, you will not be able to establish another session (it sends TCP RESET and closes the session immediately)

Check

curl --location --request POST 'http://192.168.100.81:8081/zeroconf/info' --header 'Content-Type: text/plain' --data-raw '{ "deviceid": "", "data": {}}' | python3 -m json.tool
{
    "seq": 6,
    "error": 0,
    "data": {
        "switch": "on",
        "startup": "off",
        "pulse": "off",
        "pulseWidth": 500,
        "ssid": "ssid",
        "otaUnlock": false,
        "fwVersion": "3.6.0",
        "deviceid": "120xx4aa732",
        "bssid": "4e:5e:c:12:1:11",
        "signalStrength": -52
    }
}

"otaUnlock": false, means its locked

You need to run this command to unlock the device:

curl -XPOST --header "Content-Type: application/json" --data-raw '{"deviceid": "", "data": {}}' http://192.168.100.81:8081/zeroconf/ota_unlock

But when you do it, the device attempts to connect to internet, to IP 52.57.118.192 (double check that when you actually go and do it, but it seems that it has hardcoded IP address and not DNS name).

You need to do two things:

  1. Spoof or NAT the 52.57.118.192 IP address to some webserver accessible in the subnet
  2. Spoof the webserver
    The endpoint must be
    http://52.57.118.192/api/device/otaFlash
    It must return this reply
    { "error": 422 }

Run apache server and create otaFlash.php file with content

<?php
echo '{
    "error": 422
}';
?>

use .htaccess for URL redirection;

/api/.htaccess 
# Turn on the rewrite engine
RewriteEngine  on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]

Now you can run the curl unlock again;

curl -XPOST --header "Content-Type: application/json" --data-raw '{"deviceid": "", "data": {}}' http://192.168.100.81:8081/zeroconf/ota_unlock
{"seq":8,"error":0}

error:0 is the proper response

Check to make sure it worked:

curl --location --request POST 'http://192.168.100.81:8081/zeroconf/info' --header 'Content-Type: text/plain' --data-raw '{ "deviceid": "", "data": {}}' | python3 -m json.tool
{
    "seq": 6,
    "error": 0,
    "data": {
        "switch": "on",
        "startup": "off",
        "pulse": "off",
        "pulseWidth": 500,
        "ssid": "ssid",
        "otaUnlock": true,
        "fwVersion": "3.6.0",
        "deviceid": "120xx4aa732",
        "bssid": "4e:5e:c:12:1:11",
        "signalStrength": -52
    }
}

If otaUnlock value is 'true', it worked.

If anyone is interested in further reading...

This is how apache server sees the request

192.168.100.81 - - [24/Dec/2022:23:32:39 +0100] "POST /api/device/otaFlash HTTP/1.1" 200 166 "-" "-"

data captured with pcap

POST /api/device/otaFlash HTTP/1.1
Host: api.coolkit.cn:8081
Content-Type: application/json
Authorization: Sign afec0945f48e14995d7449f6f0642e051b2eabac55a545fa2c4dc72987fb3177
Connection: close
Content-Length: 52

{"deviceid":"120xx4aa732","sequence":"9883232126123"}HTTP/1.1 200 OK

@pbassut
Copy link

pbassut commented Jun 14, 2023

@navennn Your solution worked for me, thanks!

I ran a reverse dns lookup and looks like the device requests this URL http://ec2-52-57-118-192.eu-central-1.compute.amazonaws.com/.
This was the one I had to spoof.

Although since my router didn't support spoofing that url directly, I placed that URL into my DNS server(I have one in my local network) to point to the where the server was. Then I was able to make the device download the firmware.

@carlosoboe
Copy link

@navennn Your solution worked for me, thanks!

I ran a reverse dns lookup and looks like the device requests this URL http://ec2-52-57-118-192.eu-central-1.compute.amazonaws.com/. This was the one I had to spoof.

Although since my router didn't support spoofing that url directly, I placed that URL into my DNS server(I have one in my local network) to point to the where the server was. Then I was able to make the device download the firmware.

Could you please help me, i'm a newbie and it's to hard for me

@navennn
Copy link

navennn commented Jul 18, 2023

@navennn Your solution worked for me, thanks!
I ran a reverse dns lookup and looks like the device requests this URL http://ec2-52-57-118-192.eu-central-1.compute.amazonaws.com/. This was the one I had to spoof.
Although since my router didn't support spoofing that url directly, I placed that URL into my DNS server(I have one in my local network) to point to the where the server was. Then I was able to make the device download the firmware.

Could you please help me, i'm a newbie and it's to hard for me

I'm afraid you won't be able to do it if you do not understand the steps I've provided. It's not easy if you don't know all those technologies.

I guess you just need to connect it to internet and let it do its thing.

@jackun
Copy link

jackun commented Nov 25, 2023

Spoof or NAT the 52.57.118.192 IP address to some webserver accessible in the subnet

EU Mini R2 v3.7.6 calls apid.coolkit.cn

@3N37
Copy link

3N37 commented Nov 28, 2023

@DasRed
Copy link

DasRed commented Dec 4, 2023

Here some additional information.
I have a Sonoff Mini. FW Version is 3.7.6
I found out, that the request for ota_unlock should go to http://apid.coolkit.cn:80/v2/d/otaflash METHOD post. The response should be '{"error": 422}'.
After this, the otaUnlock value is true.
If you have your own DNS in your network, just overwrite this domain with a running server and return the response. That's all ;)

@DasRed
Copy link

DasRed commented Dec 4, 2023

I added a small mock server for this problem for all

run like docker run -d --name sonoff-ota_unlock --restart unless-stopped -p 80:9082 dasred/sonoff-ota_unlock

Github: https://github.com/DasRed/sonoff-ota_unlock
Docker Hub: https://hub.docker.com/r/dasred/sonoff-ota_unlock

@dreeti
Copy link

dreeti commented Dec 4, 2023

@DasRed

Can you please help more in detail how to use your docker container to unlock a sonoff mini with firmware 3.7.6?
I have pulled the docker image and its running on my machine, the sonoff is in my local network - but now I am lost ... Thanks

@dreeti
Copy link

dreeti commented Dec 4, 2023

I'm making progress :-)

I got it right now http://apid.coolkit.cn:80/v2/d/otaflash is replied with '{"error": 422}'.
I test it simply by opening the url from a browser in my network.
( the docker container from @DasRed works well - thanks).

But jet the ota_unlock is still not working.
Now I am stuck - where can I look further.
This is the tcpdump from the sonoff when I run curl -X POST -d "{"data":{}}" http://192.168.1.23:8081/zeroconf/ota_unlock.

tcpdump: data link type PKTAP
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on pktap, link-type PKTAP (Apple DLT_PKTAP), snapshot length 524288 bytes

22:02:09.223732 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
22:02:15.209531 IP apid.coolkit.cn.56720 > #.sunproxyadmin: Flags [S], seq 2995609857, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 4115325840 ecr 0,sackOK,eol], length 0
22:02:15.257954 IP #.sunproxyadmin > apid.coolkit.cn.56720: Flags [S.], seq 659539, ack 2995609858, win 5840, options [mss 1460], length 0
22:02:15.258024 IP apid.coolkit.cn.56720 > #.sunproxyadmin: Flags [.], ack 1, win 65535, length 0
22:02:15.258130 IP apid.coolkit.cn.56720 > #.sunproxyadmin: Flags [P.], seq 1:181, ack 1, win 65535, length 180
22:02:15.322880 IP #.sunproxyadmin > apid.coolkit.cn.56720: Flags [.], ack 181, win 5660, length 0
22:02:39.348646 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
22:03:09.419888 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
22:03:15.323857 IP apid.coolkit.cn.56720 > #.sunproxyadmin: Flags [.], ack 1, win 65535, length 0
22:03:15.366796 IP #.sunproxyadmin > apid.coolkit.cn.56720: Flags [.], ack 181, win 5660, length 0
22:03:34.842550 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
22:03:37.892639 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
22:03:40.791924 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
22:03:44.968916 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
22:03:51.041161 IP # > mdns.mcast.net: igmp v2 report mdns.mcast.net
^C
15 packets captured
812 packets received by filter
0 packets dropped by kernel

Any further advice ?
Thanks.

@3N37
Copy link

3N37 commented Dec 4, 2023

@dreeti ,
once you have enabled the DIY mode of the sonoffmini R2 follow my guide I put above .
From the tcpdump it looks like you are not reaching the server on the lan.
curl -X POST -d "{"data":{}}" http://192.168.1.23:8081/zeroconf/info
what does it return?

@VeeGit09
Copy link

VeeGit09 commented Dec 4, 2023

@dreeti
Hi, I am at the same stage. I pulled the docker image and its running on the local machine. Can you tell more on how you got to the next step of getting the '{"error": 422}', while calling http://apid.coolkit.cn:80/v2/d/otaflash. Thanks

@dreeti
Copy link

dreeti commented Dec 5, 2023

@3N37
see here:
curl -X POST -d "{"data":{}}" http://192.168.1.23:8081/zeroconf/info

{"seq":6,"error":0,"data":{"switch":"off","startup":"off","pulse":"off","pulseWidth":500,"ssid":"MYSSID","otaUnlock":false,"fwVersion":"3.7.6","deviceid":"1000c3f10d","bssid":"78:44:76:e7:f4:14","signalStrength":-67}}%

@dreeti
Copy link

dreeti commented Dec 5, 2023

@VeeGit09
When your docker container is running on port 80 you can open a browser on that machine localhost:80 and the reply would be '{"error": 422}'
Next is then to tell your network: when the url apid.coolkit.cn is called to go to your local machine and not out in the internet to china.

I couldn't figure out how to do it on my router but I have a piHole and there I could setup a DNS entry apid.coolkit.cn -> 192.168.1.62 (the ip adress of the computer where the docker image is running). The piHole is my DNS server (configured in my router)
As a result now every browser requesting apid.coolkit.cn ends up on the docker image and gets '{"error": 422}'

@3N37
Copy link

3N37 commented Dec 5, 2023

@dreeti ,
have you checked that it actually makes a call to apid.coolkit.cn ; because this address can change and so can the subdirectory where the otaflash file resides. i'm attaching the sniffing with wireshark that i did to figure out what exact address the sonoff calls.
image

@dreeti
Copy link

dreeti commented Dec 5, 2023

@3N37
thanks. No I haven't - because my knowledge in this regard is limited :-)
Ok - let me educate myself about wireshark and see how far I get.
Thank you.

@dreeti
Copy link

dreeti commented Dec 5, 2023

@3N37
Screenshot 2023-12-05 at 15 14 18
It looks like the sonoff not connecting to anywhere. Am I right?

@dreeti
Copy link

dreeti commented Dec 5, 2023

@3N37
Thanks a lot !! It looks like I got it right.
My bad - after getting it right installing wireshark it didn't start my docker image with the webserver.
So starting the webserver made a difference :-)
As you can see it still wants the /v2/d/otaflash
Screenshot 2023-12-05 at 15 54 57

curl -X POST -d "{"data":{}}" http://192.168.1.23:8081/zeroconf/info
{"seq":3,"error":0,"data":{"switch":"off","startup":"off","pulse":"off","pulseWidth":500,"ssid":"totolink","otaUnlock":true,"fwVersion":"3.7.6","deviceid":"1000c3f10d","bssid":"78:44:76:e7:f4:14","signalStrength":-67}}%

Looks like I can flash tasmota.

Yet I don't know what I might have done wrong yesterday - after installing wireshark and looking into the trafic it worked. No matter I learned quite a lot.
Thanks to all

@DasRed Thanks for the image

@3N37
Copy link

3N37 commented Dec 5, 2023

@dreeti

  • ok i'm glad you succeeded ,
  • to listen properly with wireshark you have to place yourself between the router and the device you want to sniff(sonoff), on the mikrotik and similar router there is just a special function for that.
  • after unlocking and before flashing you can also make a copy of the original firmware 3.7.6 so you can restore the sonoff as originally( over TTL device https://www.superhouse.tv/33-sonoff-mini-and-s55/ esptool.py --port COMx read_flash 0x00000 0x100000 sonoff376.bin )

@VeeGit09
Copy link

VeeGit09 commented Dec 17, 2023

@dreeti

Thank you for the details. Finally I was able to unlock after learning a lot on running a docker in WSL2 and mapping the IP to pi hole. When I run curl -X POST -d "{"data":{}}" http://192.168.1.xx:8081/zeroconf/info i get the following
{
"seq": 2,
"error": 0,
"data": {
"switch": "off",
"startup": "off",
"pulse": "off",
"pulseWidth": 500,
"ssid": "xxxxxxx",
"otaUnlock": true,
"fwVersion": "3.7.6",
"deviceid": "xxxxxxxxxxxxx",
"bssid": "xxxxxxxxxx",
"signalStrength": -54
}
}

@3N37 and @dreeti Now I am stuck on how to flash with Tasmota. I followed the instructions in the pdf by @3N37 and used the curl http://10.0.0.118:8081/zeroconf/ota_flash -XPOST --data '{"data":{"downloadUrl":
"http://10.0.0.108/tasmota-lite.bin", "sha256sum":
"123a378c9da7f2fdf9a4870ddecb06742cd1ab529b93ec2bb9419b88d6dc6bee"} } and I got the response as {"seq":3,"error":0}.

But when I reach the ip address it keeps says unable to connect but checking with curl -X POST -d "{"data":{}}" http://192.168.1.xx:8081/zeroconf/info gives the same info as before that otaUnlock = true. So it seems that I haven't flashed it yet.

So, any help on what to do next is appreciated. (Also, I couldn't understand this in the pdf file written by @3N37 "sometimes you have to move the .htaccess file directly to the main directory /var/ww/html and then
reposition the outlet in v2. This is because you would need to change something in the apache
configuration but I don't feel like investigating."), because of my very primitive knowledge.

@VeeGit09
Copy link

@mahipat99

Thank you. I had issues running the PHP script. But I used DasRed Docker to unlock it. So if it unlocks and flashes Tasmota, then I should see the Tasmota access point, which I couldn't see. Running the curlx post command shows that the otaUnlock is true which means all worked. I am puzzled why it didn't flash Tasmota after unlocking.

@3N37
Copy link

3N37 commented Dec 19, 2023

unlocking the device is the hardest thing . for flash after downloading the correct firmware version to the mock server, checked and annotated the sha256 , and placed the otaflash.php and .htaccess file in the root directory .there is no more problem.
The DasRed docker image should already have everything ready. Just start it up and give the command curl.... from your computer's terminal

@egio12
Copy link

egio12 commented Dec 19, 2023

@3N37
I have read all your conversations, and I have made several attempts to unlock my sonoff mini r2 fw. 3.7.6. I tried using both AdGuard with DNS rewrites and Dnsmasq, but unfortunately, I couldn't redirect apid.coolkit.cn to my server where Docker is running with the image created by @DasRed . Do you think that flashing Sonoff Mini R2 devices will be increasingly challenging in the future? I remember when I configured the first ones a few years ago; I only had to run the script, and everything was automatic.

@3N37
Copy link

3N37 commented Dec 19, 2023

@enricogiordano
la procedura secondo me si è semplificata, the procedure in my opinion has simplified, if you can't do the redirect of apid.coolkit.cn it can't work . In adguard you just have to type apid... and then the ip of your server and then make sure that your browser uses adguard and that the cache is clean

@dreeti
Copy link

dreeti commented Dec 20, 2023

Well, I think I need to step back and understand somethings here. So, @dreeti, when I run the docker container created by @DasRed and do the sonoff_ota_unlock, does it both unlock and flash with the Tasmota bin? I followed all the steps that you explained in earlier posts, and I could unlock it (I believe otaUnlock: true means it's unlocked now). What steps did you follow after that to flash Tasmota, can you explain that as well?

I have ordered some more sonoff minis. I hope they will arrive with an older firmware than 3.7.6.
I had some with firmware 3.5.0 and that worked with https://githubhelp.com/njh/sonoff-ota-flash-cli
that's the script @mahipat99 (#45 (comment)) referred to as "original script".

Good luck. Don't stop trying - it's very rewarding when it finally works :-)

@mahipat99
Copy link

@egio12
Here are the steps for AdGuard.

@dreeti
Added options for the alternative method, which skips the OTA unlock process in case you have already unlocked it via any other method.

@VeeGit09
You can also try the above method; there's no need for a mock server if you've already unlocked it.

@3N37
Copy link

3N37 commented Dec 20, 2023

@mahipat99 ,
Great ! a simple and concise guide ,nice job !

@egio12
Copy link

egio12 commented Dec 20, 2023

I have finally managed to flash my Sonoff devices. My Sonoffs arrived with firmware version 3.7.3. Since I initially couldn't flash them, I connected one to the EWeLink app and updated it to version 3.7.6. Eventually, I successfully flashed all of them, regardless of whether they had version 3.7.3 or 3.7.6.

Here is the procedure I followed to flash my Sonoff Mini R2 devices:

  1. I started a Docker container using the image from @DasRed (https://hub.docker.com/r/dasred/sonoff-ota_unlock).

    docker run -d --name sonoff-ota_unlock --restart unless-stopped -p 80:9082 dasred/sonoff-ota_unlock
    
  2. Now, I needed to ensure that in my home network, when visiting the domain apid.coolkit.cn, it would be forwarded to the IP address of the server running the container. Since my FRITZ!Box doesn't allow DNS spoofing (at least as far as I know), I had to install AdGuard and use its DNS Rewrites function.
    (This guide by @mahipat99 precisely outlines the steps I took within the AdGuard panel)

  3. I entered the IP address of the AdGuard server as the local DNS server in my Fritzbox:
    Local Network → Network → Network Settings → Other Settings → IPv4 Settings → Local DNS Server. After entering the AdGuard server's IP address, it's advisable to restart the Sonoff by disconnecting and reconnecting it to ensure that the DNS server is updated.

  4. Important step (the reason I couldn't initially flash the Sonoff): If you have a Fritzbox, you also need to configure an exception in the DNS rebind protection. Follow these simple steps. Add apid.coolkit.cn to the exceptions. It's essential to restart the Fritzbox after configuring the exception.

  5. At this point, I executed the command:

    curl -O https://raw.githubusercontent.com/IBims1NicerTobi/sonoff-ota-flash-cli-devid-fix/main/sonoff-ota-flash.sh && chmod +x sonoff-ota-flash.sh && ./sonoff-ota-flash.sh -i 192.168.[your sonoff ip here]
    

    This allowed me to complete both the OTA unlock and Tasmota flashing procedures. The script handled everything automatically.

I'd like to add that I ran both the Docker image and the AdGuard server within my Home Assistant instance without any issues or conflicts.

@VeeGit09
Copy link

Thank you @egio12 for a clear step by step instruction. Perfectly put together. It worked like a charm. The only difference is I used Pi-hole to direct the POST to my local dns server. Since Pi-hole runs in port 80 (which I changed it in lighttpd.conf file, but still had issues, may be for me) I was running two different Ubuntu systems (my old PC and a laptop) as the mock server running the container by @DasRed also uses port 80. Used ARC (Advanced Rest Client) in Windows to POST the command http://xxx.xxx.xx.xx/zeroconf/info to check whether my Sonoff Mini Device is connected. Once everything setup, it took just 45 minutes to unlock 8 devices, update and setup Tasmato.

Thank you all especially, @dreeti. @3N37 and @mahipat99 for the details that helped to understand the instructions by @egio12. Also, thanks to @DasRed for making this painless.

@dreeti
Copy link

dreeti commented Dec 23, 2023

@VeeGit09
I am very glad that you succeeded. Well done for not giving up!

I got 5 new sonoff minis yesterday - they came with firmware 3.6.0.
@mahipat99
You script works fantastic! It actually boring - I just put the minis on my network and started your script without IP. Done.
Thanks very much. Great work!

Screenshot 2023-12-23 at 10 37 56

@mahipat99
Copy link

@dreeti Haha, yes, it actually scans, but sometimes there are hits and misses. Adding an IP solves that

Btw, all the credit goes to Nicholas

@VeeGit09
Copy link

@mahipat99 Yes, you are right, for me for some reasons without IP, it couldn't find. So I included the IP. If there are many devices in the network it might be difficult to find the IP address, but mostly it would be named either eWelink_1001xxxxxx or ESP_XXXXXX for the SonoffMini device in the network after its connected to the local network through the DIY mode.

@VeeGit09
Copy link

@dreeti @3N37 @mahipat99 @egio12

This is not the topic of discussion. Any one used WSL2 Ubuntu for this process. I spent several days to expose port 80 to run the mock server but couldn't do it, missing something. If so, please let me know, I am interested in learning that.

@3N37
Copy link

3N37 commented Dec 24, 2023

@VeeGit09
dasred made an 'image with the mockserver but you have to install docker (https://hub.docker.com/r/dasred/sonoff-ota_unlock) don't complicate your life using WSL2. Using docker is super easy and very secure.

@VeeGit09
Copy link

@3N37
Great, thanks, thats what I decided after few days experiment with it.

@carlosoboe
Copy link

carlosoboe commented Dec 27, 2023 via email

@3N37
Copy link

3N37 commented Dec 27, 2023

@carlosoboe
hola,dnsspoofing uses UDP port 53 , mockserver uses port 80.
If you want to change the public port instead, you have to use --publish : e.g.: --publish 8888:80 and it will be reachable from port 8888.
or

image

@fr43c0
Copy link

fr43c0 commented Jan 17, 2024

Hi there!
I currently own 4 old Sonoff Mini devices, and I've recently updated their firmware to version 3.7.6. In an effort to understand their network behavior, I followed the provided instructions. Specifically, I attempted to determine whether the devices were attempting to communicate with any external addresses.

After configuring the devices to connect to my local WiFi network, I executed both tcpdump and Wireshark to capture network traffic. Unless I overlooked a step, it appears that my devices are not initiating any connections to external servers. This observation leads me to question the effectiveness of the Docker image in my current understanding.

I'd appreciate any insights or guidance on this matter. It's possible that there are additional considerations or steps I should take to ensure a comprehensive analysis of the network behavior of my Sonoff Mini devices. Thank you in advance for your assistance!

==========TCPDUMP=========

sudo tcpdump -i wlx00c0ca4ab294 ether host dc:4f:22:be:96:3f

tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlx00c0ca4ab294, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:08:06.386955 IP 192.168.0.13.mdns > mdns.mcast.net.mdns: 0*- [0q] 4/0/0 PTR eWeLink_1000b4544d._ewelink._tcp.local., (Cache flush) TXT "txtvers=1" "id=1000b4544d" "type=diy_plug" "apivers=1" "seq=4" "data1={"switch":"off","startup":"off","pulse":"off","sledOnline":"on","fwVersion":"3.7.6","pulseWidth":500,"rssi":-72,"ssid":"VIVOFIBRA-70A1","bssid":"68:d4:0c:4c:70:af"}", (Cache flush) SRV eWeLink_1000b4544d.local.:8081 0 0, (Cache flush) A 192.168.0.13 (423)
14:11:07.384770 IP 192.168.0.13.mdns > mdns.mcast.net.mdns: 0*- [0q] 4/0/0 PTR eWeLink_1000b4544d._ewelink._tcp.local., (Cache flush) TXT "txtvers=1" "id=1000b4544d" "type=diy_plug" "apivers=1" "seq=4" "data1={"switch":"off","startup":"off","pulse":"off","sledOnline":"on","fwVersion":"3.7.6","pulseWidth":500,"rssi":-72,"ssid":"VIVOFIBRA-70A1","bssid":"68:d4:0c:4c:70:af"}", (Cache flush) SRV eWeLink_1000b4544d.local.:8081 0 0, (Cache flush) A 192.168.0.13 (423)
14:11:07.384822 IP 192.168.0.13.mdns > mdns.mcast.net.mdns: 0*- [0q] 4/0/0 PTR eWeLink_1000b4544d._ewelink._tcp.local., (Cache flush) TXT "txtvers=1" "id=1000b4544d" "type=diy_plug" "apivers=1" "seq=4" "data1={"switch":"off","startup":"off","pulse":"off","sledOnline":"on","fwVersion":"3.7.6","pulseWidth":500,"rssi":-72,"ssid":"VIVOFIBRA-70A1","bssid":"68:d4:0c:4c:70:af"}", (Cache flush) SRV eWeLink_1000b4544d.local.:8081 0 0, (Cache flush) A 192.168.0.13 (423)
14:11:10.461302 IP 192.168.0.13.mdns > mdns.mcast.net.mdns: 0*- [0q] 4/0/0 PTR eWeLink_1000b4544d._ewelink._tcp.local., (Cache flush) TXT "txtvers=1" "id=1000b4544d" "type=diy_plug" "apivers=1" "seq=4" "data1={"switch":"off","startup":"off","pulse":"off","sledOnline":"on","fwVersion":"3.7.6","pulseWidth":500,"rssi":-72,"ssid":"VIVOFIBRA-70A1","bssid":"68:d4:0c:4c:70:af"}", (Cache flush) SRV eWeLink_1000b4544d.local.:8081 0 0, (Cache flush) A 192.168.0.13 (423)
14:11:10.467488 IP 192.168.0.13.mdns > mdns.mcast.net.mdns: 0*- [0q] 4/0/0 PTR eWeLink_1000b4544d._ewelink._tcp.local., (Cache flush) TXT "txtvers=1" "id=1000b4544d" "type=diy_plug" "apivers=1" "seq=4" "data1={"switch":"off","startup":"off","pulse":"off","sledOnline":"on","fwVersion":"3.7.6","pulseWidth":500,"rssi":-72,"ssid":"VIVOFIBRA-70A1","bssid":"68:d4:0c:4c:70:af"}", (Cache flush) SRV eWeLink_1000b4544d.local.:8081 0 0, (Cache flush) A 192.168.0.13 (423)
...
8081 0 0, (Cache flush) A 192.168.0.13 (423)
14:12:03.397437 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:12:03.398667 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:12:03.399190 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:12:10.406052 IP 192.168.0.13.mdns > mdns.mcast.net.mdns: 0*- [0q] 4/0/0 PTR eWeLink_1000b4544d._ewelink._tcp.local., (Cache flush) TXT "txtvers=1" "id=1000b4544d" "type=diy_plug" "apivers=1" "seq=4" "data1={"switch":"off","startup":"off","pulse":"off","sledOnline":"on","fwVersion":"3.7.6","pulseWidth":500,"rssi":-72,"ssid":"VIVOFIBRA-70A1","bssid":"68:d4:0c:4c:70:af"}", (Cache flush) SRV eWeLink_1000b4544d.local.:8081 0 0, (Cache flush) A 192.168.0.13 (423)
...
8081 0 0, (Cache flush) A 192.168.0.13 (423)
14:14:53.329796 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:14:53.330206 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:14:53.330548 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:15:04.106544 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:15:04.107033 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:15:04.107500 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:15:23.106875 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
14:15:23.107252 IP 192.168.0.13 > mdns.mcast.net: igmp v2 report mdns.mcast.net
^C
34 packets captured
34 packets received by filter
0 packets dropped by kernel

sonoffWireshark

@dreeti
Copy link

dreeti commented Jan 17, 2024

@fr43c0
Hi,
my understanding is that the communication to http://apid.coolkit.cn happens only in the moment when you flash a new firmware/tasmota on the sonoff.
Did you flash you sonoff? Have you been successful?

@fr43c0
Copy link

fr43c0 commented Jan 17, 2024

@dreeti

I'm still trying to unlock the device. The command curl -X POST -d "{"data":{}}" http://192.168.13.xx:8081/zeroconf/info always returns "otaUnlock": false. The command curl -X POST -d "{"data":{}}" http://192.168.13.xx:8081/zeroconf/ota_unlock seems not to be working at all and remains indefinitely stuck without a response. I understand that to perform the unlock, the device would attempt to communicate with an external server, which may vary depending on the original firmware version. However, my device doesn't seem to be doing that, unless I am doing something wrong...

@mahipat99
Copy link

indefinitely stuck without a response

You can send a maximum of 1 request at a time. Make sure no other software/browser is pinging the device.

@3N37
Copy link

3N37 commented Jan 17, 2024

@fr43c0 ,
you wrote that they are old sonoff mini , if they are the ones with the jumper ,the procedure is different

@fr43c0
Copy link

fr43c0 commented Jan 17, 2024

yes the one with the jumper... Jumper is in place already. I also managed to make Wireshark detect the request to api.coolkit.cn ...

@navennn
Copy link

navennn commented Jan 18, 2024

@dreeti

I'm still trying to unlock the device. The command curl -X POST -d "{"data":{}}" http://192.168.13.xx:8081/zeroconf/info alway s returns "otaUnlock": false. The command curl -X POST -d "{"data":{}}" http://192.168.13.xx:8081/zeroconf/ota_unlock seems not to be working at all and remains indefinitely stuck without a response. I understand that to perform the unlock, the device would attempt to communicate with an external server, which may vary depending on the original firmware version. However, my device doesn't seem to be doing that, unless I am doing something wrong...

It may a co dolso be stuck when it attempts to connect to internet and fails.
Are you trying to do it with, or without access to the internet?
Run the tcpdump when you call ota_unlock. Then you should be able to see that traffic, assuming you have currently set up the spoofing. What you see in your current tcpdump is multicast. Seeing this does not mean that spoofing works. It goes to multiple hosts in the network (special protocol with special addresses).

Edit: I somehow missed your last message. That's good. Did it go through to your mock server, or internet? You'll see that in tcpdump. Also I recommend using -an parameter for tcpdump. It'll show you IP address instead of hostnames. Should be easier to see what actually happens.
Try and check ota_unlock by hand (run curl from your machine) and see if there is a reply.

@fr43c0
Copy link

fr43c0 commented Jan 18, 2024

@dreeti @mahipat99 @3N37

I made some progress but still can't unlock the device.

Initially, I successfully used Wireshark appropriately and verified that the request is made to apid.coolkit.cn as described in the instructions.

Instead of using the Docker image kindly provided, I opted to set up a Flask server responding to the POST request at /v2/d/otaflash with a JSON {"error": 422}. However, the response I am getting is "seq":11,"error":422}, and upon checking the info, I still find "otaUnlock":false".

I must be doing something wrong...

I appreciate any tips or suggestions from anyone who might have insights.

$ sudo tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlp2s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:27:52.001190 IP apid.coolkit.cn.54052 > 10.42.0.219.tproxy: Flags [S], seq 1685447935, win 64240, options [mss 1460,sackOK,TS val 2733728749 ecr 0,nop,wscale 7], length 0
17:27:52.005817 IP 10.42.0.219.tproxy > apid.coolkit.cn.54052: Flags [S.], seq 14345, ack 1685447936, win 5840, options [mss 1460], length 0
17:27:52.005856 IP apid.coolkit.cn.54052 > 10.42.0.219.tproxy: Flags [.], ack 1, win 64240, length 0
17:27:52.005954 IP apid.coolkit.cn.54052 > 10.42.0.219.tproxy: Flags [P.], seq 1:184, ack 1, win 64240, length 183
17:27:52.025913 IP 10.42.0.219.tproxy > apid.coolkit.cn.54052: Flags [P.], seq 1:346, ack 184, win 5657, length 345
17:27:52.025945 IP apid.coolkit.cn.54052 > 10.42.0.219.tproxy: Flags [.], ack 346, win 63895, length 0
17:27:52.026034 IP apid.coolkit.cn.54052 > 10.42.0.219.tproxy: Flags [F.], seq 184, ack 346, win 63895, length 0
17:27:52.027608 IP 10.42.0.219.tproxy > apid.coolkit.cn.54052: Flags [F.], seq 346, ack 185, win 5656, length 0
17:27:52.027625 IP apid.coolkit.cn.54052 > 10.42.0.219.tproxy: Flags [.], ack 347, win 63895, length 0
17:27:57.096629 ARP, Request who-has 10.42.0.219 tell apid.coolkit.cn, length 28
17:27:57.098630 ARP, Reply 10.42.0.219 is-at dc:4f:22:be:96:3f (oui Unknown), length 28
17:28:06.641192 IP apid.coolkit.cn.35588 > 10.42.0.219.tproxy: Flags [S], seq 2423920762, win 64240, options [mss 1460,sackOK,TS val 2733743389 ecr 0,nop,wscale 7], length 0
17:28:06.664398 IP 10.42.0.219.tproxy > apid.coolkit.cn.35588: Flags [S.], seq 14842, ack 2423920763, win 5840, options [mss 1460], length 0
17:28:06.664439 IP apid.coolkit.cn.35588 > 10.42.0.219.tproxy: Flags [.], ack 1, win 64240, length 0
17:28:06.664544 IP apid.coolkit.cn.35588 > 10.42.0.219.tproxy: Flags [P.], seq 1:189, ack 1, win 64240, length 188
17:28:06.674120 IP 10.42.0.219.tproxy > apid.coolkit.cn.35588: Flags [P.], seq 1:147, ack 189, win 5652, length 146
17:28:06.674164 IP apid.coolkit.cn.35588 > 10.42.0.219.tproxy: Flags [.], ack 147, win 64094, length 0
17:28:06.674290 IP apid.coolkit.cn.35588 > 10.42.0.219.tproxy: Flags [F.], seq 189, ack 147, win 64094, length 0
17:28:06.675790 IP 10.42.0.219.tproxy > apid.coolkit.cn.35588: Flags [F.], seq 147, ack 190, win 5651, length 0
17:28:06.675830 IP apid.coolkit.cn.35588 > 10.42.0.219.tproxy: Flags [.], ack 148, win 64093, length 0
17:28:23.139509 IP apid.coolkit.cn.36340 > 10.42.0.219.tproxy: Flags [S], seq 660859195, win 64240, options [mss 1460,sackOK,TS val 2733759887 ecr 0,nop,wscale 7], length 0
17:28:23.143105 IP 10.42.0.219.tproxy > apid.coolkit.cn.36340: Flags [S.], seq 15340, ack 660859196, win 5840, options [mss 1460], length 0
17:28:23.143143 IP apid.coolkit.cn.36340 > 10.42.0.219.tproxy: Flags [.], ack 1, win 64240, length 0
17:28:23.143225 IP apid.coolkit.cn.36340 > 10.42.0.219.tproxy: Flags [P.], seq 1:184, ack 1, win 64240, length 183
17:28:23.153947 IP 10.42.0.219.tproxy > apid.coolkit.cn.36340: Flags [P.], seq 1:346, ack 184, win 5657, length 345
17:28:23.153980 IP apid.coolkit.cn.36340 > 10.42.0.219.tproxy: Flags [.], ack 346, win 63895, length 0
17:28:23.154081 IP apid.coolkit.cn.36340 > 10.42.0.219.tproxy: Flags [F.], seq 184, ack 346, win 63895, length 0
17:28:23.157286 IP 10.42.0.219.tproxy > apid.coolkit.cn.36340: Flags [F.], seq 346, ack 185, win 5656, length 0
17:28:23.157330 IP apid.coolkit.cn.36340 > 10.42.0.219.tproxy: Flags [.], ack 347, win 63895, length 0

─[revir@revir]─[]─[17:25:38]
└──╼ $ curl -XPOST --header "Content-Type: application/json" --data-raw '{ "deviceid": "1000b4544d","data":{}}' http://10.42.0.219:8081/zeroconf/info
{"seq":11,"error":0,"data":{"switch":"off","startup":"off","pulse":"off","pulseWidth":500,"ssid":"sonoffDiy","otaUnlock":false,"fwVersion":"3.7.6","deviceid":"1000b4544d","bssid":"b0:52:16:f6:4a:5","signalStrength":-26}}┌─[revir@revir]─[
]─[17:27:52]
└──╼ $ curl -XPOST --header "Content-Type: application/json" --data-raw '{ "deviceid": "1000b4544d","data":{}}' http://10.42.0.219:8081/zeroconf/ota_flash
{"seq":11,"error":422}┌─[revir@revir]─[]─[17:28:06]
└──╼ $ curl -XPOST --header "Content-Type: application/json" --data-raw '{ "deviceid": "1000b4544d","data":{}}' http://10.42.0.219:8081/zeroconf/info
{"seq":11,"error":0,"data":{"switch":"off","startup":"off","pulse":"off","pulseWidth":500,"ssid":"sonoffDiy","otaUnlock":false,"fwVersion":"3.7.6","deviceid":"1000b4544d","bssid":"b0:52:16:f6:4a:5","signalStrength":-26}}┌─[revir@revir]─[
]─[17:28:23]
WhatsApp Image 2024-01-18 at 17 39 23

@navennn
Copy link

navennn commented Jan 19, 2024

It seems you are using API call otaflash. It should be ota_unlock. See my first post in this thread.

@fr43c0
Copy link

fr43c0 commented Jan 19, 2024

@navennn

My bad! I ran the correct command this time (ota_unlock) , and it stayed stuck without a response again...otaUnlock remains false ...:((

@navennn
Copy link

navennn commented Jan 19, 2024

Try and set it's gateway as your machine, where you can do tcpdump to see what it tries to do. I bet you have the wrong NAT/spoof and it still tries internet.

@fr43c0
Copy link

fr43c0 commented Jan 19, 2024

@navennn
I have set up a hotspot on my laptop without internet access. Additionally, I configured the /etc/hosts file to redirect traffic to my local Flask server. According to the tcpdump logs, it appears that the response to the POST request has been successfully sent and received by the Sonoff device. This suggests that the communication is occurring locally, as intended...

$sudo tcpdump -i wlp2s0 -nA '(tcp or udp)'
12:55:18.200812 IP 10.42.0.1.50396 > 10.42.0.219.8081: Flags [S], seq 46908400, win 64240, options [mss 1460,sackOK,TS val 3748310619 ecr 0,nop,wscale 7], length 0
12:55:18.250529 IP 10.42.0.219.8081 > 10.42.0.1.50396: Flags [S.], seq 6515, ack 46908401, win 5840, options [mss 1460], length 0
12:55:18.250601 IP 10.42.0.1.50396 > 10.42.0.219.8081: Flags [.], ack 1, win 64240, length 0
12:55:18.250748 IP 10.42.0.1.50396 > 10.42.0.219.8081: Flags [P.], seq 1:190, ack 1, win 64240, length 189
POST /zeroconf/ota_unlock HTTP/1.1
Host: 10.42.0.219:8081
User-Agent: curl/7.81.0
Accept: /
Content-Type: application/json
Content-Length: 37
{ "deviceid": "1000b4544d","data":{}}
12:55:18.465641 IP 10.42.0.219.10011 > 10.42.0.1.80: Flags [P.], seq 1:269, ack 1, win 5840, length 268: HTTP: POST /v2/d/otaflash HTTP/1.1
POST /v2/d/otaflash HTTP/1.1
Host: apid.coolkit.cn:80
Content-Type: application/json
Authorization: Sign 6a70494d7b9773419a1ce7742653adc5f396dbf758f273466974edffa8d2a81f
Connection: close
Content-Length: 2
X-CK-Deviceid: 1000b4544d
X-CK-Seq: 6451385484892
{}
12:55:18.465727 IP 10.42.0.1.80 > 10.42.0.219.10011: Flags [.], ack 269, win 63972, length 0
12:55:18.469100 IP 10.42.0.1.80 > 10.42.0.219.10011: Flags [P.], seq 1:167, ack 269, win 63972, length 166: HTTP: HTTP/1.1 200 OK
HTTP/1.1 200 OK
Server: Werkzeug/3.0.1 Python/3.10.12
Date: Fri, 19 Jan 2024 15:55:18 GMT
Content-Type: application/json
Content-Length: 19
Connection: close
{ "error": 422 }
12:55:18.472250 IP 10.42.0.219.10011 > 10.42.0.1.80: Flags [F.], seq 269, ack 167, win 5674, length 0
12:55:18.472349 IP 10.42.0.1.80 > 10.42.0.219.10011: Flags [P.], seq 167:186, ack 270, win 63972, length 19: HTTP
{ "error": 422 }
12:55:18.473088 IP 10.42.0.1.80 > 10.42.0.219.10011: Flags [F.], seq 186, ack 270, win 63972, length 0
12:55:18.473627 IP 10.42.0.219.10011 > 10.42.0.1.80: Flags [R.], seq 270, ack 186, win 5840, length 0
12:55:18.474135 IP 10.42.0.219.10011 > 10.42.0.1.80: Flags [R.], seq 270, ack 187, win 5840, length 0
12:55:47.735244 IP 10.42.0.1.50396 > 10.42.0.219.8081: Flags [F.], seq 190, ack 1, win 64240, length 0
12:55:47.948770 IP 10.42.0.219.8081 > 10.42.0.1.50396: Flags [F.], seq 1, ack 191, win 5650, length 0
12:55:47.948844 IP 10.42.0.1.50396 > 10.42.0.219.8081: Flags [.], ack 2, win 64239, length 0
12:56

@3N37
Copy link

3N37 commented Jan 19, 2024

error 422 appears when you send an incorrect json( – 422: The operation failed and the request parameters are invalid. For example, the device does not support setting specific device information.) from the command line should be curl -X POST -d "{"data":{}}" etc.

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

No branches or pull requests