Welcome back to the next part of our blog series. If you haven’t checked out the earlier posts yet, I suggest giving a read to the first post. In that part, we talked about how we picked our target, got the firmware from the camera, and got into the shell.

After installing the firmware version 1.0.5-0185 on the camera, we started with the reconnaissance phase, a crucial step in understanding our target. The aim here is to gather information about the target and identify potential vulnerabilities. This data not only gives us a snapshot of the target’s weak points but is also handy when crafting a strategy for the attack.

Now, let’s get started by discovering all the services the camera has exposed, shall we?

Service Discovery

Using nmap we were able to list all the TCP services that the IP camera exposes:

We ran a similar command to detect all the accessible UDP ports, but unfortunately, none could be identified.

Let’s now take a look at all the exposed ports identified as open by nmap:

  • Ports 80/443 host the web management interface that can be used to manage the camera settings.
  • Port 554 exposes the Real-Time Streaming Protocol (RTSP). This is a protocol that provides access to the video stream of the camera.
  • Port 49152 reveals the Universal Plug and Play (UPnP) service, facilitating seamless discovery and communication among devices on the network.

Now, let’s conduct a brief analysis of the identified services.

Ports 80/443/tcp

Authentication

The web server requires authentication for most of the exposed URLs. In the next blog post we’ll take a close look at how the web server checks and approves or rejects the incoming HTTP requests.

Password Change Command Injection

As mentioned in the previous blog post, the password for the synodebug user is updated whenever we change the password for the camera web interface user, using the same password for both users. You may have also noticed in a screenshot from the first part of this blog series that the used function appends both the username and the provided password to a shell command without any validation. This allows for command injection.

To validate our assumption, we can change the user’s password through the web interface and insert the command injection payload into both the new password and confirm password textboxes. For instance, we used the following command injection payload to create a file named file123 inside the tmp folder:

First let us verify that no files with name file123 exist in the tmp directory:

Upon altering the password using the command injection payload shown above, the file file123 was indeed generated by the root user:

Great! Now that we’ve confirmed the command injection vulnerability, it’s important to note that this endpoint requires authentication. While we’ve uncovered similar command injection vulnerabilities in other endpoints, it’s noteworthy that all of them require authentication.

WebDAV

Surprisingly, we discovered that WebDAV (Web Distributed Authoring and Versioning) is enabled on the web server. This service is usually used for collaborative editing and management of files over the web.

After running some tests, we discovered a few misconfigurations. We found that the web server let WebDAV modification actions to happen on specific paths without needing a login. However, because the camera file system was mounted as read-only, these modifications were blocked by the operating system.

But here’s the interesting part about the DELETE action – when we used it on the root path (/), it deleted all files on the SD card linked to the camera. Why? Because that was the only writable file system, and a reference to the SD card folder was present in the web server’s root directory.

Sadly, we couldn’t remove any configuration files that might have let us reset the user’s credentials and access the management interface. This might seem like a Denial of Service (DoS) vulnerability, but it doesn’t really help in the Pwn2Own competition.

Port 554/tcp

The Real-Time Streaming Protocol (RTSP) is a protocol for creating and managing time-synchronized streams for multimedia communications.

The OPTIONS response (shown in blue in the screenshot below) displays a list of the available commands supported by the service:

When attempting to connect to the RTSP protocol without valid credentials, an unauthorized error is triggered, prompting the user to provide valid credentials through HTTP Digest authentication. This is shown in the following image:

Port 49152/tcp

Universal Plug and Play (UPnP) is a service often found in IoT devices, simplifying network setup. Essentially, devices supporting the UPnP passive discovery method protocol periodically share their services on the network through NOTIFY messages that are sent to the multicast address 239.255.255.250 on UDP port 1900. These messages usually include a URL pointing to an XML file that describes the device’s UPnP profile. Here’s an example of a NOTIFY message sent by the camera:

The camera tells us that the XML description file is available at port 49152, accessible through the /device_desc.xml path. Unfortunately, the XML description file doesn’t offer much information about additional services:

We didn’t discover any notable weaknesses in the exposed service that could be combined with the vulnerabilities we’ve identified thus far to execute commands arbitrarily on the camera.

However, during our investigation, we encountered a curious behavior in the server’s response headers. The " character must be present an even number of times in HTTP headers. If not, the request pauses for 30 seconds before ultimately resulting in a 400 error:

An even number of " characters, results in a proper response in 29 milliseconds.

This behavior appears to be independent of where the " characters are positioned. For instance, in this request, the same behavior is observed with 3 " characters placed in 3 different headers:

After reverse engineering the systemd binary, responsible for handling incoming UPnP requests, we found that the root cause of this delay lies in the code responsible for string detection in the received request. In short, when the code encounters the initial " character, it continues reading characters until it hits the closing ", failing to identify the end of the request. It’s worth noting that, despite this issue, we found no vulnerabilities that could be leveraged to manipulate the binary’s execution flow.

Hidden Service!

So, after going through all the services identified by nmap, our next move was to dig into the services exposed internally. We executed netstat as the root user to get a more comprehensive perspective on all active network connections and listening services.

The Netstat output revealed an additional UDP port that was not detected by Nmap. This discrepancy could be caused by the usage of a custom protocol or the service never sending a response.

We decompiled the webd binary to find the code responsible for handling these UDP packets. After extracting values from the incoming packet, the code checks whether the Custom.Activated option is enabled and jumps to the function r0x00030d5c if it is not:

The mentioned code is responsible for updating the network information of the camera:

Unfortunately, the camera we are targeting is expected to have already been activated. As a result, this service doesn’t appear to offer many exploitable functionalities.

Additional Discovery

During the reconnaissance phase, we discovered from the documentation that the camera can be integrated with the Surveillance Station software, allowing centralized management of Synology cameras across one or multiple offices. Intrigued by this, we went ahead and purchased the Synology NAS DS233, setting up a mock office scenario where the IP camera is linked to the Surveillance Station running on the NAS.

During our analysis, we found that the Surveillance Station software supports both plaintext HTTP and encrypted HTTPS connections. Because of the IP camera’s self-signed certificate, it allowed for potential man-in-the-middle attacks using tools like Burp, as the Surveillance Station would trust the self-signed certificate or prompt the user to trust it. For simplicity, we chose to establish the connection using the plaintext HTTP protocol and monitored the traffic using Wireshark.

The Wireshark traffic revealed a peculiar behavior: every HTTP request is sent twice:

  • The first HTTP request sends the user’s credentials using the HTTP basic authentication method. However, the process running on the camera returns a 401 HTTP error code because it does not support HTTP basic authentication.
  • Subsequently, a second HTTP request is sent using HTTP digest authentication. In this case, the request is successfully processed by the process running on the camera.

By intercepting the first HTTP request, it becomes possible to steal the cleartext credentials of the web user:

As described in RFC 7617, the characters following the Basic string in the displayed HTTP header represent a base64-encoded form of the following string: <username>:<password>. In the intercepted traffic, the password of the web user is Password.1:

By combining this issue with the command injection vulnerability in the password change functionality, it is possible to perform remote code execution starting as anonymous users in a man-in-the-middle scenario inside a network where the Synology NAS is configured. However, our goal is to identify a weakness exploitable by anonymous users without any specific setup. Therefore, we continued our exploration for other potential vulnerabilities.

What’s Next?

We’ve gained a better understanding of the camera’s exposed services and what they can do. In the next blog post, we dive deep into the analysis of the web server as it exposes most of the available functionalities, making it an interesting area for exploration.

Articles in this series: