WEBVTT

00:01.440 --> 00:04.240
Good afternoon, everyone, and thank you all for coming.

00:04.240 --> 00:07.300
This is Abusing Peer-to-Peer to Hack 3 Million Cameras.

00:07.340 --> 00:13.740
This talk is the culmination of about two years of research, so I'm very excited to finally be able to share this with you all.

00:13.740 --> 00:15.520
And with that, let's get started.

00:16.520 --> 00:21.660
I'm going to be talking about an obscure feature lurking in IoT devices around the world.

00:21.660 --> 00:28.620
Peer-to-peer is intended to make life easier for people, but it's had the nasty side effect of exposing millions of devices to the internet.

00:28.620 --> 00:31.380
Even those behind firewalls are not immune.

00:31.820 --> 00:37.740
Hundreds of different brands are affected by this, including security cameras, alarm systems, and even baby monitors.

00:37.920 --> 00:40.340
But exposure is just the tip of the iceberg.

00:40.340 --> 00:45.960
When hordes of insecure things get put on the internet, you can bet the end result is not going to be pretty.

00:46.080 --> 00:48.820
So I'm here to show you just how bad this can get.

00:49.300 --> 01:00.340
By the end of this talk, you'll see how peer-to-peer devices work, the numerous ways they can be exploited, and finally, how a $40 purchase from Amazon is all you need to start hacking into other devices.

01:01.500 --> 01:02.600
So who am I?

01:02.600 --> 01:11.000
My name is Paul Marapici, I am a security researcher based out of San Jose, California, and I probably spend too much time getting angry at computers.

01:11.320 --> 01:17.140
I largely focus on offensive security, and I work on the red team at a certain enterprise cloud company.

01:17.360 --> 01:25.640
When I'm not breaking things, I make music, I dabble in photography, and I have two cats, who funny enough, are the catalyst for this entire story.

01:27.100 --> 01:33.640
In 2018, I adopted a pair of rescue kittens, and I wanted to keep an eye on them as they slowly took over my apartment.

01:34.200 --> 01:40.920
I had an old IP camera from around 2002, but this was now 2018, so I figured I could get something a little better.

01:41.320 --> 01:49.180
Amazon has a wide selection of IP cameras, and some are marked as Amazon's choice, and there's quite a few with decent enough reviews.

01:49.540 --> 01:58.000
This SV3C model, for example, is $40, and it has 4 stars with nearly 2,000 reviews, so it sounds like a pretty good deal.

01:58.420 --> 02:04.340
I figured this would be like any other network device, where if I wanted to view it externally, I would need to forward a port.

02:04.460 --> 02:09.620
But once I hooked it up, I realized I could immediately view it from my phone, no setup required.

02:09.880 --> 02:17.780
This shook me a little bit, because it implies it's either doing something to get around my router, or it's sending my video through some third-party servers.

02:17.780 --> 02:21.280
Either way, I'm freaked out, so I load up Wireshark.

02:21.660 --> 02:24.760
And as we can see, this camera is very chatty.

02:24.760 --> 02:29.040
It's pinging three different servers every 40 seconds, two of which are in China.

02:29.040 --> 02:36.200
And as I continue watching, I start noticing that sometimes my video is being funneled through mysterious servers all over the world.

02:36.200 --> 02:40.940
At one point, I even see this camera talking to a Comcast IP in a different state.

02:41.240 --> 02:44.880
It turns out a lot of people have noticed this sketchy behavior.

02:45.280 --> 02:51.400
There are a lot of concerned reviews talking about this suspicious traffic on UDP port 32100.

02:51.400 --> 02:55.220
Not just on my brand of camera, but on many, many different models.

02:55.240 --> 02:57.120
So now I'm extremely intrigued.

02:57.120 --> 02:58.520
What is this, exactly?

02:59.640 --> 03:01.320
Well, this is peer-to-peer.

03:01.320 --> 03:08.580
And I'm sure the name is conjuring memories of file-sharing networks like Napster and Kazaa, but the context here is a little bit different.

03:08.680 --> 03:15.880
In the context of IoT, peer-to-peer is a feature that lets people connect to their device from anywhere in the world without any special setup.

03:15.940 --> 03:21.420
You have to remember, some folks don't even know how to log into their routers, never mind how to forward a port.

03:21.420 --> 03:24.740
So vendors started coming up with ways to make connecting easier.

03:24.740 --> 03:32.220
To achieve this, devices with peer-to-peer will automatically work around both NAT and firewalls so anyone from the outside can connect in.

03:32.220 --> 03:36.260
But thankfully, your device doesn't have any gaping security holes, right?

03:37.080 --> 03:39.120
So where does this feature come from?

03:39.120 --> 03:43.680
Peer-to-peer is not typically something that's developed in-house by device manufacturers.

03:43.720 --> 03:50.300
There are actually several different players in the industry who develop peer-to-peer solutions, and device makers will get it from them.

03:50.420 --> 03:56.820
So this originates from higher up in the supply chain, meaning any faults in it are going to propagate downward very quickly.

03:57.140 --> 04:02.980
The largest is probably ThruTech, whose Kali platform is in use by over 66 million devices.

04:02.980 --> 04:07.220
If you've got a Wyze camera at home, chances are it's using ThruTech's platform.

04:07.480 --> 04:13.900
This talk will focus on two products in particular, CS2 Network P2P and Shenzhen Uni iLink P2P.

04:13.900 --> 04:22.700
According to CS2, their product is in use by over 50 million devices, and iLink P2P is actually a functionally identical clone of CS2.

04:22.700 --> 04:28.220
Its market share is relatively smaller, but it's still present in over 3.6 million devices.

04:28.880 --> 04:33.940
So with peer-to-peer existing in over 100 million devices, it's obviously a popular feature.

04:33.940 --> 04:35.840
But what are the risks here?

04:35.840 --> 04:40.660
Well, primarily, peer-to-peer by its very nature is meant to expose devices.

04:40.660 --> 04:46.580
And this should be pretty scary, given IoT has a pretty notorious history when it comes to security.

04:46.680 --> 04:52.040
But convenience always wins, so devices are now punching through your firewall by design.

04:52.240 --> 05:00.500
In many cases, there's no way to turn this feature off, and anyone that has your device's unique identifier, or UID, can easily connect to it.

05:00.500 --> 05:04.840
I'll be demonstrating how these UIDs aren't exactly all that hard to come by.

05:05.120 --> 05:09.940
These devices are typically running Linux under the hood, with everything as root, of course.

05:09.980 --> 05:17.940
So when you pair that with how they're also essentially online without a firewall, the insanity of this whole concept really starts to set in.

05:17.980 --> 05:26.580
While there are obvious risks, like spying on someone's camera or disabling their alarm system, those pale in comparison to remote code execution.

05:26.780 --> 05:31.820
Malware leveraging the ability to punch through firewalls could really spread like wildfire.

05:32.560 --> 05:38.020
So now we know what peer-to-peer does, and we've come up with a few ways that we can potentially have fun with it.

05:38.020 --> 05:43.460
Let's get a bit deeper here and see what one of these peer-to-peer networks actually looks like.

05:44.540 --> 05:51.660
A peer-to-peer network is governed by peer-to-peer servers, and these are our gateways to millions of devices.

05:52.200 --> 05:59.820
These servers are imperative to this whole system working properly, and the reason for this is these servers actually orchestrate everything.

05:59.820 --> 06:05.640
They manage devices, and they also are what handle connections between users and their devices.

06:05.640 --> 06:09.400
You can basically think of these as command and control servers.

06:09.460 --> 06:15.680
There are hundreds of these on the internet because manufacturers will have dedicated servers for their own devices.

06:15.960 --> 06:25.120
It's very common to see these hosted on cloud providers like Alibaba and AWS, and they typically listen on UDP port 32100.

06:26.260 --> 06:34.700
Then, of course, you have devices, and these could be anything, but the common theme here is these will be 100% internet accessible.

06:34.940 --> 06:44.620
A very important concept here is that all of these devices will have a UID or a unique identifier, and if someone knows your UID, they can connect to your device.

06:44.620 --> 06:48.500
So this isn't something that you really want falling into the wrong hands.

06:48.680 --> 06:54.300
These UIDs are generated by the peer-to-peer providers and burned into the device during manufacturing.

06:54.300 --> 06:58.080
So if someone learns your UID, this isn't something you can change.

06:58.420 --> 07:00.420
Let's have a closer look at these.

07:00.680 --> 07:05.720
A UID has three separate parts, a prefix, a serial number, and a check code.

07:05.720 --> 07:15.180
The prefix is basically used for product grouping, and a single vendor may have several of these and their server will only respond to their own specific prefixes.

07:15.520 --> 07:20.760
The serial is simply the device identifier, and these are effectively just sequential numbers.

07:20.900 --> 07:23.800
And finally, the check code is a security feature.

07:23.800 --> 07:28.040
It's used to protect UIDs and also try to prevent device spoofing.

07:28.040 --> 07:32.540
A peer-to-peer server will reject any requests where the check code is not correct.

07:33.840 --> 07:36.000
And finally, there are clients.

07:36.000 --> 07:40.500
A client could be any desktop or mobile app for connecting to a device.

07:40.500 --> 07:45.740
It could be for viewing video, retrieving files, or even configuring an alarm system.

07:45.800 --> 07:52.760
But before a client can do any of that, the user needs to put in their UID so the client can make the connection.

07:54.410 --> 07:59.140
And under the hood, this whole thing runs on a fairly basic UDP protocol.

07:59.240 --> 08:07.300
There are control messages for setting up connections, and DRW or device read-write messages that actually wrap the application data.

08:07.500 --> 08:13.880
Messages are really just C structures with a 4-byte header, and a signature of this protocol is its magic number.

08:13.880 --> 08:18.700
The first byte of any peer-to-peer message will begin with hexadecimal F1.

08:18.700 --> 08:27.520
And thanks to debug information being left in, it was fairly easy to reverse this protocol, and I was actually able to create a Wireshark dissector for it.

08:28.140 --> 08:35.740
This was done using a plugin called Wireshark Generic Dissector, which lets you quickly write dissectors using a declarative language.

08:35.740 --> 08:44.120
I'll actually be releasing this today, so if you have any devices that use P2P, you can use this to get a little more insight into what's going on.

08:45.960 --> 08:48.960
So, with all that, we're finally at the crux of this.

08:48.960 --> 08:51.140
How does this connection actually happen?

08:51.140 --> 08:54.880
Or more importantly, how does peer-to-peer punch a hole through your firewall?

08:54.900 --> 08:59.480
As I mentioned, I was able to access this camera without forwarding any ports.

08:59.540 --> 09:02.480
The magic trick here really isn't magic at all.

09:02.620 --> 09:07.680
Peer-to-peer simply takes advantage of a particular behavior present in NAT and firewalls.

09:08.220 --> 09:12.980
UDP hole punching is a way to establish direct connections in the presence of NAT.

09:12.980 --> 09:22.840
For those unfamiliar with the terminology, NAT is just Network Address Translation, which is used by routers to forward traffic from the internet to the proper host on the LAN.

09:23.100 --> 09:30.240
The router does this by watching outbound packets and automatically creating inbound rules to correctly bring the response back in.

09:30.320 --> 09:36.120
The router needs to do this because if it didn't, we wouldn't be able to get responses back from our requests.

09:36.340 --> 09:40.600
But consider if two networks that are using NAT want to talk to each other.

09:40.600 --> 09:45.560
Any packet sent to the other is going to be dropped because no forwarding rules exist.

09:45.640 --> 09:47.760
So how can we get around this?

09:47.840 --> 09:51.680
Well, this is actually one of the main functions of the peer-to-peer servers.

09:51.820 --> 09:55.980
Both sides can use a peer-to-peer server to swap addresses with each other.

09:56.080 --> 10:00.020
And at that point, they can go ahead and send packets at each other.

10:00.020 --> 10:05.260
This will punch holes in their respective NATs and let traffic from the other side come through.

10:05.460 --> 10:12.520
In summary, just by sending UDP packets to each other, both sides can create a direct channel of communication.

10:13.820 --> 10:16.560
So this demonstrates how this works.

10:16.740 --> 10:22.760
When a connection request happens, the peer-to-peer servers will tell both sides the other's information.

10:22.760 --> 10:26.180
The device will send a packet to the client and vice versa.

10:26.180 --> 10:29.720
And even though these may not actually be delivered, that doesn't matter.

10:29.720 --> 10:32.320
The point here is just to open ports.

10:32.440 --> 10:36.520
After both sides have done this, then they should be able to talk to each other.

10:37.120 --> 10:41.120
But the problem with UDP hole punching is it doesn't always work.

10:41.200 --> 10:48.160
It usually works with most home networks, but it might not work in more complicated enterprise or mobile networks.

10:48.300 --> 10:57.380
For this situation, a client and a device can use what's called a relay server, which exists on the network specifically to help clients and devices make connections.

10:57.700 --> 11:02.720
As long as both sides can connect to the same relay, then it can proxy data between them.

11:03.720 --> 11:11.280
What's really fascinating is that some networks will actually use people's devices as extra relays for the network.

11:11.440 --> 11:17.480
And that means someone else's camera may very well be proxying your own video feed.

11:17.480 --> 11:22.460
These are called super devices, and this behavior is kept secret from users.

11:22.460 --> 11:26.300
They are never asked if they are okay with having their bandwidth donated.

11:26.300 --> 11:29.440
And if they have quotas, this could certainly cause a problem.

11:29.440 --> 11:33.660
And as sketchy as this sounds, this concept isn't actually unheard of.

11:33.660 --> 11:41.180
The more standard terminology for these is super nodes, and they're a relatively common occurrence in peer-to-peer software.

11:41.480 --> 11:46.920
Skype actually used to do this too, but at least people had the ability to opt out of that.

11:47.060 --> 11:49.560
Spoiler alert, we're going to have fun with these.

11:50.100 --> 11:54.840
Okay, so with the background out of the way, now we can start getting to the really good stuff.

11:54.940 --> 11:59.960
Since these networks are supporting millions of devices, is there anything we can do to hunt them down?

11:59.960 --> 12:04.260
And specifically, is there any way we can guess or generate UIDs?

12:05.040 --> 12:09.840
If we want to do this, the first step is going to be to find some peer-to-peer servers.

12:09.840 --> 12:14.540
Again, these are essentially gateways to devices, so finding them has a lot of value.

12:14.720 --> 12:21.460
I started doing this by looking at desktop and phone apps, as these are obviously going to be using a vendor's servers.

12:21.800 --> 12:26.100
However, this is a bit tedious, and there is a much more efficient way to do it.

12:26.100 --> 12:29.280
We can use NMAP's host detection to do this.

12:29.540 --> 12:35.640
The protocol has a simple hello message, and any valid peer-to-peer server will come back with an ACK message.

12:35.640 --> 12:43.340
So we can configure this probe and then run it against the entire IP space of a cloud provider like AWS or Alibaba.

12:43.820 --> 12:49.760
AWS in particular is very kind and provides an up-to-date listing of their current IP ranges.

12:50.060 --> 13:01.280
I've come across 618 peer-to-peer servers since 2018, and some basic fingerprinting has shown that 86% of these are CS2, and 14% are ILINK P2P.

13:02.460 --> 13:08.460
So next, if we want to use these servers to find devices, we're going to need to find out what prefixes they support.

13:08.460 --> 13:18.860
Like before, I started looking for these in apps and even Amazon reviews, because sometimes people will include their UIDs in their photos without realizing what they're doing.

13:19.060 --> 13:23.920
These two reviews have 11 different UIDs, and they're using three different prefixes.

13:24.560 --> 13:29.180
Sifting through these is also kind of tedious and quickly provides diminishing returns.

13:29.180 --> 13:31.020
So what is a better way?

13:31.360 --> 13:37.200
Well, when we try to connect to a device, the server will respond with an error code if the UID isn't valid.

13:37.200 --> 13:41.700
But that error code will change depending on if the prefix you asked for is valid.

13:41.740 --> 13:44.460
So I wrote a script to brute force prefixes.

13:44.460 --> 13:49.240
It continuously sends requests and saves any prefixes that appear to be valid.

13:49.240 --> 13:52.600
There's no rate limiting or checks to prevent this sort of thing.

13:52.600 --> 14:02.320
And depending on the latency between you and the server, you can find all three-letter prefixes in about an hour and all four-letter prefixes in about 36 hours.

14:02.460 --> 14:06.280
In total, I have found about 488 distinct prefixes.

14:06.460 --> 14:11.520
And while the average server hosts about four prefixes, there are a couple that have 130.

14:12.880 --> 14:17.620
So we're at a point where we've got servers and we know which prefixes they support.

14:17.620 --> 14:21.440
We can also predict serial numbers because they're just sequential numbers.

14:21.440 --> 14:27.760
If we want to find UIDs, the problem is now the check code, which exists precisely to stop this sort of thing.

14:28.160 --> 14:31.800
If the check code is off by even one letter, the UID will be rejected.

14:32.040 --> 14:33.520
These are five letters long.

14:33.520 --> 14:40.900
And while that's not an impossible key space to brute force, it's still enough to thwart any efforts to find a large number of devices quickly.

14:41.080 --> 14:43.100
So how can we get around this?

14:44.540 --> 14:47.760
Well, with ILinkP2P, luck would be in our favor.

14:47.760 --> 14:53.960
I found a variant of the ILinkP2P library that contained the algorithm they use to generate check codes.

14:54.180 --> 15:01.740
It basically hashes a few components using a modified MD5 and then puts together the letters from the hash to create the check code.

15:01.860 --> 15:12.460
This was apparently included in the library to do client-side UID validation, which is odd given the peer-to-peer server does this anyway, but someone thought it was a good idea to ship this.

15:12.520 --> 15:21.180
This is a big deal because we can now generate any valid ILinkUID, meaning we can now connect to any online ILink device.

15:21.440 --> 15:25.160
And with this ability, we can start to do some very interesting things.

15:25.160 --> 15:33.220
For one, we can now find out how many devices are online, but what would be even more interesting is finding out where these devices are.

15:33.320 --> 15:41.140
We can use a UID to get the IP address of a device, and using that, we can approximate its location using IP geolocation.

15:42.660 --> 15:45.800
So what you're seeing here is an enumeration script I wrote.

15:45.800 --> 15:52.280
It generates a UID, grabs its IP from the servers, and then looks it up using MaxMind's GeoLite database.

15:52.280 --> 15:55.180
This is going at 10,000 requests per minute.

15:56.300 --> 16:02.680
Taking this another step further, I was able to visualize this data with LeafletMarkerCluster and OpenStreetMap.

16:02.680 --> 16:13.120
Of the 3.6 million devices I've seen, Europe makes up about 21% of this, with France, Italy, Germany, and the United Kingdom all having over 100,000 devices.

16:13.120 --> 16:16.840
North America makes up about 8% of this total, with the U.S.

16:16.840 --> 16:23.040
seeing over 205,000 devices, and Canada and Mexico both having over 40,000 each.

16:26.280 --> 16:30.980
Finally, Asia is the most heavily impacted, with over 1.8 million devices.

16:31.100 --> 16:34.920
China and Thailand alone make up more than half of the entire dataset.

16:36.320 --> 16:43.200
Horrifyingly, lots of these devices use default passwords, meaning the UID is enough to gain full access to the camera.

16:43.200 --> 16:50.200
I disclosed this to Shenzhen Uni in early 2019, but despite multiple attempts, I never received a response back from them.

16:50.240 --> 16:55.220
And despite this vulnerability, I've continued to see an increase in the use of iLink P2P.

16:55.220 --> 16:59.620
In fact, thousands of new UIDs come online every single month.

16:59.760 --> 17:04.860
CS2 doesn't appear to be affected by this vulnerability, but that's not the end of the story.

17:06.060 --> 17:14.240
So now I have a way to directly connect to millions of cameras, but I'm not really interested in spying on people or talking through their cameras.

17:14.240 --> 17:17.360
That's creepy, and frankly, we're not in middle school here.

17:17.360 --> 17:19.500
What we really want is shells.

17:20.000 --> 17:22.640
So let's find some camera vulnerabilities.

17:22.960 --> 17:28.060
When planning for this, I really wanted to focus on a big vendor for maximum impact.

17:28.060 --> 17:33.320
Shenzhen High Chip Vision Technology is a major manufacturer in the IP camera industry.

17:33.700 --> 17:42.520
They caught my attention because as I was looking into different brands, I started to realize that a huge number of them were ultimately manufactured by HiChip.

17:42.520 --> 17:47.750
In fact, close to 3 million of the iLink devices I have found are using HiChip prefixes.

17:49.160 --> 17:57.360
This sort of practice is very common, where manufacturers will sell white-labeled equipment to vendors who then resell it with their own branding.

17:57.360 --> 18:02.160
This is a list of 50 different brands that are actually using HiChip under the hood.

18:02.160 --> 18:08.960
So given their ubiquity, any vulnerabilities in HiChip's firmware would be both widespread and very accessible.

18:11.260 --> 18:14.420
So to get started, I began analyzing their firmware.

18:14.420 --> 18:20.820
One function of interest was this read request method, which is used to handle any commands coming in over peer-to-peer.

18:20.820 --> 18:26.380
It even handles login, and we've got a 1024 byte buffer to read data off the wire.

18:26.680 --> 18:31.480
The message header has a field that says how big the payload is, so of course that's validated.

18:31.800 --> 18:34.680
To allow 10 times the size of the buffer.

18:34.680 --> 18:38.200
Okay, so we've clearly got a buffer overflow here.

18:38.200 --> 18:40.240
But how easy is it to exploit this?

18:40.240 --> 18:45.380
Because after all, there have been defenses to stop exploits like this for years.

18:45.760 --> 18:48.620
And the library doesn't seem to use any of them.

18:48.620 --> 18:56.060
So one very reliable ROP gadget later, and we've got ourselves a system call, and then a reverse shell with root privileges.

18:57.900 --> 19:00.060
Obviously, any vulnerability is bad.

19:00.060 --> 19:05.880
But the most devastating really tend to be those that are pre-auth, because any anonymous person can exploit them.

19:06.020 --> 19:09.420
In this case, as long as you have a UID, you can get a shell.

19:09.420 --> 19:12.160
And we now have all the UIDs.

19:13.060 --> 19:19.360
Once you get a shell, you can run binaries, you can browse the file system, and you can even access the camera's password.

19:19.560 --> 19:23.060
You can even directly invoke the camera's Wi-Fi utilities.

19:23.060 --> 19:25.340
And here's why this is a really bad thing.

19:25.460 --> 19:29.400
You can do a lot of really crazy things with base station MAC addresses.

19:29.400 --> 19:35.280
Google has an entire API that uses MAC addresses to perform disturbingly accurate geolocation.

19:35.420 --> 19:39.640
And the more information you give it, the more accurate the results are going to be.

19:39.640 --> 19:46.940
So once you get a shell, you can use it to scan for nearby Wi-Fi networks and potentially pinpoint the exact location of a camera.

19:47.220 --> 19:56.180
If you want to try this yourself, check out Google's geolocation API, feed it some MAC addresses of nearby wireless networks, and see just how accurate it can get.

19:56.180 --> 19:58.360
It costs literally pennies to do this.

19:59.880 --> 20:10.540
It's hard to say exactly how many devices are affected by this vulnerability, but given I found this bug in almost two years worth of firmware, I think it's a pretty safe bet to say that this could be weaponized.

20:10.540 --> 20:14.320
But thankfully, HiChip did release a patch for this in June 2020.

20:15.260 --> 20:17.880
I did find another vulnerability worth mentioning.

20:17.880 --> 20:21.440
It's not exploitable over P2P, but it's still pretty amusing.

20:21.660 --> 20:28.020
Up until recently, you could anonymously reset the password of any HiChip camera just by being on the same LAN.

20:28.020 --> 20:38.200
The reason for this is apparently some devices don't have physical reset switches, so instead you can just send a magic packet to the camera and it'll reset the password to admin.

20:38.260 --> 20:49.760
I'll be releasing a script for this, but I actually found out HiChip provided a tool to do this already, so I'm not sure if this qualifies as an exploit per se, but have fun with this.

20:51.060 --> 20:53.540
Okay, still got a few more tricks up my sleeve.

20:53.540 --> 20:55.780
Let's talk about man-in-the-middle attacks.

20:55.780 --> 21:01.800
When people hear man-in-the-middle attack, they might associate it with something that's restricted to the local network.

21:01.800 --> 21:04.420
Sniffing packets at a coffee shop, for example.

21:04.980 --> 21:11.880
Peer-to-peer should be pretty scary by now, but we haven't even talked about how it lets you intercept traffic over the internet.

21:12.380 --> 21:19.060
This comes from the fact that, as we now know, the peer-to-peer servers are responsible for coordinating all connections.

21:19.480 --> 21:23.080
Clients and devices obey the orders of the peer-to-peer servers.

21:23.080 --> 21:29.100
So, if we can influence that process in any way, we may be able to insert ourselves into a session.

21:29.340 --> 21:38.400
This is particularly scary because despite being a transport layer for the application, peer-to-peer doesn't actually perform any encryption or identity checks.

21:38.400 --> 21:44.580
These measures are left entirely up to the application, and as you can guess, most don't do a very good job of this.

21:44.800 --> 21:48.060
In fact, some even outright lie about it.

21:48.080 --> 21:59.460
This is a screenshot from VSTARCAM's app, which assures you that it is building an encrypted channel, but as you can see from the packet capture on the right, there is absolutely no encryption happening here.

22:00.860 --> 22:02.900
So, how do we get in the middle?

22:02.920 --> 22:07.520
Well, once per minute, a device is going to log into its peer-to-peer servers.

22:07.680 --> 22:12.400
This action tells the servers where the client needs to go when they request a connection.

22:12.560 --> 22:17.020
The problem is, this login message just contains the device UID.

22:17.020 --> 22:27.080
Absolutely no device-specific secret is used, which means if we have a UID, it's very easy for us to forge this login message and confuse the servers.

22:27.500 --> 22:35.160
And if our timing is right, when the client requests a session, the peer-to-peer server will tell them that we're the device.

22:35.240 --> 22:39.220
And at that point, the client will happily try to authenticate to us.

22:39.220 --> 22:41.360
And yes, that is Base64.

22:41.360 --> 22:43.200
It's always Base64.

22:43.660 --> 22:49.540
So, we have the password, and now we can turn around and connect back to the real device.

22:50.480 --> 22:54.520
This works with both CS2 and iLink P2P devices.

22:54.520 --> 22:58.800
CS2 did try to patch this problem, but it's pretty easy to circumvent.

22:58.800 --> 23:07.780
The login message is encrypted with what's called a CRC key, but a vendor's devices all use the same CRC key, so you can just grab it right from the firmware.

23:08.040 --> 23:16.480
And with some servers, you actually don't even need to go this far, because it will still let you log in with the old login message, so there's not much of a point.

23:16.480 --> 23:20.800
While this attack is certainly doable, there are a couple of drawbacks.

23:20.800 --> 23:29.500
You need to have a specific UID to target, you need to know knowledge of the protocol, and you actually need to wait for the person to try to connect.

23:29.740 --> 23:33.540
However, there is another attack that has none of these requirements.

23:33.680 --> 23:41.020
In fact, there is a way that someone with practically zero hacking experience can start owning handfuls of devices.

23:41.940 --> 23:44.340
Let's talk about super devices again.

23:44.340 --> 23:49.700
These are devices in people's homes that are proxying sessions for other users.

23:49.760 --> 23:56.140
A lot of vendors use these, so the chances of you buying a camera that will act as a super device is pretty high.

23:56.220 --> 23:59.960
And as I said, P2P doesn't actually perform any encryption.

24:00.180 --> 24:03.420
So what happens when a vendor's crypto sucks too?

24:03.820 --> 24:08.500
That means that anyone can buy a device and access other people's traffic with it.

24:08.500 --> 24:16.320
It means literally anyone on the planet can sniff your entire session and capture your password or your video without you ever knowing.

24:16.440 --> 24:23.280
There's no need to expend a ton of effort setting up a man-in-the-middle attack when this exists in the product by design.

24:23.940 --> 24:28.260
There are plenty of devices that don't even use encryption for sessions.

24:28.360 --> 24:34.660
A little PCAP parsing can give you a raw video stream that you can immediately watch with something like FFPlay.

24:34.660 --> 24:41.280
And all the while, users will have no way of knowing whether their connection is being intercepted like this.

24:41.280 --> 24:46.240
In fact, it's a risk that they're taking every single time that they connect to their device.

24:47.120 --> 24:53.420
As an added bonus, this has the side effect of leaking UIDs during the peer-to-peer handshake.

24:53.420 --> 24:59.880
So alternatively, you can just take the credentials which you also probably captured and connect back to the device yourself.

24:59.880 --> 25:05.700
I actually developed a proof of concept of this just to collect UIDs by posing as a super device.

25:05.700 --> 25:13.380
And by doing this, I was able to collect over 236,000 unique CS2 UIDs over the course of 10 months.

25:13.500 --> 25:20.580
So even though CS2's check code algorithm has yet to be cracked, this is a very reliable way for anyone to collect UIDs.

25:20.900 --> 25:25.880
The funny thing is, CS2 actually mentioned this exact concern in a marketing deck.

25:25.880 --> 25:32.140
They said a super device cannot spy on any data it relays because there is no API for this.

25:32.140 --> 25:33.680
But of course, that's insane.

25:33.680 --> 25:35.680
You don't need an API to pull this off.

25:35.700 --> 25:43.160
It's absolutely trivial to set up a camera and then leave Wireshark running to capture every single packet flowing through that device.

25:43.560 --> 25:45.760
So that's exactly what we're going to do.

25:45.760 --> 25:48.400
This bullet cam is running iLink P2P.

25:48.400 --> 25:55.460
So against my better judgment, I'm going to put this on the internet and we'll run Wireshark for a while and see what we come back to.

25:55.620 --> 26:01.720
Okay, so I left Wireshark running for a few hours and we can see that this camera has stayed pretty busy.

26:01.720 --> 26:06.360
I have the P2P dissector active so we can clearly see what it's been doing.

26:06.420 --> 26:13.320
Each of these hello messages is the peer-to-peer servers telling the camera to reach out and try to help someone with a session.

26:13.320 --> 26:17.360
So this will generate some handshaking with both the client and the device.

26:17.560 --> 26:26.340
Of particular interest is these relay packet messages, which will actually contain a UID of the device that we're trying to relay for.

26:26.620 --> 26:30.060
But we want to see some actual session traffic.

26:30.060 --> 26:34.890
We can locate this by filtering for message DRW messages.

26:35.400 --> 26:38.740
I'll go up here and apply that filter.

26:46.590 --> 26:49.430
Sure enough, looks like we've got some traffic here.

26:49.430 --> 26:56.210
If we actually pull up the resulting conversation here, well, that sure looks like Base64.

26:56.910 --> 26:58.380
If we copy that...

27:02.990 --> 27:05.690
Yep, nice secure password there.

27:06.210 --> 27:09.770
So there's some other information in plain text over here.

27:09.770 --> 27:18.630
We can see some information about the camera, the firmware version, and it looks like some other sort of name or identity information.

27:19.150 --> 27:20.510
But what about video?

27:20.810 --> 27:28.210
One of the ways that this DRW concept works is there are message indexes and message channels.

27:28.250 --> 27:31.730
And each channel is going to be used for a particular purpose.

27:31.730 --> 27:40.590
So in this case here, it looks like there's a lot of sort of authentication or negotiation going on on this channel zero.

27:40.590 --> 27:45.510
But on this channel two, we start to see binary data.

27:45.990 --> 27:58.850
So what I did here is I actually wrote a quick script that is going to take the data from this packet capture and just concatenate it together so we can pipe it into a video player.

27:58.850 --> 28:04.710
So what we're going to do is just go and export packet dissections as JSON.

28:04.710 --> 28:09.970
Call this export.json and make sure we hit packet bytes.

28:10.130 --> 28:11.530
Save this.

28:17.700 --> 28:25.660
And then we will go here and do node json2vid export.json.

28:25.660 --> 28:27.860
Pipe that right into ffplay.

28:28.820 --> 28:32.060
And we have some chickens, how about that?

28:33.340 --> 28:35.340
So final thoughts.

28:36.320 --> 28:44.520
I had a feeling things weren't going to be pretty when I started down this rabbit hole, but I never could have imagined some of these things.

28:44.740 --> 28:47.920
I've reported all of these problems to the vendors.

28:47.960 --> 28:55.980
Shenzhen Uni never did get back to me, and the number of devices using iLink P2P has steadily increased since I first reached out to them.

28:56.100 --> 29:03.660
I've tried to contact a lot of vendors in China over the past few years, and it's honestly pretty rare that I get a response at all.

29:03.860 --> 29:15.780
So I'd also really like to give credit where it's due here, because both CS2 Network and Hychip kept in close contact with me earlier this year, even as the COVID situation was first emerging in China.

29:16.240 --> 29:21.560
It was refreshing to see my concerns taken seriously, and especially during such a difficult time.

29:22.160 --> 29:29.320
The issues with CS2 are slated to be fixed in the next release, and Hychip just released patches for their problems in late June.

29:30.460 --> 29:35.080
With the warm and fuzzies over, uh, boy, things are not looking good.

29:35.180 --> 29:41.920
Even with patches on the way, I think it's safe to say that everything you just saw is going to be a problem for a long time.

29:41.920 --> 29:49.620
And this is because a lot of these peer-to-peer problems are outright architectural flaws, and they can't really be fixed retroactively.

29:50.100 --> 29:56.220
I think even if they could be fixed, it doesn't matter because most people don't update firmware anyway.

29:56.280 --> 30:00.060
I've seen some devices with firmware versions going back half a decade.

30:01.480 --> 30:09.420
In June of this year, I worked with the UK consumer watchdog group Witch to try to get some of the affected devices pulled off of shelves.

30:09.540 --> 30:14.120
Amazon, who sells more than 20 vulnerable brands, uh, didn't respond at all.

30:14.120 --> 30:21.080
And eBay said to use IP cameras without an internet connection, which isn't even possible with a good number of these.

30:21.080 --> 30:23.340
So, you know, thanks for that advice.

30:23.980 --> 30:30.060
Um, I do hope that this was inspiring to some of you, because I think there's a lot of opportunity here for further research.

30:30.080 --> 30:40.760
I think it's pretty clear that peer-to-peer is a pretty nasty vector, and I'm sure there's a lot more vulnerabilities in devices beyond what I've discovered on my own.

30:40.980 --> 30:45.280
I also haven't really had a chance to dig into other peer-to-peer platforms.

30:45.280 --> 30:51.440
For example, CalA, which is used by over 66 million devices, including Wyze cameras.

30:51.660 --> 30:56.200
And I know they use a similar paradigm where a UID will get you device access.

30:56.200 --> 30:58.740
So I think there's certainly opportunity there.

30:58.740 --> 31:04.960
And while I focus my efforts on HiChip, there are definitely other massive device manufacturers out there.

31:04.960 --> 31:13.960
In general, I encourage folks to climb up the supply chain a bit if you're looking for vulnerabilities that could be both widespread and potentially high impact.

31:14.960 --> 31:20.580
I'd like to leave you with a few reverse engineering tips that have led me to some major discoveries.

31:20.580 --> 31:26.820
First, if you're doing reversing, be sure to collect as many different samples and variants as you possibly can.

31:26.820 --> 31:30.960
Run diffs against them, look for abnormal changes in file sizes.

31:30.960 --> 31:35.760
Some may leave in debug symbols, extra logging, and alternate functionality.

31:35.760 --> 31:38.440
So those are all new avenues of exploration.

31:38.880 --> 31:43.240
Also, APKs are a great way to check out things with minimal effort.

31:43.240 --> 31:48.800
Java can decompile into beautiful, readable code that can very quickly reveal interesting things.

31:49.020 --> 31:55.300
And finally, and most importantly, throw every single interesting file name or magic string you find into GitHub.

31:55.300 --> 31:56.240
Seriously.

31:56.240 --> 32:01.380
It is incredible how many people push sensitive source code to public repositories.

32:01.600 --> 32:07.500
And this has helped me find everything from SDKs, to documentation, to full-on source repos for firmware.

32:08.380 --> 32:13.260
Finally, I'd like to give a shout out to the folks who published some of the initial research on peer-to-peer.

32:13.260 --> 32:17.260
Their work was really inspiring and key to the success of my own research.

32:17.260 --> 32:19.040
So cheers to you guys.

32:19.680 --> 32:21.160
And that's a wrap, my friends.

32:21.160 --> 32:22.960
Thank you all so much for coming.

32:22.960 --> 32:24.980
Happy hacking and be safe out there.

