{"id":1696,"date":"2022-04-14T09:15:29","date_gmt":"2022-04-14T16:15:29","guid":{"rendered":"https:\/\/surfrock66.com\/?p=1696"},"modified":"2023-01-06T11:53:10","modified_gmt":"2023-01-06T19:53:10","slug":"improving-the-motorola-blink-baby-monitor-camera-part-6","status":"publish","type":"post","link":"https:\/\/surfrock66.com\/?p=1696","title":{"rendered":"Improving the Motorola Blink Baby Monitor\/Camera (Part&#8230;6?!?)"},"content":{"rendered":"<p>After all this time&#8230;why am I still working on this?  The cameras are dead, Motorola shut down the monitoreverywhere service, so the cameras are dead!   You can&#8217;t register them, or join to cameras remotely, right?<\/p>\n<p>Well, they still work on the LAN, so if they&#8217;re already on the wifi, you can use them as little RTSP streams.  The problem is&#8230;I want to change my SSID&#8217;s, and there&#8217;s no way to rejoin to wifi without the app connecting with the (now offline) monitoreverywhere service.<\/p>\n<p>Enter crazy old Joe.  I had a Titanium Backup of the apk and my config from an android device I don&#8217;t even have anymore.  I was able to extract this and decompile it to learn how the app handles registration, then emulate that.  First, from previous research, when you factory reset a camera it broadcasts a &#8220;Camera-######&#8221; SSID when you can connect to as it&#8217;s open.  You&#8217;ll get a 192.168.2.# address, and the camera will be &#8220;192.168.2.1&#8221;.  From there, you can start performing operations on the camera, for example, If you go here in a web browser: <a href=\"http:\/\/192.168.2.1\/?action=command&amp;command=enable_telnet\">http:\/\/192.168.2.1\/?action=command&amp;command=enable_telnet<\/a> You will then be able to telnet to the camera.<\/p>\n<!--more-->\n<p>From previous work, we know a lot of the scripts and commands on there, but I never found how to format the wifi request.  So, I started poking through the apk.  Here&#8217;s some snippets that are useful:<\/p>\n<pre><code>this.cam_profile.setBasicAuth_usr(&quot;camera&quot;);\nthis.cam_profile.setBasicAuth_pass(&quot;000000&quot;);<\/code><\/pre>\n<p>The camera has a basic http authentication piece, and that is the default username and password&#8230;maybe.  I also found this in defining the variables:<\/p>\n<pre><code>this.usr_name = usrName == null ? &quot;&quot; : usrName;\nthis.pass_wd = pwd == null ? &quot;&quot; : pwd;<\/code><\/pre>\n<p>So the user and password will either be &#8220;camera:000000&#8221; or &#8220;:&#8221;.  We can try both.<\/p>\n<pre><code>public String build_setup_core_request() {\n    String auth_mode;\n    String key_index;\n    if (this.security_type.equalsIgnoreCase(&quot;WEP&quot;)) {\n        auth_mode = this.auth_method.equalsIgnoreCase(&quot;Open&quot;) ? &quot;0&quot; : &quot;1&quot;;\n        key_index = String.format(&quot;%d&quot;, Integer.valueOf(Integer.parseInt(this.key_index) - 1));\n    } else if (this.security_type.equalsIgnoreCase(&quot;OPEN&quot;)) {\n        auth_mode = &quot;0&quot;;\n        key_index = &quot;0&quot;;\n    } else {\n        auth_mode = &quot;2&quot;;\n        key_index = &quot;0&quot;;\n    }\n    String ssid_len = String.format(&quot;%03d&quot;, Integer.valueOf(this.ssid.getBytes().length));\n    String sec_key_len = String.format(&quot;%02d&quot;, Integer.valueOf(this.pass_string.length()));\n    String usr_name_len = String.format(&quot;%02d&quot;, Integer.valueOf(this.usr_name.length()));\n    String passwd_len = String.format(&quot;%02d&quot;, Integer.valueOf(this.pass_wd.length()));\n    String setup_value = String.valueOf(&quot;1&quot;) + &quot;00&quot; + auth_mode + key_index + &quot;0&quot; + ssid_+ sec_key_len + &quot;0000000&quot; + usr_name_len + passwd_len + this.ssid + this.pass_string + .usr_name + this.pass_wd;\n    if (shouldEncodeData()) {\n        try {\n            setup_value = URLEncoder.encode(setup_value, &quot;UTF-8&quot;);\n        } catch (UnsupportedEncodingException e) {\n            e.printStackTrace();\n        }\n        Log.d(GcmIntentService.TAG, &quot;Encode setup data&quot;);\n    } else {\n        Log.d(GcmIntentService.TAG, &quot;No need to encode setup data.&quot;);\n    }\n    String setup_request = &quot;\/?action=command&amp;command=setup_wireless_save&amp;setup=&quot; + setup_value;\n    return setup_request;\n}<\/code><\/pre>\n<p>That is exactly what we need.  First of all, since the security type would be &#8220;WPA2\/PSK&#8221; auth_mode is 2 and key_index is 0.  The SSID length is formatted to be 3 digits (mine is 32 characters, so 032), and the passcode length is formatted to be 2 digits (mine is 26 characters, so 26).  <\/p>\n<p>That means the pieces needed break down into one of these 2:<\/p>\n<p>1 00 2 0  0 032 26 000000 06 06 SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS PPPPPPPPPPPPPPPPPPPPPPPPPP camera 000000<\/p>\n<p>or<\/p>\n<p>1 00 2 0  0 032 26 000000 00 00 SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS PPPPPPPPPPPPPPPPPPPPPPPPPP<\/p>\n<p>Following all that string concatenation, we have 2 options to set up the wifi, depending on which password configuration it needs (SSID and passcode are obfuscated):<\/p>\n<pre><code>http:\/\/192.168.2.1\/?action=command&amp;command=setup_wireless_save&amp;setup=1002000322600000000606SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPPPPPPPPPPPPPPPPPPPPPPPPPPcamera000000<\/code><\/pre>\n<pre><code>http:\/\/192.168.2.1\/?action=command&amp;command=setup_wireless_save&amp;setup=1002000322600000000000SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPPPPPPPPPPPPPPPPPPPPPPPPPP<\/code><\/pre>\n<p>The 2nd one worked; the camera made a loud beep but the SSID was still active.  I telnetted to the camera and this was in \/var\/log\/messages:<\/p>\n<pre><code>Jan  1 15:54:57 MJPG-streamer [1901]: Org client thread : GET \/?action=command&amp;command=setup_wireless_save&amp;setup=1002000322600000000000SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPPPPPPPPPPPPPPPPPPPPPPPPPP HTTP\/1.1^M\nJan  1 15:54:57 MJPG-streamer [1901]: After URL Encode : GET \/?action=command&amp;command=setup_wireless_save&amp;setup=1002000322600000000000SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPPPPPPPPPPPPPPPPPPPPPPPPPP HTTP\/1.1^M\nJan  1 15:54:57 MJPG-streamer [1901]: Connect 192.168.2.11\nJan  1 15:54:57 MJPG-streamer [1901]: access granted\nJan  1 15:54:57 MJPG-streamer [1901]: command string: setup_wireless_save\nJan  1 15:54:57 MJPG-streamer [1901]: setup=1002000322600000000000SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPPPPPPPPPPPPPPPPPPPPPPPPPP HTTP\/1.1^M\nJan  1 15:54:57 MJPG-streamer [1901]: len=91\nJan  1 15:54:57 MJPG-streamer [1901]: 1002000322600000000000SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPPPPPPPPPPPPPPPPPPPPPPPPPP HTTP\/1.1^M\nJan  1 15:54:57 MJPG-streamer [1901]: len SSID 32 and index 9\nJan  1 15:54:57 MJPG-streamer [1901]: Key Length = 26\nJan  1 15:54:57 MJPG-streamer [1901]: String got is:0\nJan  1 15:54:57 MJPG-streamer [1901]: Len of workport is:0\nJan  1 15:54:57 MJPG-streamer [1901]: SSID=&#039;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS&#039; - Key=&#039;PPPPPPPPPPPPPPPPPPPPPPPPPP&#039;\nJan  1 15:54:57 MJPG-streamer [1901]: Before sem wait\nJan  1 15:54:57 MJPG-streamer [1901]: After sem wait\nJan  1 15:54:57 MJPG-streamer [1901]: Finish init Flash\nJan  1 15:54:57 MJPG-streamer [1901]: Flash Init 20 (1901)\nJan  1 15:54:57 MJPG-streamer [1901]: Before sem post\nJan  1 15:54:57 MJPG-streamer [1901]: Flash DeInit 20 (1901)\nJan  1 15:54:57 MJPG-streamer [1901]: Finish deinit Flash\nJan  1 15:54:57 MJPG-streamer [1901]: After sem post\nJan  1 15:54:57 MJPG-streamer [1901]: ===WRITE TO FLASH===\nJan  1 15:54:57 MJPG-streamer [1901]: Before sem wait\nJan  1 15:54:57 MJPG-streamer [1901]: After sem wait\nJan  1 15:54:57 MJPG-streamer [1901]: Finish init Flash\nJan  1 15:54:57 MJPG-streamer [1901]: Flash Init 20 (1901)\nJan  1 15:54:57 MJPG-streamer [1901]: Before sem post\nJan  1 15:54:57 MJPG-streamer [1901]: Flash DeInit 20 (1901)\nJan  1 15:54:57 MJPG-streamer [1901]: Finish deinit Flash\nJan  1 15:54:57 MJPG-streamer [1901]: After sem post\nJan  1 15:54:57 MJPG-streamer [1901]: Wifi configuration saved successfully\nJan  1 15:54:57 MJPG-streamer [1901]: leaving<\/code><\/pre>\n<p>It looked like it took, so I rebooted the camera, and it connected and got its proper assigned DHCP address!  I am able to view the camera connected to the correct SSID!  As far as I&#8217;m concerned, the camera is now back to as operational as I want it to be, despite the vendor&#8217;s abandoning of the device.<\/p>","protected":false},"excerpt":{"rendered":"<p>After all this time&#8230;why am I still working on this? The cameras are dead, Motorola shut down the monitoreverywhere service, so the cameras are dead! You can&#8217;t register them, or join to cameras remotely, right? Well, they still work on the LAN, so if they&#8217;re already on the wifi, you can use them as little [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,3],"tags":[],"class_list":["post-1696","post","type-post","status-publish","format-standard","hentry","category-geek","category-projects"],"_links":{"self":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1696"}],"version-history":[{"count":7,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1696\/revisions"}],"predecessor-version":[{"id":1736,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1696\/revisions\/1736"}],"wp:attachment":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}