Hacking a Cheap Temu WiFi Camera

I recently got my hands on a cheap Temu WiFi camera made by Jooan. I figured I will attempt to hack this cheap Temu WiFi camera and stumbled upon an authentication bypass vulnerability. The vuln is pretty much because authentication verficiation is done client side, not server side, allowing you to get to the post login screen. We will look at how I used a browser’s developer tools and Burp proxy to bypass the front-end checks.

Camera1
Camera2

It is a nifty little camera for $8; it has WiFi, infrared night vision, 2 way voice, pretty OK image quality, PTZ, etc. It takes power via USB C but should be pretty easy to mod to run off a battery and solar panel using a TP4056 board and a disposable little vape battery.

But if you value your privacy, don’t be fooled by its features, stay away from it.

Authentication Bypass Issue

The issue is not that there is no authentication, it is just that the code is so bad that it was possible to enter an incorrect username and password, then use Burp Proxy to intercept and modify the response, and get access. Credit where credit is due though, trying to change the username and password after getting access, does validate your credentials again, and because we’re running around with fake credentials which does not match with whatever is hard coded on the camera, then it won’t allow you to change the password.

I did not do a firmware analysis, as by this time I already knew the software probably had more issues, and the fact that the credentials were hard coded and auth was so easily bypassed, was enough for me.

Authentication Bypass Process

Power on the camera and connect to it’s WiFi hotspot. The camera’s IP should be in range 10.68.68.xx (mine was in 10.68.68.22). Open this IP in a web browser and you will be greeted by the login page where it asks for a username and password.

Login page

I entered some random credentials and then inspected things with Firefox Developer Tools.

Login Page Developer Tools

I could see where the request went, but saw the initiator was jquery. No idea what webserver this camera is running, because it is also running .asp pages. Strange.

Clicking on the initiator, shows us this:

Login Page Javascript

I saw there was a login.js, so I opened that in a new window and got this code (I removed the unnecessary code, just showing the important part)

Unpacking the Authentication Code

var ciphertext = $.md5(userkeyget);
	$.get("/goform/getVideoSettings", { userid : useridget, userkey : ciphertext }, function(data, status) {
		//alert("Data: " + data + "\nStatus: " + status);
		if ('success' == status) {
			var jsonObjs = ParseCgiJson(data);
			if (typeof(jsonObjs.fps) == "undefined") {
				alert("failed");
				return;
			}
			var strUrl = (document.URL.split('//')[1]).split('/')[0].split(':')[0];
			SetCookie("policy", 1);
		    SetCookie("url", strUrl);
			SetCookie("userid", useridget);
			SetCookie("userkey", ciphertext);
			SetCookie("loginflag_" + g_hostname, 1);
			window.location.href = "/apcam/index.asp";
		} else {
			alert("failed");
		}

The 3 lines in red is of particular interest. Basically this happens:

  • The first red line says “if the status is equal to the string ‘success’ “, then
  • check if (second red line) “data” (the variable) is a JSON obect, then
  • check if that JSON object contains a key “fps” and check if it is undefined.

So I intercepted the login response using Burp Proxy:

Burp Proxy Intercept

And I replaced the blue line of code with this:

{"status":"success","fps":{"a":"a"}}

That was it, now we satisfy the JS code above, and the SetCookie lines will execute, as well as the window.location.href line, getting us to the post login screen, where you can upload firmware, upload config (if you know the templating to use), etc.

As I said, trying to change the password will not work, it the request is authenticated, and because we’re using some random password, it won’t work.

Post Login Screen

Figuring out the default password

When trying to change or remove the password will give an error saying the password must be between 8 and 31 “bytes”… maybe there is an opportunity for a buffer overflow, who knows.

So I figured, let me trying the password “admin123” as that is 8 characters, and we know for a fact that these mass produced, cheap devices, will not use a unique password. And that worked.

Other issues

  • Pretty much everything is sent as URL parameters so it is super easy to see what it does.
  • The password is sent as an MD5 hash, as a URL parameter, so this will probably end up in logs somewhere.
  • The camera immediately phones home, constantly, non stop. Some are ICMP (ping) packets, some not.
  • At no point during the normal camera setup process is the user asked to change this password. It will therefore be the same for all cameras.

Here is a list of some of the activity and IPs it is connecting to:

Phone home IPs

necrolingus

Tech enthusiast and home labber