I have been running across malware like this lately.
It appears to be a local infection that appends some VBScript to HTML files on
the webmaster's computer, spreading to the Internet when it's uploaded.
Alternatively, it could be an infection on a Windows IIS server.
At any rate, WriteData is a hex string that goes on and on for a good couple of screen lengths, followed by some more VBScript to open a file handle, write binary data to it, then execute the dropped binary.
Since it appears this HTML file has been infected multiple times, I use uniq to get only one copy of the WriteData line. I split it with cut based on the double quotes to get only the hexadecimal part. I decided I'd try to use xxd to decode it. xxd can create or read hex dumps. I save xxd's output to svchost.exe (which is what the VBScript would have called it).
Finally, I use file to determine what kind of file svchost.exe is, presuming it'll be a Windows executable file.
No surprises there. I uploaded it to VirusTotal, and it looks like we have a ZBot (ZeuS) on our hands.
OpenBSD 5.3 was released on May 1. (I told you I'm running behind!)
There are many enhancements and changes, including some much-needed tweaking to dhclient, making it a little less frustrating to use. While updating the nginx/MySQL/PHP-FPM how-to, I noticed that nginx is now defined in rc.conf like Apache has been for quite a while, so the setup procedure changed ever so slightly. The Apache/MySQL/PHP how-to remains basically unchanged, and it'll continue to be maintained so long as Apache is available in either the base distribution or from ports/packages.
Yes, I know, I'm running way behind, aren't I?
The thing is, authorization to your web-based accounts isn't why we recommend using an unprivileged account for your daily computing use.
On Windows, OS X and most popular desktop distributions of Linux, the first account that's created has administrator-level access. Increasingly, privilege escalation tools such as sudo, UAC and keychain access have made it to where you have to authenticate in order to make dramatic changes to the system (such as install drivers) but this protection can often be disabled or wholly bypassed.
In any case, an administrator-level account on a computer can not only install drivers and software, but may unwittingly allow malware to set its hooks deep into the operating system. It's for this reason that people recommend setting up another user-level account without privileges to install software.
As for protecting your sensitive data inside that user-level account, full-disk encryption is the way to go. This feature ships standard (although it is disabled by default) with OS X, many popular Linux distribution, and even the premium and enterprise versions of Windows. FDE has its flaws, but it's better than nothing.
Why bother decoding this stuff? Because encoded within this mess is
another URL. Depending on the source of the obfuscated code it may be a
link to a page full of exploit payloads or something similarly sinister.
Unwrapping the layers of malware allows researchers to find out where
the bad guys are actually hosting their stuff, and helps us identify
providers who are willing to help with or at least turn a blind eye to
cybercrime operations.
Lately, I've become more determined to handle javascript de-obfuscation outside the browser. Over the last year or so, I've been experimenting with a bunch of techniques to make sense of blocks of code that look like this:
I think it goes without saying that this looks like a monumental pain in the ass. The truth is, it's not as bad as it appears, but I didn't say it was going to be easy.
First, the basics. In JavaScript, FromCharCode() turns a decimal number between 0 and 255 into its ASCII character counterpart. You've all seen the ASCII table, right? Same thing.
I found a way to use printf in most shells to create a similar behavior, and I called this function "chr". So let's start really simple. Here's a file containing a message encoded with CharCodes, and a quick way to decode it. It simply reads each number in (by replacing , with a space and using a for loop, then prints each character one at a time.
This is the basis for the rest of what we're about to do. Let's break down that obfuscated javascript:
The yellow highlighted area is a bunch of numbers separated by the letter w. This is stored in an array labeled "f". If you look after the yellow, you can see that the code uses the letter w to split it.
The blue highlighted area is the loop that handles decoding the numbers into characters. This is obfuscated code, so by definition they've made it a bit confusing, but the end result is that they keep appending each character to the end of the "s" variable.
The bulk of the conversion of number to charcode (ascii decimal number of the character to be rendered) is here: (w[j]*1+41)
This gets us to the essence of the article: You'll need to use some brain power. The first thing I do is turn the data block into a string of comma-separated numbers so they're easier to work with, and I put these in their own file, like so. You can do this inside a text editor with search/replace, or on the CLI if you like.
Then you need to figure out the math. In our example code, what is w? what is j? You'll probably run into a bunch of bizarre variable reassignment when trying to make sense of obfuscated code like this. Looking above, you can see between the yellow and blue blocks, w=f. So w is now a copy of that array full of numbers. Inside the blue block of code, you can see that j=i. So, w[j] points to the current number in the array. But this number isn't the CharCode. There's still the "*1+41" part to deal with. Manually, we can see what's going on here. This is a very simple algorithm. The first 3 numbers are -32,-32,64.
-32*1+41 = -32+41= 9 - CharCode 9 is a tab.
64*1+41 = 64+41 = 105 - CharCode 105 is a lowercase "i"
Doing this manually would suck. The algorithm here is obvious. The CharCode is the number, plus 41. That's it. Let's decode it with my script:
So what happened here? This is the source of my relatively simple script.
#!/bin/sh
# Obfuscated JS Decoder
# Ax0n - 2013-03-22
# ax0n@h-i-r.net
#
if [ -z "$1" ]
then
echo "$0 codefile algorithm"
echo "c = placeholder for each number"
echo "i = iterator"
exit 1
fi
chr() {
# http://mywiki.wooledge.org/BashFAQ/071
# Turns a charcode into the ASCII byte
printf \\$(printf '%03o' $1)
}
count=0
file=$1
shift
algo="$*"
for code in `cat $file | tr "," " " `;
do
chr `echo "$algo" | \
sed -e s/"i"/"$count"/g -e s/"c"/"$code"/g | \
bc | cut -f1 -d\.` | tr -d "\r"
count=`expr $count + 1`
done
echo
echo "----- done ----"
At the heart of the above script is a nifty function I found in the Bash FAQ. And then, I used a pair of sed expressions to replace the "i" and "c" placeholders within the loop that handles the output. We call on the "bc" command-line calculator to work all the math magic. tr -d "\r" fixes some broken newlines found in some of the samples I decoded. Let's see it in action:
Now, let's look at the one in the video. It has a much more complicated algorithm than simply adding 41 to each digit before converting it to the ASCII byte! It's hard to read in the video, so here it is:
Fortunately, this one already separates the codes with commas, so we can pretty much just copy and paste the numbers into a text file for decoding. As you can see on the 3rd-to-last line, the algorithm it uses for each character is this:
((w[j]*1+e(x+3)+11))
Let's tear into it, shall we?
w[j] starts out just like the last example. We can see they set j=i and w is a copy of the array, so for each iteration, this is the digit. We can replace this with "c" in our algorithm expression.
That leaves us to figure out what e and x are. Also like the last example, e is set to "eval" at the end of the second line. We'll ignore it. Let's look for x= in the code.
There it is! j% - and remember, j = i, so it's the iterator. % is a mathematical modulus operator. -- that is, it divides two numbers and the output is the remainder. Example: 17 divided by 4 is 4 with a remainder of 1.
$ echo "17 % 4" | bc
1
(x+3) becomes essentially, (i % +3) and +3 just means "positive 3" in this context. We don't even need the +.
((w[j]*1+e(x+3)+11)) becomes ((c * 1 + ( i % 3 ) + 11)) or simply "c + ( i % 3 ) + 11"
When I first installed OpenBSD to my netbook, I had tried several ways to get the ISO written to a USB stick including unetbootin, using dd to directly write the image to USB, and a few other tricks. The Googles showed me a workable yet rather complicated way to do it, but that sounded like a pain in the butt. I didn't have an external USB optical drive, but I had the hardware to hack one up. This is really how I did that first OpenBSD install:
Earlier, I had actually installed OpenBSD to a USB stick, and run the whole system directly from USB, including a swap partition, logs going to /var and the whole nine yards. OpenBSD's gratuitous logging and swap utilization killed that USB stick in a matter of months after daily use, but the thought hit me to use that same method here. By default, the bsd.rd package is installed to the root filesystem to use in a recovery situation. This is an initial ramdisk, a bare-bones userland with just enough tools to install or rescue a system. So that's what we're going to do. The TL;DR goes something like this:
Boot a desktop from the boot CD
Insert the USB stick you wish to use
Choose "Install" from the CD's menu.
Format the USB stick, and install OpenBSD to it. If it's a 4GB stick or larger, the default partitioning scheme will work great. Otherwise, make one root partition without swap. Install only the base, bsd, bsd.rd and etc packages.
After install, re-mount the cd and copy the install files to the root partition.
Create an etc/boot.conf file on the USB stick (mounted to /mnt) with "bsd.rd" as the first and only line.
Shut down the system. The USB stick will now boot on most servers and netbooks lacking optical drives, and will go directly to the installer. All the OpenBSD install packages will be right there on the USB stick.
Here's the walk-through.
I booted up the system, and after the installer menu popped up, I plugged in my USB stick. I did this to make it obvious what its device id is. You can tell it's sd0 in this image. Adjust accordingly. At the menu, I chose "I".
You can see I'm choosing sd0 here. Again, use the right device, or you may damage important filesystems.
I just rolled with the default partition sizes here. The install files are a little over 100 megs, so they'll fit in the root partition. If you're an avid OpenBSD user, feel free to mess with the disk options here, but the defaults work well on a 4GB stick (the smallest I had laying around).
When the time comes to install sets, the only ones you really need to get an installation environment up are bsd, bsd.rd, baseXX.tgz and etcXX.tgz (where XX is the release number) - I had an official OpenBSD 5.1 install set at my desk, so I used it for this example. The numbers will change for each release, but the process works the same.
When the installer exits, it will un-mount the CD. You'll want to re-mount it to copy the install sets to USB. Also note that I set mnt/etc/boot.conf to "bsd.rd" - This forces the USB stick to boot directly to the installer ramdisk, so you'll be ready to go!
To test, I put the USB stick into my netbook and fired it up.
nginx (see also
nginx(8))
has been added to OpenBSD, ultimately to replace the Apache 1.3 derived
httpd(8).
For new installations, you are encouraged to utilize nginx rather than
httpd, existing installations are encouraged to start planning replacing
the stock httpd with nginx.
With Apache 1.3 being awfully long in the tooth, most of us saw something like this coming. With that, there's a new walk-through that covers the basic configuration of nginx, MySQL and php-fpm to create a working, secure and chroot-enabled web application environment in OpenBSD 5.2.
HiR is what happens when 1990s-era e-Zine writers decide to form a blog. Most of us hail from the Great Plains region of the United States.
Ax0n, HiR founder and editor-in-chief is an information security specialist currently working in the luxury goods industry.
Asmodian X joined HiR in December 1997 and currently works as a web developer and SysAdmin in the education industry.
Frogman has been on board since May 1998 and has many technical passions. When not experimenting with obscure hardware, he can be found leaping from one rooftop to the next, making the world his office.
TMiB has also been helping since 1998. Also our resident Physicist and go-to guy for xkcd jokes we don't get, The Man in Black currently works in the Internet industry in an east-coast data center.