Saturday, December 29, 2012

XSS for Stealing Cookies and Mozzila for Using Them: article 201207

Takeaway: Using stored cross site scripting, XSS, a user's cookie can be stolen and used to bypass authentication to a website.  You need a vulnerable website, a script to steal the cookie, a server to write to, a script to write the cookie to a log, and an appendable log file.  Once you have the cookie you can utilize a Mozilla add on to use it.

My primary resource of information for this blog can be found at this YouTube video.

I have played with stored XSS before using the script message box to create a pop up:


and to read my own cookie:

but I decided today to take the opportunity to simulate actually stealing another users cookie. has posted a decent set of videos on YouTube from which I used as my guide to simulate this attack.

The first thing I needed was a vulnerable site.  I chose to use  Damn Vulnerable Web App.  Here is a link to a video showing how to install DVWA with XAMPP.  XAMPP can be downloaded here.

I changed the security setting of  DVWA to "Low".

The target of DVWA of course was XSS stored.  An issue I ran into was that the Messages text box only allowed for a maximum of 50 characters; too few to pull this simulation off.

To resolves this I navigated to:


and modified the index.php script, in my case line 49, from

    maxlength=\"50\" to maxlength=\"500\"

Next, two files needed to be created.  First a blank file named cookielogs.txt and a second file named stealer.php that receives the cookie and appends it to the cookielogs.txt file.  The code for stealer.php is:

I uploaded these two files to a personal website.

A third piece to this is the malicious script to post to the guest book; it is seen here:

Next it was time to post my script to the DVWA vulnerable guest book:

The next user that came along and clicked on the XSS stored link

Would have the cookie stolen and shipped off to my cookielogs.txt text file:

We have a cookie!  Now what?  Consume that cookie!

There is an add-on for the Mozilla browser titled cookie editor.  It is a tool that will let you view your cookies and, as the name says; edit them.

Once the editor is installed it can be found under the Tools menu of the browser.

Now as the attacker I browsed to the cookielogs.txt file and selected the cookie I wanted to try.  In the case the one at the bottom of the list.

I then browsed to the DVWA login page.

I opened the cookie editor

Notice in the above pic the IP address of the site I am visiting and next to each IP are the cookie names "PHPSESSID" and "security".  Notice back on the cookielogs.txt file that each of those are defined. So I edited these to match the cookie I had captured.  First the PHPSESSID.  Highlight then select edit.

Then replace the "Content" string with the string captured:

Click save and then repeat for the "security" cookie:

Here I changed it from "high" to "low", just as I had captured.  I then clicked "Save"

I clicked "Close"

Now back the web page I removed the "login.php" from the URL address:

I hit my keyboards "Enter" key and "Boom goes the dynamite". 

I was able to get to the log in screen without credentials.

As always I hope this helps others.  Please provide any feedback and I will be happy to answer any pertinent questions that I can.


Wednesday, December 5, 2012

Screen Scraper in Python: article 201206

As part of the SecurityTube Python Scripting Expert course the below is a simple script written to scrape the Top X suspect IP addresses from SANS Internet Storm Center.

Written in Python 2.7.2, Beautiful Soup 4, and LXML parser


import urllib
import re
import sys
from bs4 import BeautifulSoup
print "\n\n"
print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
print """
        The following list of IP's is pulled from
        the SANS Internet Storm Center.  It shows
        a list of up to the top 100 IP's from which
        suspected malicous traffic was seen. It is
        not recommended to use this as a black list.
print "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"

topX = int(raw_input("Enter the Top X amount, btw 1 & 100, of flagged IP's you want to see: "))

while ((topX < 1) or (topX > 100)):
        print "The ammount must be a number btw 1 & 100\n"
        topX = int(raw_input("Enter the Top X amount, btw 1 & 100, of flagged IP's you want to see: "))

print "\nPlease be patient\n"
print "Retrieving the top ", topX , " IPs\n"

iscPage = urllib.urlopen("")

#print iscPage.code

iscSoup = BeautifulSoup(, "lxml")

allAtag = iscSoup.find_all('a')

counter = 0

for item in allAtag:
        if ('ipinfo', str(item)) and (counter < topX)):
                        print item.string
                        counter = counter + 1
print "\n"

Sunday, November 11, 2012

tshark and airmon-ng to capture SSID broadcasts: article 201205

Take aways: 
Your chip set must be able to drop into monitor mode.
Command to enable monitor mode: airmon-ng start
Command to determine available link-layer header types: tshark -i -I -L

At the time of this writing I am taking a class developed and presented by Vivek Ramachandran titled SecurityTube Python Scripting Expert.  A project in the class is to use write a program that will capture SSID broadcasts.  To capture informaiton at this level you must place your NIC into monitor mode.  As to why, the Wireshark Wiki provides great information and instructions.

It took some, reading, some fiddling, and I still have questions for myself, such as why am I not seeing all SSID's but below is how I was finally able to see SSID broadcasts.

The card I am using is a D-Link USB wifi card purchase many years back

I am running Backtrack BT5R1 as a VM on a Windows 7 host using VM Workstation 9.

Running the command:

    airmon-ng check

shows what processes are running and a note is provided that it could cause trouble.  To kill the process I choose to use the command:


Next to put the card in monitor mode I ran the airmon-ng start command:

    airmon-ng start

Notice in the above image that monitor mode is enabled on "mon0" not "wlan0"

Next comes tshark to capture SSID's.  I recommend reading the Wireshark Wiki link at the beginning of this post. First is the command to see what link-layer headers are available:

    tshark -i -I -L 
    tshark -i -L

The "-I" switch stands for monitor mode.  This is something I need to research further because based on wiki I thought I had to use it but when I did I received error messages which I will show in a screen shot below.

First here are what the commands provided me:

And now to capture SSID broadcasts, at least the one that worked for me:

    tshark -i -y IEEE802_11_RADIO

I am not sure if I am in true "monitor" mode because when I use the "-I" switch I get the following.  Which was frustrating because I just stumbled on to the fact that I could see SSID's without it.

Also of interest when I run this in my VM I only see the one SSID. When I run this another laptop with Backtrack5 R3 and it's built in NIC I see more SSID's but not all the ones that I know are in my area. You can see there are a few more in the background of the picture of my D-Link USB NIC; but even this isn't all of them.

Any suggestions, advice, or answers would be much appreciated!

Any way.... It is a good start for and now to get back to my Python scripting!


Thursday, August 16, 2012

My Experience Building a MiniPwner: article 201204

Takeaways: Cookbook to building your own minipwner
This model of router I  used:
Using firmware from OpenWrt:

First, thanks to folks at for putting together a step by step how to on building ones own minipwner! Also thanks to the many folks of the project!

Perhaps you have heard of the minipwner or the similar Pwnie Express teams pwn plugs.  If not then in a brief statement know that these are devices that allow remote access to a network via wireless connectivity.  From a pentester's or attacker's point of view they are a small, easy to disguise, effective means to infiltrate a network.  These devices can be loaded with tools that once one connects to a network can be used for reconnaissance and attack. Examples of this can be read about here:

MintyPwner - pwner in an Altoids tin box

Wired Article interview with Jayson Street

My Experience With the Build

Let me make it clear I used the step by step instructions from MiniPwner web site.  But as is typical with technology I ran into a few nuances with my build.  Below will be excerpts from the MINIPWNER site but I have made modifications based on what I experienced.

I purchased my router from a local computer store for around $40.  I went with the TP-Link TL-MR3020 because that is what they had in stock.

I used version 1.7 of the the device.  At the time of this writing OpenWrt did note that their firmware worked with this version of the router but had not signed off on the upgrade of its firmware via the the web interface of the router; however it did work just fine.

For my USB I used a 4GB Cruzer.

The files I used were:
MiniPwner Files :  these are configuration files created by the MiniPwner team.
OpenWrt SquashFS factory bin file  : this is the base firmware from  OpenWrt.
OpenWrt SquashFS sysupgrade file : this is the upgrade to the base firmware file. I had many issues my first go around with the project and ended up installing this to fix those issues.  My second build of the MiniPwner I upgraded the firmware as soon as I was able to connect to the OpenWrt version of the router and the remainder of the project went without incident.

I have these stored on my website to help maintain consistency with this write up.

I also used  Backtrack 5 R2 as my OS for this project.  This is a standalone install not a VM.

The below steps will written with the above described environment in mind.

Alright, let's step into it.

Working from Backtrack 5 R2 with an internet connection.

1. Download the files I have linked to above.  Again, these files reside on my website's server they are not links to the original authors' websites.  I did this to help maintain consistency with the files I will be working with.  I downloaded the files into my /root/home directory.  Use GParted to create the partitions on the USB Stick.

2. You will need to partition a USB drive so that it has a swap space partition and an EXT4 partition.  I will be creating a separate detailed write up on how to do this with Backtrack 5 R2.  From a command prompt within Backtrack type the command apt-get install gparted.

3. Insert the USB drive into the TP-Link router.

4. Plug the TP-Link router into a power source.

5. Connect the TP-Link router to the computer running Backtrack via an ethernet cable.  Determine if you if you acquired an IP address. I used ifconfig from the command line. I did not acquire one so used dhclient eth0 to retrieve and IP.

6. The IP of the TP-Link router is  This can be confirmed by typing the command route -n from the command line in Bactrack. This particular router is in English so the interface is different from the that shown at If it prompts for a username and password try admin and admin 

 7.  On the left hand side of the page click System Tools which will drop down a  menu then click Firmware Upgrade.
 8.  Click the browse button and navigate to the openwrt-ar71xx-generic-tl-mr3020-v1-squashfs-factory.bin file.

Click the upgrade button.  The status bar will go through to 100% TWICE and then it will reboot.
You will, of course, lose connectivity to the device.

Video capture of the end of the upgrade process

9.  Now that this process is complete Backtrack NIC has to have a new IP addressed assigned.  Sticking close to the MiniPwner instructions apply by using the command line and typing the command:
ifconfig eth0 netmask

10. Now connectivity to the router should be established.  This can be tested by telnetting to the router.  From the command line type: 

Leave this window open.

11. The next task is to upgrade the firmware.  As mentioned earlier this alleviated many issues that occurred with my first MiniPwner install.  In Backtrack open a new command prompt and navigate to the directory containing the openwrt-ar71xx-generic-tl-mr3020-v1-squashfs-sysupgrade.bin file. Then at the command prompt type:
nc -l -p 3333 < openwrt-ar71xx-generic-tl-mr3020-v1-squashfs-sysupgrade.bin
Hit the Enter key on the keyboard.
Return to the OpenWrt telnet session window and type:
cd /tmp
then type the command
nc 3333 > sysupgrade.bin
Wait for about 10 seconds then hit ctrl+C to cancel.  If successful an ls command should the appropriate sized file.  See the picture below for an example of what this should look like.
12. No to perform the upgrade; from the telnet session type the following command:
sysupgrade sysupgrade.bin
Hit enter, and wait for the system router to reboot.

Here is a video capture of my experience.

13.  Once the router reboots, telnet back into the router from a command line Backtrack:

From here on out you should be good to go with the remainder of the instructions from the site except there is one command in step 19 that does not apply to this build:

cp -f /etc/config/fstab /etc/config/fstab.orig

There is not fstab in the /etc directory of this version of the TP-Link router.  So the rest of the instructions I have just copied and pasted from

Have fun, good luck, and check their forums if you run into issues.  They helped me tremendously.

  1. *** If you mess up anything after this point, enter the command "firstboot" into your telnet session, reboot, and you will be right back here.***
  2. If you aren't good with vi for editing, consider doing "opkg install nano" to get a more friendly editor.
  3. Copy and paste the following commands into your telnet session.

cd /usr/share
nc 3333 > minipwner.tar
  1. It will hang up while transfering the tar archive from the PC. (netcat doesn't know that the file transfer is done) Wait 10 seconds then go to the command prompt window on the PC and Ctrl-C to break the connection
  2. Paste this command into your telnet session:

tar -xf minipwner.tar
  1. Paste these commands into your telnet session:

cd /usr/share/minipwner
cp -f /etc/config/network /etc/config/network.orig
cp -f /etc/config/wireless /etc/config/wireless.orig
cp -f /etc/config/firewall /etc/config/firewall.orig
cp -f /etc/profile /etc/profile.orig
cp -f /etc/config/fstab /etc/config/fstab.orig
cp -f /etc/opkg.conf /etc/opkg.conf.orig
cp -f /etc/config/system /etc/config/system.orig
cp -f /etc/config/dhcp /etc/config/dhcp.orig
cp -f ./network.1 /etc/config/network
cp -f ./wireless.1 /etc/config/wireless
cp -f firewall.1 /etc/config/firewall
cat /etc/config/wireless.orig
  1. Your original /etc/config/wireless file contents should have been displayed on the screen. Copy the MAC address of your wireless adapter from the screen.
  2. Edit etc/config/wireless using

vi /etc/config/wireless

Delete the bad MAC address (cursor to it and use x to delete) then paste in the copied MAC (i to insert then paste). Then change the Wifi settings to connect to your wireless router (by default tries to connect to SSID "TOKI". Shift-ZZ to save and exit. :q! to exit without saving.
  1. Paste these commands into your telnet session:

/etc/init.d/network restart
  1. Type
ifconfig wlan0
to check that your wireless settings came up. If you don't have a DHCP assigned address you'll need to troubleshoot your settings.
  1. If your internet connection works you should be able to run "opkg update" and see that it connects and updates packages.
Some people have challenges at this step. One common problem is that their wireless network is in the range 192.168.1.x, which is the same range as eth0. See the forum for options if this is your problem (simple fix is to change the IP range of your wireless network)
  1. Paste these commands into your telnet session:

cd /usr/share/minipwner
opkg update
opkg install kernel
opkg install kmod-usb-storage
opkg install kmod-fs-ext4
opkg install block-mount
cp -f profile.1 /etc/profile
cp -f fstab.1 /etc/config/fstab
cp -f opkg.conf.1 /etc/opkg.conf
cp -f system.1 /etc/config/system
mkdir /mnt/usb
/etc/init.d/fstab enable
/etc/init.d/fstab start
ls /mnt/usb
  1. Check that your USB drive mounted. "mount" or "df" commands should show it. If not, you'll need to troubleshoot USB access.
  2. Paste these commands into your telnet session:

cd /usr/share/minipwner
ln -s /mnt/usb /opt
ln -s /etc /mnt/usb/etc
opkg update
opkg install netcat
opkg -dest usb install tar
opkg -dest usb install openssh-sftp-client
opkg -dest usb install nmap
opkg -dest usb install tcpdump
opkg -dest usb install aircrack-ng
opkg -dest usb install kismet-client
opkg -dest usb install kismet-server
opkg -dest usb install perl
opkg -dest usb install openvpn
opkg -dest usb install dsniff
opkg -dest usb install nbtscan
opkg -dest usb install snort
opkg -dest usb install karma
opkg -dest usb install samba36-client
opkg -dest usb install elinks
opkg -dest usb install yafc
cp -f ./network.2 /etc/config/network
cp -f ./wireless.2 /etc/config/wireless
cp -f ./dhcp.2 /etc/config/dhcp
ln -s /mnt/usb/usr/share/nmap /usr/share/nmap
cat /etc/config/wireless.orig
  1. Your original /etc/config/wireless file contents should have been displayed on the screen. Copy the MAC address of your wireless adapter from the screen.
  2. Edit etc/config/wireless using

vi etc/config/wireless

Delete the bad MAC address (cursor to it and use x to delete) then paste in the copied MAC (i to insert then paste). Shift-ZZ to save and exit. :q! to exit without saving.
  1. Type passwd to set a root password.
  2. Reboot. The default configuration for the minipwner is acting as a wireless access point with an SSID of TLINK and a router IP of, and running DHCP on the ethernet port.
  3. If things get hosed up, see the "rebuilding" section of the FAQ for instructions on using fail-safe mode to rebuild your router.
  4. If you want to install other packages to the USB key, do opkg -dest usb install .  I have had problems where installed libraries, modules, or other resources are not found because they are not in the "normal" place.  In a lot of cases you can kinda fix this by creating a symlink, similar to the one above for "

ln -s /mnt/usb/usr/share/nmap /usr/share/nmap"


Thursday, June 7, 2012

De-Obfuscation of a Phishing Attack: article 201203

The other day I received a phishing email masquerading as a message from LinkedIn.  It stated I had just changed my email address and needed to confirm.  I decided to practice my analysis skills.  Below is what I found.

I will start with a basic comparison of a phishing email with a legit one.  Then I will dig into the malicious link and show what I was able to discover.

Luck was on my side.  A coworker of mine happened to just have changed his LinkedIn email address and was able to provide me with a legitimate notification from LinkedIn to use as a comparison.

Here is a screen shot of the legitimate LinkedIn email received by my coworker:

And here is a screen shot of the Phishing email I received.

As you see very similar.  What threw flags for me were:
1. I had not changed my email address at LinkedIn ( My first thought was that my account had been hacked).
2. I don't use my work email on my LinkedIn account. (So I probably was not hacked).
3. The To: field was not me. (I have it redacted here)
4. It states that if the link does not work "copy and paste the below link into a browser".  There is not link to copy and paste.
5.  Looking at the destination of the "Click here" showed it did NOT point back to LinkedIn.

So a comparison of the properties of the "Click here" links showed that the legitimate link pointed to:


This link matched to one provided to paste into my browser.

The malicious link pointed to:

For good measure I also looked at the header information of the too emails:

Here is the header from the legitimate email:

Received: from (###.###.###.###) by XXXX.XXXX.XXXX.LOCAL
 (###.###.###.###) with XXXX id #.#.#; Thu, 31 May 2012
 10:40:48 -0500
X-WSS-ID: 0M4W8U8-01-0BJ-01
X-TMWD-Spam-Summary: TS=20120531153944; ID=1; SEV=2.4.2; DFV=B2012041615; IFV=NA; AIF=B2012041615; RPD=5.07.0001; ENG=NA; RPDID=dfssd; CAT=NONE; CON=NONE; SIG=AAABAKR1FwAAAAAAAAAAAEASBgoAAAE=
X-TMWD-IP-Reputation: SIP=###.###.###.###; IPRID=7469643D303030312E30413032303330322E34464337393046452E30313230; CTCLS=R6; CAT=Unknown
Received: from ( [###.###.###.###]) by (XXXX) with SMTP id 21D6B1180D5 for
 ; Thu, 31 May 2012 10:39:43 -0500 (CDT)
Received: from ([]) by ([###.###.###.###]) with SMTP; Thu, 31 May 2012 10:40:47
DomainKey-Signature: q=dns; a=rsa-sha1; c=nofws;
DKIM-Signature: v=1; a=rsa-sha1;; s=proddkim; c=relaxed/relaxed;
q=dns/txt;; t=1338478846;
Date: Thu, 31 May 2012 15:40:46 +0000
From: LinkedIn Email Confirmation
To: "XXXX"
Message-ID: <>
Subject: Please confirm your email address
MIME-Version: 1.0
Content-Type: multipart/alternative;
X-LinkedIn-Template: email_confirm
X-LinkedIn-Class: ACCT-ADMIN
X-LinkedIn-fbl: s-X39FxNh3lf7HEqL8X9_80bUZR57bEdA8X5_vfPnalJZ_JzpDowC5Eq
X-pstn-levels: (S:99.90000/99.90000 CV:99.9000 FC:95.5390 LC:95.5390 R:95.9108 P:95.9108 M:95.5423 C:98.6951 )
X-pstn-dkim: 1 skipped:not-enabled
X-pstn-status: off

Here is the header from the phishing email:

Received: from (###.###.###.###) by XXXX.XXXX.local
 (###.###.###.###) with XXXX Server id #.#.#.#; Fri, 1 Jun 2012
 07:52:43 -0500
X-WSS-ID: 0M4XVPZ-01-6FI-01
X-TMWD-Spam-Summary: TS=20120601125135; ID=1; SEV=2.4.2; DFV=B2012041615; IFV=NA; AIF=B2012041615; RPD=5.07.0001; ENG=NA; RPDID=ygyuguy; CAT=NONE; CON=NONE; SIG=AAABAKR1FwAAAAAAAAAAAEASBg0AAAI=
X-TMWD-IP-Reputation: SIP=###.###.###.###; IPRID=7469643D303030312E30413032303330322E34464338423935422E30303741; CTCLS=R5; CAT=Unknown
Received: from ( [###.###.###.###]) by (XXXXX) with SMTP id 2C14B1180D9; Fri,  1
 Jun 2012 07:51:33 -0500 (CDT)
Received-SPF: none ( does not designate permitted sender hosts) client-ip=;
Received: from Khalid-PC ([]) by
 ([###.###.###.###]) with SMTP; Fri, 01 Jun 2012 05:52:38 PDT
Received: from ([]) by; Fri, 1 Jun 2012 11:52:38 +0500
Date: Fri, 1 Jun 2012 11:52:38 +0500
From: LinkedIn Email Confirmation
To: emailXXX
Message-ID: <>
Subject: Please confirm your email address
MIME-Version: 1.0
Content-Type: multipart/alternative;
X-LinkedIn-Template: email_confirm
X-LinkedIn-Class: ACCT-ADMIN
X-OriginalArrivalTime: Fri, 1 Jun 2012 11:52:38 +0500 FILETIME=[372CCC03:A54BD8E6]
X-pstn-neptune: 500/438/0.88/100
X-pstn-levels: (S:55.09949/99.90000 CV:99.9000 FC:95.5390 LC:95.5390 R:95.9108 P:95.9108 M:95.5423 C:98.6951 )
X-pstn-dkim: 0 skipped:not-enabled
X-pstn-status: off

As you can see, they are quite different, along with some more red flags that I placed in bold text.

So what does that hxxp:// look like?  I used the tool WGET in my BackTrack VM to pull the file down locally.

Here is a screen shot of the page:

Notice in the bottom of the browser Firefox prevented a script from running.  So next I decided to peek at the web page's source.  Which showed this:

Notice in the web page's source  a script tag is seen.  It reads as one long line so I copied it out into a text editor and formatted it to be a little more reader friendly. This is what I came up with:
The above code is javascript.  And at a quick review it appeared that there was simple obfuscation implemented.   The following is what I made of the code:

By the way obfuscation (the result of obfuscating) as defined by by merriam-webster is to be evasive, unclear, or confusing.

I am not a javascript programmer so I was not familiar with the "Try / Catch" statements.  I referred to to get me up to speed.  w3schools explains try...catch as:

 "The try...catch statement allows you to test a block of code for errors. The try block contains the code to be run, and the catch block contains the code to be executed if an error occurs."

I was also not familiar with the appendChild() method. This is explained by w3schools as a method that appends a node to the last child of a node.  Here are w3schools examples.  However; in this code, appendChild() purposefully has nothing to do with execution.

Obfuscation Examples

The attacker purposefully inserts incorrect code in the the "try" block so that the code in the in the "catch" block will be executed.  In the first "try" block "q" is not defined and so passes on to "catch".  In the second "try" block the string prototype is not defined and so the code in the second "catch" block is executed.

Also note in the above code the "catch" functions contain parameters:

The first:  "catch(qw)"
The second: "catch(b43gds)"

These appear to only be further measures of obfuscation.

Another attempt at obfuscation is that the attacker is assigning and appending variables all over the place. This is just a further attempt to make it a bit challenging to follow.

The first example is very simple. "h" is declared and assigned the value "-012/5" up on the"catch" block then used in the "for" loop later.

There are also multiple other examples of variables being assigned then either appended to or concatenated together and using multiple further techniques to obfuscate the codes final output.

Notice the variable "f" in the below screenshot:

1. "f" is being assigned a concatenated string of fromCh
2. then "f" is being appended to with the characters "arC", so now "f" stands for "fromCharC"
3. Finally "f" is being appended to one more time, among more obfuscation. This little line is using what is known as a conditional operator "?" which in layman's terms reads 

(test a condition) ? :

In this case:
-  "append to f", (which so far is "fromCharC")
-   Test to see if "h" exists and "zz" exists.  They do exist as we see at the top of the code h=-012/5 and just two lines up with "zz" being assigned to more obfuscated code.
- ? is the conditional operator.
- If h" and "zz" exists append the letters "ode" to "fromCharC"
- : is the break between "do if true else do if false"
- then finally if "h" and "zz" did not exists then append nothing as seen as ""

So now we see that "f" is a variable housing the phrase "fromCharCode".
f = fromCharCode

But notice we see "f" one more time just two more lines down in the code:


So what is going on here?  Before I answer that I want to step back and mention what substr is doing and discover what the "zz" is.

Referring back again to w3schools they give a concise and effective explanation of the "string" object, its properties, and methods. I have substr pointed out in the image below.

A simplified example of substr would be:

x = "example";  
y = x.substr(2);
Printing out "y" would show ample

So if "y" was printed out it would read "ample" because in the string "example" e is in the 0's place, x in the 1's, a in the 2's in the 3's etc... So y=x.substr(2) basically says take the characters starting at the 2's position and assign them to y.

Hopefully substr is understood so lets look at what is going on with its use in the obfuscated code.

1. "zz" is being assigned the concatenated characters "a+l", so "zz" is "al".
2. There is a little obfuscation in this line.  That attacker is assigning "zz" a new value by using the substr method on the string "zv".  The attacker then appends the current value of zz ("al") to that.  Notice in the line there is (123-122); this is simply a mathematical operation which means the same thing as (1). This means the string could be simplified (de-obfuscated) as all of the following mean the same thing:


Based on what we know about substr "zv" in this case has "z" in the 0's place and "v" in the 1's. What is happening here is that the attacker is stripping off the z and appending the letter "v" to "al".  All that now makes "zz" assigned "val" 

zz = val

3. Now we know:

f = fromCharCode
z = val

Next I will break down some of the line "e=w[f.substr(11)+zz]". These all mean the same thing:


Working our substr with "f" in the 0's place, "r" in the 1's etc we determine that the 11's place character is "e"; the last character of the string "fromCharCode".  The line then appends that "e" to "val". Now have the word "eval"!  


What is the significance of "eval"? It is a javascript global function, and again, more info from w3schools; if the argument for the eval() function is a javascript statement, eval() executes that statement!

Now about that  "w" in front of the brackets...

1. "this", is a javascript keyword that took me a bit of time to understand, but thanks to an article at Digital Web Magazine it finally has clicked, (or flickered).  The "this" keyword localizes execution context to a particular scope in javascript code.  (I am merely regurgitating Digital Web's article, if you want to understand "this" better then read their article by Mike West who did a great write up)  The attacker has not assigned the "this" keyword to any context nor any object. In this case, Mike West states in his article; the ""this" defaults to reference the most global thing it can: for web pages, this is the "window" object. It is within this object the eval() function will be used.

2. Here the variable "e" is being assigned.  De-obfusctating the line may make it a little more clear.  All of the following perform the same action:


Unfortunately I am unable to determine why the [ ... ] are working in place of the " . ".  I assumed them to be reserved for arrays.  If anybody reading this can help me out please contact me.

3. Finally we see the variable "e" (which is literally the function "eval()") being used to call the command housed by the  variable "ss"

Now I want to show what the SS variable is housing, but first I want to step back and clear up some more obfuscated code of the mathematical variety.

Starting back near the top of the code we have seen that:

Typical math would have "h" looking like this:
h = -2.4

But the code is not declaring this to be a floating point integer.  Javascript defaults the number to just be an integer so we lose the ".4" and we are left with:

h = -2
We will visit the "h" variable again in just a bit but next I want to tackle the "for" loop.

1.  Traditionally a "for" loop is written something like:

for( i=0; i < 10; i++)
      print i

The  code in the malicious script is similar if one just does the math.  

Starting with "i ="

6-2-1-2-1 = 0

so this could be written as

i = 0

Then moving to -645+i != 2-2 we clean this up a bit and find it looks like this (by the way != means not equal to)

-645+i != 0

cleaning up some more we could write this as

i < 645

and at the end we have the standard i++

So the entire initiation of the "for" loop could be written as

for(i=0; i < 645; i++)

2. Next there is a simple assignment of k = i.  In this case there is not a need for this.  We could just stick with "i"

3. Here we see "k" again which was assigned to "i" above, but as mentioned we could do without the "k" and just place "i" here.  With these few changes the code begins easier to understand as the above could be written as:

for(i=0; i < 645; i++)

Next I want clean up that line of code in the "for" loop. The first stop is the "h" variable I wrote about above.  

h = -2

So the line can be written as:


Continuing to clean up that part of formula we see:

-1 * 4 * -2

Since this is multiplication the two negatives cancel each other out so this can also be written as:

1 * 4 * 2

Now notice the 1 is pointless since:

1 * 4 * 2 = 8 

4 * 2 = 8

This shows that the 


can be written as:


Now taking a look inside the next set of parenthesis I use mathematical precedence to help clean this up.  


Multiplication happens before addition.  Above we see that 1 is being multiplied by "n[i]" (I will get to what is going on with "n[i]" in just a moment). 1 multiplied by any number will equal that number; so will remove it too.  With this;




Now stepping back we see that:




Next I move a bit to the left and see that a simple concatenation is occurring:

["from" + "CharCode"]

This can be written as:


So with that change notice the line of code that started as:


can be written as:


and again with the square brackets... so actually the code will work if written as


Now I want to address the "fromCharCode" and again I refer to w3schools. fromCharCode() is a method of the "string" object in javascript that converts Unicode values into in characters.  For example "65" is unicode for "A".

x = string.fromCharCode(65);

Now if I printed out "x" I would see "A"

Earlier in this write up I had a screen shot of the entire malicious javascript but after that I have been using screen shots with a chunk of the code missing.  The code that was missing was a an array of numbers that are fed into the "for" loop I just presented.  When the formula is run it creates a unicode value that is then converted into a character.

Here is the entire code set again:

1. Here the "ss" is being declared as an empty array that is to be filled in during the "for" loop.  Then the array is called again at the end of the program.

2. "n" is declared here as an array and is filled with numbers that will be fed into the "for" loop formula as part of the creation of the unicode value.  

I want revisit the line of code in the "for" loop. I am going to use the line that I presented as de-obfuscated to make understanding what is going on a little more simple.  I will start with a bit on arrays and for loops. Here is just an example of an array

x = [ "dog", "cat", "bird"]  is an array of animals.  Similar to the "string" position the array has positions too. In this case "dog" is in position 0, "cat" is in position 1 and "bird" is in position 2. I now present a sample loop that would print these out. (NOTE this code is not completely accurate I just want to get the idea of what is happening).

x = [ "dog", "cat", "bird"] 

for(i=0; i < 2; i++)
    print x[i];

As the array loops through it is read as:

print x[0] which prints "dog" from the "x" array in position 0 because at this time i = 0. 

next "i++" increments "i" from 0 to 1 so the next pass through the loop is

print x[1] which prints "cat".   "i++" increments again and now "i" becomes 2

print x[2] which prints "bird". Now when "i" is incremented again it is 3, which is greater than 2 so the loop exits.

Hopefully this lays a foundation of understanding for how the "n" array and the "for" loop in the malicious script works.

2. The blue box in the above image encompasses the entire array of "n".  I am just going to look at the first few items of the array to demonstrate what exactly is happening with it and the "for" loop.

The array starts out

n = [-3.875, -3.875, 8.125, 7.75 ..... ]

As we have seen the "n" array is addressed in the "for" loop


Now it is time to explain "n[i]" as I promised earlier.  As I have just pointed out in the for loop example, "n" is the array name and at this time it is calling for the item in the "0" position; which is -3.875.  So the array at this time now is read as


Breaking it down we start with:

 5 + (-3.875) = 1.125

8 * 1.125 = 9

Now the string at this iteration of the "for" is the same as this:


Recall this line is taking 9 as a unicode value and converting it to a character value.  The character value for 9 unicode is an empty space.  Check out Uncle Jim's Web Designs for a handy tool to convert unicode to characters

The next object in the "n" array is also -3.875. So it too becomes 9 unicode and thus represents an empty space character.

The third object in the "n" array is 8.125 plugging it in looks like this:


and this formula gives us:

ss=ss+String.fromCharCode(8*(5+(8.125))) = 105 

105 unicode converts to the character "i"

The fourth object is 7.75 and plugging it in:


Gives us the unicode value:

ss=ss+String.fromCharCode(8*(5+(7.75))) = 102

With that we have:

"9,9,105,102" unicode

This converts to

"  if" character

So far see that:

 ss = [  if]

This next image shows what we get if we iterate through the entire loop. Now we see what the entire "ss[]" array contains:

This is a little hard to read so I will clear it up with some formatting in the next image.

The above images show that unicode was converted into further javascript. This code consists of an "if / else" statement and a "function" the attacker wrote and named "iframer".

1.  The if statement starts by calling the "document object's" "getElementsByTagName()" function.  w3schools describes this method but I also found a nice explanation at  What this is looking for is the "body" 
tag in the html document.  In my experience there is most always a "body" tag as it is part of the basic HTML4 page structure. You can right click and view the source of this page to see an example or just peek at my quick mock up here.

If the "body" tag is found then function "iframer" is called.

2. If the "body" tag is not found then the document object's write() method is used to create an iframe.  The write() method writes HTML or javascript code to a document; as explained at w3schools.  More about what this iframe code is doing is described in part 3.

3. This is the iframer() function.  It's purpose to is create an iframe 10 x 10 in pixel size.  However the frame is hidden so this will operate in the background, and, as the attacker hopes, go undetected.  Most importantly notice what web page address the iframe is going to load; a Russian domain web page at he site.

A search at Google's "Safe Browsing Diagnostic Page"  Helps confirm suspicions that this site has in the recent past housed malicious code.

Now I know what is loaded in the variable "ss".  I also know what is loaded in the variable "e".  So one more visit to the malicious code shows what comes next, which hopefully by now is obvious.

1. This is the command to execute the code that will create the invisible iframes. Thus calling the malicious website and possibly downloading malware to the victim's computer.


Could be interpreted as:

There you have it!  

If there is something in this write up that I am mis-communicating, corrections that need to be made, or any other feedback please let me know.