Rick's b.log - 2016/08/22 |
|
It is the 24th of November 2024 You are 3.138.124.28, pleased to meet you! |
|
mailto:
blog -at- heyrick -dot- eu
Oh boy.
Or maybe I should say:
Oh God.
I had set the camera to disable its built-in DDNS. The web interface seemed to be ignoring me, so I hacked the scripting and extracted the command to make it work:
Turns out, by the way, that the HTML setup document would never show DDNS as unticked, as the script ticks the box if it is loaded in an unticked state. Lovely.
The DDNS, by the way, is used by the app to provide an easily-found camera. The address is xxxxxxx.nwsvr1.com. You might be wondering why I don't want to use the nwsvr1.com service when my own server is accessible via no-ip. Well, easy. What you know when you look at no-ip is that something is there. Usually it is my Pi. From time to time, it'll be my camera as well (it is only on when I punch a hole in the NAT to allow the world access).
So, in my gross naivety, I thought that maybe it wasn't going to be blathering my information around the place.
The transaction starts fairly normally. The device tries to find out who and where it is, and if its gateway/DNS is working. It then appears to send out a UPnP request (I turned that off too, so a good thing I also have it disabled at the Livebox end!).
Yup. Hardcoded password. I used that to specify a bogus port and LAN address for my camera. The Chinese (or whoever) will think my camera is on port 666.
Just as an experiment, I replaced the username field with a different sequence of numbers and letters.
And, to test, I entered 001abcd.nwsvr1.com into my browser and looked at what came back:
There you go. My IP address and a redirect to port 666.
Assuming there's no sort of rate limiting (and assuming not given that this nastiness works at all!), I wonder how long it would take for somebody to identify available cameras and redirect them. It might be non-trivial if the camera has a custom password, but if it is the admin/admin pair... whoa...
I won't go any further. We've seen enough. The device is really talkative, doing the STUN stuff about every 30 seconds. In the middle of this, XP blasts a load of SSDP notify packets at 239.255.255.250 to advertise its services.
Five minutes later, nwsvr1 is updated again. You know, just in case the IP address changed.
Thankfully my camera isn't quite as braindead as the ones that would happily provide the URI
So, since we have something we could try playing with, time to rummage around inside. The directory
Easily sorted.
Reboot and...
Nothing.
What's worse, the /etc/hosts file was no longer there. Great. They must be dynamically recreating that directory from saved stuff.
Okay, so let's try something else. The folder that contains the camera initialisation script is /system/init with a script called ipcam.sh. As it happens, this folder is writeable. Sweet.
The hosts file is recreated there, and the ipcam script modified as follows:
Reboot and... it didn't work. Actually, it seems to have silenced p2p1.mclview.com as the camera was now looking for p2p2.mclview.com, but it didn't silence nwsvr1.com.
Okay then. Here's the sledgehammer approach. I really couldn't be bothered to work out where best to put the file copy so it would get noticed but wouldn't get deleted, so...
The
And the sledge-ha-mmer
Bingo!
The first two minutes of communications after boot contain a mere 65 transactions, which are: the standard setup and service discovery (including from XP), the STUN to determine the outward IP (to 94.23.26.228 - this address appears to be hardcoded), fetching the time from an NTP server (time.nist.gov), and... actually that's about it. We're about a hundred packets down on the first two minutes of the original boot. I consider this to be a good application of duct tape over the camera's mouth. ☺
Not tried, but, hmmm - I wonder if I could paste in a replacement passwd file using this method?
Silencing the webcam / IPCAM
Just for fun, I set up my XP box to do Internet connection sharing. I tweaked the camera's static IP address to match XP (192.168.0.1 vs the Livebox's 192.168.1.1). Then I booted the camera to check that I could ping the device, and it could ping Google's DNS. With all of that working first time, I fired up WireShark and rebooted the camera.
http://192.168.1.20:8080/set_smarteye_factory_params.cgi?loginuse=NAME&loginpas=PASSWORD&se_ddns_enable=0
What do you know about nwsvr1.com? They're IPCAMs, the same sort. All of them. A person with some spare time could figure out the pattern (it appears to be three digits counting from either 000 or 001 followed by four lower-case alphabet letters), and then just start looking through all of them. By my reckoning, 26*26*26*26 is 456,976. That's how many letter combinations exist, in total. Trying uppercase letters redirects to a lowercased version, so, yeah. Multiply that by 5 or 6, meaning you just need to try something in the region of 2.5 million fetches. All of the ones I've randomly typed into Firefox returned "OFFLINE". However you only need to spot a redirect to know you've hit a live camera. When you have, I wonder how many can be pwned by using the login name admin and the password admin? Better yet, if it's a horribly insecure router (or a stupid user) and port 23 is available - the login name is root and the password is 123456 and this cannot be changed!
So, yeah. Better not to scream "insecure camera here", don't you think?
Then KURONEKO (the XP box) sends an announcement of what it offers.
The camera then spams maybe two dozen malformed UDP packets saying "Hello, I'm online!" (seriously, that's the payload data) to 192.168.0.1 (the XP box) and also to 255.255.255.255.
Some more registration stuff takes place, and by now the camera is ready to talk to the outside world. The first thing it does is look for p2p1.mclview.com. While it is waiting on a reply, it bounces a STUN request off of 94.23.26.228 and 5.135.188.138 and 5.135.188.205. It would seem that "STUN" is a method of a device behind a NAT determining its outward-facing IP address. The device knows that it is 192.168.0.20 but it doesn't know what that means in global scope.
These servers appear to reply with a TFTP Write Request. I can only imagine that WireShark is misinterpreting this, as the destination file specifier are three bytes followed by the outside IP address bytes.
I guess spamming three servers is simpler than asking one and if it fails, trying another...
It seems that this process goes back and forth, now including the mclview server as well.
That done, the camera looks up www.nwsvr1.com and that done, performs an HTTP request for:
GET /api/userip.asp?username=XXX&userpwd=XXX&vertype=913&language=0&dtype=0&tcpport=8080&lanip=192.168.0.20&
But it gets worse.
MUCH WORSE.
The server replied "Update-OK".
Holy hell, who codes shit like that?
Excuse my Old Norse/Germanic there, but this is such a pile of fail I'm sure you uttered even worse words, likely of Middle Dutch origin. ☺
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 20
Content-Type: text/html
Date: Mon, 22 Aug 2016 19:22:21 GMT
Keep-Alive: timeout=20, max=100
Location: http://90.32.247.121:666
Server: Apache/2.2.22 (Ubuntu)
Vary: Accept-Encoding
x-powered-by: PHP/5.3.10-1ubuntu3.11
http://x.x.x.x//proc/kcore
without any attempt at user authentication. If my camera did that, it would be straight back in its box and back to the supermarket before you could blink.
/etc
contains the password file (with the hardcoded root username), and some other configuration stuff.
There is no hosts file.
vi hosts
vi is less than friendly. You need to press 'i' to go to insert mode, to then type the following:
127.0.0.1 www.nwsvr1.com p2p1.mclview.com
Then press Enter
, followed by Escape
.
Back in command mode, type :w
then press Enter
to write the file to disc, and then :q
and Enter
once more to quit. Do it as two separate commands, it doesn't seem to like the :wq!
syntax.
export LD_LIBRARY_PATH=/system/system/lib:$LD_LIBRARY_PATH
export PATH=/system/system/bin:$PATH
telnetd
/system/system/bin/daemon.v5.5 &
/system/system/bin/cmd_thread &
/system/system/bin/gmail_thread &
cp /system/init/hosts /etc/hosts
/system/init/hosts
file:
127.0.0.1 p2p1.mclview.com p2p2.mclview.com www.nwsvr1.com
ipcam.sh
file:
export LD_LIBRARY_PATH=/system/system/lib:$LD_LIBRARY_PATH
export PATH=/system/system/bin:$PATH
cp /system/init/hosts /etc/hosts
telnetd
cp /system/init/hosts /etc/hosts
/system/system/bin/daemon.v5.5 &
cp /system/init/hosts /etc/hosts
/system/system/bin/cmd_thread &
cp /system/init/hosts /etc/hosts
/system/system/bin/gmail_thread &
cp /system/init/hosts /etc/hosts
Rob, 23rd August 2016, 17:01 Some good detective work there!
It's almost as if these things were thrown together with absolutely no thought to security at all..Rick, 23rd August 2016, 20:58 That's probably EXACTLY what it was. After all, what domestic user that buys something like this from a supermarket is going to know diddly/squat about security?
Sadly, that's probably true...
I have examined the scripting for the "mobile view" option to see how it works. God - it sets up some Javascript to simply spam the get_snapshot function. So, yeah, it isn't even video, it's just a repeatedly updated still JPEG as fast as the network can push 'em over.
On the other hand, ought to be able to throw together some code for RISC OS to do that... ;-)
I'm going to go water the plants and listen to Nightwish. This stuff frazzles my poor little braincell.David Pilling, 31st August 2016, 18:40 It is interesting how the people making these have access to more powerful processors than does the hobbyist. Generally these pan and tile ip cams are a lot more expensive than yours, and this makes me wonder if yours is a fake. I recently bought some super cheap digital cameras off ebay, and they were fakes - full of electronics which kinda sorta worked, but was useless. Only good enough to convince you it worked long enough to buy it and get it home. A common situation amongst the people selling 'Rolex' watches on Blackpool's 'Golden Mile'.Rick, 31st August 2016, 19:11 To take your comments on reverse order - of course it is a "clone". I won't say fake as it does work, but it's really just a knock off FOSCAM. But then one could use similar logic to say the Pi is just an inferior Beagle, see? :-)
To your first point, I don't think so. It's an ethernet/wifi chip with a MIPS core clocking something like 300MHz. This is the sort of spec I would expect to see in a budget bit of "smart" networking kit, like a WiFi repeater or the like. It runs Linux. Well, somebody figured they could hook a camera to the USB port, control a couple of motors from the GPIO, and the result is an inexpensive web camera.
Remember, it is outputting MJPEG, not anything that requires actual processing grunt - and I'm not sure this device is up to that...anon, 4th May 2018, 16:32 My crappy iot camera, basically the same as this, has a few times plenty of reset, and once or twice reverted to factory defaults. That means any local hacks on the camera can be lost.
The IoT cam resets on its own reasonably often when moved, as the reset button is so close to the outer case. I had to also put insulation tape across the PCB inside to stop a short-circuit if the screw thread on the base it used to mount the camera.
Some quality design. Luckily my camera was free....
I have an old macmini running Debian as a firewall to the thing, running a DHCP server just for the camera if it resets. The camera network config has no gateway. NTPd on the mac for the camera, and then strict FW rules so only one Linux user can talk to the camera on ethernet. The mac does no routing, and the UI and video is tunnelled over SSH. And a DNS server that knows of the camera, the time server, and NOTHING else.
Also hourly a cron'd script telnets into the ipcam to remove the wireless LAN module. The aerial has been physically cut off the camera, the system-on-chip means the radio hardware can't be removed.
I used to run iptables on the camera, but it seemed to overload the thing with time. Using the telnet backdoor and the expect program works well to keep hacks on the camera from a network machine, even if the cam reverts to factory defaults.
© 2016 Rick Murray |
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted. RIPA notice: No consent is given for interception of page transmission. |