Stealing closed YouTube videos one frame at a time



In December 2019, a few months after I started hacking the Google VRP program, I turned my attention to YouTube. I wanted to find a way to access private ( Private



) videos that I don't own.



When uploading a video to YouTube, you can choose one of three access options. Open ( Public



) allows anyone to find and view the video, Link Access ( Unlisted



) allows only users who know the video ID (URL Private



) to view the video , Restricted Access ( ) allows only you or other accounts that have been granted permission to view the video. for this permission.



The first thing I did was upload the video to my second test YouTube channel and toggle the video's access options to Private



so that I could use it for testing. (Remember that testing should always be done on those resources / accounts that you own!) If I can find a way to access the video from the first test account, then we will identify the presence of a bug.



I opened YouTube with my first account, checked every feature, and clicked on every button I could find. Every time I saw an HTTP request with a video ID, I replaced it with a test video with access Private



, hoping that some information about him would leak out, but did not succeed. It looks like the main YouTube website (at least all of its endpoints I've tested) always checks to see if the video is in a state Private



, and when it tries to query the target closed video, it always returns errors like This video is private!



.



I need to find another way.



In such a situation, an excellent solution may be to check other products / services that are not our main goal, but somehow interact internally with its resources. If they have access to site resources, then there is a possibility that they have not implemented all the protection levels that the main product has.



An interesting target that meets these requirements is Google Ads. This is a product that advertisers use to create ads across all Google services , including YouTube . That is, the ads you watch in front of the YouTube video are being customized by advertisers here on the Google Ads platform.



So, I registered a Google Ads account and created a new ad that should play the video to all YouTube users as a skippable ad. During the ad creation process, I also tried to use the target gated video ID all over the place, but without the slightest success.



After creating an ad, I started to explore the various features of Google Ads. It is a very large-scale product and has many different options and tools. I was trying to find anything related to YouTube.



On the platform, I found a page titled Videos



, where I saw a list of videos used for my advertising. Clicking on the video opens the analytics section ( Analytics



) of this video. In it I found a built-in player, statistics and an interesting function called Moments



. It allowed advertisers to β€œtag” specific moments in a video so that they could see when different things happened (for example, the timestamp of the moment the company logo appeared). To be honest, I didn't quite understand why advertisers use this feature, but it seemed interesting:





Looking at the proxy logs, I noticed that every time I β€œtagged a moment,” a POST



request was sent to the endpoint /GetThumbnails



. The body of this request contained the video ID:



POST /aw_video/_/rpc/VideoMomentService/GetThumbnails HTTP/1.1

Host: ads.google.com

User-Agent: Internet-Explorer-6

Cookie: []



__ar={"1":"kCTeqs1F4ME","2":"12240","3":"387719230"}






Where in the parameter the __ar



value 1



was the video ID and the value 2



was the moment time in milliseconds. As a response, a base64 encoded image was returned as a thumbnail used by the Ads platform.



I repeated what I had done many times already: I ​​replaced the ID in the request with the identifier of the closed video of the second account, and, to my surprise, I received a base64 image in response !



I googled "base64 to image" and pasted the base64 data into the first decoder I found. The image contains a thumbnail of the targeted private video ! It worked! I found a working IDOR bug (Insecure Direct Object Reference) , thanks to which I could get a frame from any YouTube video with limited access!



But I thought, "Hmm, this is just one shot." We can do better.



I wanted to write a Python script with a proof of concept that generates a real moving "video". Looking for information, I realized that if the video was recorded at 24 FPS, then one frame is on the screen for 33



milliseconds. That is, it is enough for me to download each image, starting with 0



and performing an increment by 33



, and then collect a kind of video from all the frames received.



I quickly wrote a POC that downloads frames for the first three seconds of a video, decodes them, and then generates a GIF. To test the code, I ran it with my old video, which I had previously restricted access to because I was ashamed of it:





So, using this bug, an attacker can download any closed video on YouTube, which, in my opinion, is a rather serious threat. But, of course, it has some limitations that I could not overcome:



  • In real life, you need to know the ID of the target video. A massive leak of them would be considered a bug in itself.
  • Since we only receive images, we cannot access the sound.
  • The resolution is very low (but it is enough to understand what is happening in the video).


It can be concluded that it is always worth paying attention to situations where two different products have internal interaction with each other, since the development teams of both products know their system better and may miss important details when working with the resources of another product.



Finding the likes of IDORs can be very monotonous and painstaking work, and now I try to avoid simple blind ID substitutions in the hope of the best. If you test the product for some time and understand its internal structure, it will be more effective (and more interesting) to try to think about various unexpected actions that the developers might not have thought about, or to focus on recently implemented features, or just do something that requires thoughtful actions. You may find it more enjoyable in the long run. In my opinion, the more you understand the system, the more ideas about hacking it naturally come to mind.



But even in the most reliable and thoroughly tested systems, there is a possibility that simply replacing the ID in the request will result in a critical bug.



How the situation developed



[Dec 11, 2019] -



Bug report sent [Dec 12, 2019] - Initial triage



[ Dec 20, 2019] - Bug accepted (P4 -> P1)



[Jan 08, 2020] - Steps taken to fix the bug with a temporary disabling the feature Moments







[Jan 17, 2020] - $ 5,000 reward issued



[??? ?? 2020] - the function Moments



is turned on again, now it checks for access to the video.






Advertising



VDSina offers VDS with daily payment, the ability to create your own server configuration in a couple of clicks, install any operating system. Each server is connected to an Internet channel of 500 Megabits and is protected from DDoS attacks for free!



Subscribe to our chat on Telegram .






All Articles