RTSP… Real Time Streaming Protocol… is a protocol largely ignored these days. Once the infrastructure relied upon in the early days of multimedia (Video) and developed by RealNetworks, RTSP resides largely in the background of common protocols we pay attention to as InfoSec professionals these days.
Typically found on port 554, RTSP is still a factor in network and network exposures. Why? Because many (if not most) of the commercial IP cameras out there still utilize RTSP as a mechanism for streaming their video feeds.
Why hack RTSP credentials? To get good naked pictures? Well, maybe, but from this auditor’s experience, the credentials used by RTSP on a lot of cameras (defaults and otherwise) often are the same as the credentials to access the device itself, whether through a telnet, ssh or web interface. If not the actual credentials they are often similar to (e.g., change the username to root, admin, etc and use the same password) So what? Well, think about it… Most IP camera systems out there are basically “little” computers with video cameras. In fact most IP camera systems out there are some “Busybox” linux system, albeit resource constrained. Also consider that in a lot (if not most) cases the deployment of IP cameras is not singular – meaning there are many “little” computers with video cameras running around in the environment you are targeting.
Now what could a “bad guy” do with: a) a lot of little computers (with video) b) the system credentials to all these little computers c) access to the internal network by/with all these little computers? I would dare say a LOT!
While you may want to hack IP cameras for naked pictures, serious auditors and “bad guys” will want to look at them as nice, hidden, understated pivot points in an attack.
Let’s now look at how we can brute force RTSP. First and foremost RTSP is an HTTP like protocol. It has different structure and control commands but is textual in its format and once you learn the basics of the commands and how they interact, fairly easy to use. The specification for RTSP is pretty straightforward. Here is a link to it:
RTSP can be accessed unauthenticated (common in off-the-shelf devices) or authenticated. Authenticated access mirrors HTTP in that you have Basic and Digest authentication, both nearly identical to HTTP. To find out whether your device is authenticated or unauthenticated, simply send a “DESCRIBE” request. A simple DESCRIBE request looks like:
DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2\r\n\r\n
Note: the additional “\r\n” is required for reliable response. Some systems will accept the single “\r\n” but most won’t.
This can be sent down a raw socket. Just like HTTP, a successful response indicating unauthenticated access is available will contain a “200 OK”. In this case with DESCRIBE, it will also contain all of the operational parameters of the video feed.
If the device requires authentication, the the response back will contain “401 Unauthorized”. The response will also indicate what authentication mechanisms are available. If Basic authentication is available the response string will contain an information line that has “WWW-Authenticate: Basic”. The rest of the information provide with Basic authentication is largely irrelevant to actually conduct basic authentication.
If Digest authentication is required, then the “401 Unauthorized” response will have an information line containing “WWW-Authenticate: Digest”. The information with the Digest specification IS very important if you are going to do Digest authentication, so don’t ignore it.
Basic authentication is the way to go, hopefully the response received indicates that it is available. If not there are three different methods to assemble a Digest authentication element, so Digest can become troublesome, especially blind (unauthenticated). The rest of this article will stick with Basic authentication. I may write a follow-up article later once I decipher the secret sauce to doing Digest authentication blind.
To formulate a Basic authentication element, one simple has to base 64 encode <username> “:” <password> and add it to the request. So a new request would look like:
DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2\r\nAuthorization: Basic YWRtaW46MTIzNA==\r\n\r\n
Again note the request is terminated with the double “\r\n”.
The value YWRtaW46MTIzNA== is the base 64 encoded username and password concatenated with “:”. In this case I have used “admin”/”1234”. Some simple python scripting to try this out looks like:
req = "DESCRIBE rtsp://<ip>:<port> RTSP/1.0\r\nCSeq: 2\r\nAuthorization: Basic YWRtaW46MTIzNA==\r\n\r\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data = s.recv
Voila! You have access.
But to actually brute force 1000, 100,000, 1,000,000 combinations is a little more difficult. Fortunately for you, I have written a nice little python script, rtsp_authgrind.py, that will efficiently do this for you. For more details and usage you can check out our “Labs” post here:
Or directly here on GitHub. The Labs post tells you a bit more about it and usage, as well as future plans.