flash security past_present_future_final_en
DESCRIPTION
sTRANSCRIPT
McAfee/RIM Confidential
Flash Security:
The Past, Present, and Future
Haifei Li, security researcher
Syscan360, December 2012
Who is this guy?
• Security geek focusing on application-level vulnerability finding & exploitation.
• Involved in Chinese security community 2005-2008, known as id “cocoruder”. Got an idea?
Who is this guy? (cont.)
• Started my paid days at Huawei security lab
• Grew up with Fortinet (5 years)
• Worked for Microsoft
• Now a member at McAfee Labs with awesome friends
• Living in Vancouver, Canada – the most beautiful place on
earth • Find me if you plan to visit there!
Change: My view on VR
• Difficulty of finding vulns -- • Fuzzing technique/framwork is more mature • Software has become more complex
• more features = more vulns • Fuzzing machine (PC, server) is cheaper.
• Motivation • We have a lot of reward programs (ZDI,
iDefense, Google, etc)! • Security companies like to invest in finding
bugs for marketing strategy, or, (ideally) for
better detection in products.
Change: My view on VR
• Difficulty of exploiting vulns ++ • ASLR + DEP, the “evil” brothers. • Sandbox is armed in more apps. • Everything now is random (unpredictable)
• Exploiters (not only asian) love “predictability”.
• Motivation • We don’t have a reward program for
innovative exploitation techniques. • We can’t just pay researchers conf travel to
get new exploitation techniques. :P
Change: My view on VR
• Common exploitation tech has already died
• Application-specific exploitation is taking the place • Understanding the architecture better than
architects • Understanding the implementation details
better than developers
• Be specific!
Agenda
Flash JIT and Mitigations
Flash ActionScript 3 Architecture
3
2
4 Case Study: Digging Vulnerability Root Cause with Tamarin Source Code
5 Thoughts for Future Flash Security
A Review of Flash Threats 1
History
• Flash Player has a fairly bad record for security.
The History
• This is the search I did in March 2011, for my CanSecWest presentation.
• 269 - 147 = 122 vulns added in 20 months.
History
• Can be tracked as early as year 2002
Flash Zero Days
• A never-ending story
CVE-2011-0627 CVE-2011-2107 CVE-2011-2110 CVE-2011-2444 CVE-2012-0767 CVE-2012-0779 CVE-2012-1535
CVE-2009-1862 CVE-2010-1297 CVE-2010-2884 CVE-2010-3654 CVE-2011-0609 CVE-2011-0611 CVE-2011-0618*
*According to a research paper, CVE-2011-0618 was not detected at that time. It was actually a zero-day vulnerability.
Evolution: Flash-based Exploitation
• Breaking AS verifier by AS3_argmask overwriting, Mark Dowd, April, 2008 • Important as it shows the implementation details of
ActionScript/AVM. • fixed
• ActionScript heapSpray, used in exploits at least early 2009 • Common heap spraying trick • still available
Evolution: Flash-based Exploitation (cont.)
• JIT Spraying, Dion Blazakis, Feb 2010 • significant common exploitation technique • fixed (discussed later)
• AS3 type confusion exploitation, Haifei Li, March 2011 • vulnerability class specific, only used for type confusion
vulns • still available
• AS3 Native API info-leak, Fermin J. Serna, April 2012 • highly vulnerability specific
Agenda
Flash JIT and Mitigations
Flash ActionScript 3 Architecture
3
2
4 Case Study: Digging Vulnerability Root Cause with Tamarin Source Code
5 Thoughts for Future Flash Security
A Review of Flash Threats 1
Flash Player Architecture
AVM2
AS3 Internals
AVM1 (legacy)
Embedded Resources In Tag: fonts, pic, video, etc.
Networking
flash.net.* flash.net.drm
Display
flash.display.*
flash.display3D.*
Media
flash.media.*
Events flash.events.*
Legacy AVM1 runs independently
AS3 Execution Stream
mov dword ptr [ebp-14], 2BC5732 ; 0x02BC5732 is the
mov eax, dword ptr [edi] ; Atom of “aaaaaaaa”
..
push edi
call eax ; call to “flash!trace()”
Adobe Flash Professional Adobe Flash Builder
ActionScript 3 Source Code
SWF File (Bytecode)
AVM 2 (NanoJIT)
When executing SWF file
trace (“aaaaaaaa”);
findpropstric <q>[public]::trace
pushstring “aaaaaaaa”
callpropvoid <q>[public]::trace, 1 params
.text:1021AFF1 flash_trace proc near ; DATA XREF: .rdata:10695420
.text:1021AFF1 arg_4 = dword ptr 8
.text:1021AFF1 arg_8 = dword ptr 0Ch
AS3 Internals on Flash Player
In Simple Words
AVM2 + AS3 Native APIs = Flash
• AVM2 is open-sourced as Tamarin project. It’s just a language interpreter.
• AS3 Native APIs implement real features of Flash Player. It’s closed source. • Could be a challenge to review all the APIs.
Agenda
Flash JIT and Mitigations
Flash ActionScript 3 Architecture
3
2
4 Case Study: Digging Vulnerability Root Cause with Tamarin Source Code
5 Thoughts for Future Flash Security
A Review of Flash Threats 1
JIT Spray / Fengshui
• First disclosed by Dion Blazakis in February 2010, BlackHat DC.
• 03396E6A (normal) vs 03396E6B (shellcode)
JIT Spray / Fengshui
But, how would you know you are jumping to 03396E6B,
not 03396E6A ?
JIT Spray / Fengshui
JIT Spray / Fengshui
• Facts: • mem_header has fixed length (0x14). • Padding can be NULL when address is
divisible by 4. • JIT function length is controlled (via controlling
number of bytecode in AS function). • JIT allocation is continuous in memory
following back-forward order.
• Conclusion: • By spraying (or “fengshui”) crafted functions in
the JIT pages, everything is predictable. • Not just for “JIT spraying Xor attacks”.
JIT Spray / Fengshui
…
JIT func_N
block_header
JIT func_3
block_header
JIT func_2
block_header
block_header
JIT func_1 Ending of a JIT page
Memory address grows
JIT function allocated from the end to the beginning of the page
JIT Harden
• Feature introduced as early as October 2010.
JIT Harden
• Related source code:
JIT Harden
• But was enabled in released Flash Player in November 2011, from Flash Player 11.1.102.55.
• Setting the config flags “harden_nop_insertion” and
“harden_function_alignment” to true. else if (!VMPI_strcmp(arg, "-jitharden")) { settings.njconfig.harden_nop_insertion = true; settings.njconfig.harden_function_alignment = true; }
Codebase Alignment Randomization
• Inserting random number of 0xCC (INT3) in front of
JIT function when writing the JITed machine bytes.
• From a minimum 0 to a maximum 0x19.
const int LARGEST_UNDERRUN_PROT = 32; // add some random padding, so functions aren't predictably placed.
if (_config.harden_function_alignment) { int32_t pad = _noise->getValue(LARGEST_UNDERRUN_PROT);
underrunProtect(pad); _nIns -= pad; VMPI_memset(_nIns, INT3_OP, pad); PERFM_NVPROF("hardening:func-align", pad); }
Instruction Alignment Randomization
• Inserting an “NOP” instruction for every 0x80-0x47F
range (random choice).
• Currently has 5 “NOP” instructions: • 8B C0 mov eax, eax • 8B FF mov edi, edi • 8B C9 mov ecx, ecx • 8D 09 lea ecx, [ecx] • 8D 24 24 lea esp, [esp]
• Note: for function length less than 0x80, no
“NOP” ins inserted.
Instruction Alignment Randomization
// if no codeList then we know priorIns and _nIns are on
same page, otherwise make sure priorIns was not in the previous code block
if (!codeList || !codeList->isInBlock(priorIns)) { // sanity check NanoAssert(delta < VMPI_getVMPageSize()); nopInsertTrigger -= (int32_t) delta; if (nopInsertTrigger < 0) { nopInsertTrigger = noiseForNopInsertion(_noise); asm_insert_random_nop(); PERFM_NVPROF("hardening:nop-insert", 1); } }
JIT Harden – Effect
• By implementing the 2 mitigations together, it blocked typical JIT spraying/FengShui attacks.
• Function address isn’t predictable anymore (CAR).
• Function length isn’t controlled anymore (IAR)
• Your shellcode in JIT function will be broken by random “NOP” bytes.
• Even, you can’t guess out any JIT bytes in any JITed address.
Agenda
Flash JIT and Mitigations
Flash ActionScript 3 Architecture
3
2
4 Case Study: Digging Vulnerability Root Cause with Tamarin Source Code
5 Thoughts for Future Flash Security
A Review of Flash Threats 1
Digging Root Cause with Tamarin Source Code
• Tamarin project is the open-sourced AS3 (AVM2) implementation.
• Thus, we can locate the root causes on source code level for Flash AVM2-based vulnerabilities.
• With the source code, we can fully understand the vulnerabilities as well as the exploitations.
• Let’s see a recent real example. Note: The author did a research focusing on the Tamarin project, which is available
at http://recon.cx/2012/schedule/events/210.en.htm.
Background
• On Oct 12, a just-patched (1-day) vuln PoC was dropped on the Internet.
• McAfee Labs released a blog post responding to this threat on Oct 15.
• The CVE-ID of this vuln is CVE-2012-5271 (reported by Google), which was confirmed by Adobe PSIRT.
Analysis
• By comparing the PoC with the sample file, only one opcode’s parameter is changed. Apparently the vuln lies in the AS3 level.
Digging Deep
• declocal r10 ? Hmm.. What’s going on there?
• As we see, “locals:1” means there is only 1 local register that can be used in this function, so only register r0 is available.
• Something seems to be “out of bounds”..
Digging Deep
• Look at the Tamarin source, in the function Verifier::verifyBlock (in verifier.cpp), it reads and verifies parameter(s) of every opcode. • http://hg.mozilla.org/tamarin-
redux/file/f5191c18b0e4/core/Verifier.cpp
• Let’s locate the place where Tamarin handles the declocal opcode.
1279 case OP_inclocal: 1280 case OP_declocal: 1281 { 1282 Traits* retType = NUMBER_TYPE; 1283 bool already_coerced = false; 1284 #ifdef VMCFG_FLOAT 1285 if(pool->hasFloatSupport()) 1286 { 1287 FrameValue& v = checkLocal(imm30); 1288 BuiltinType bt = Traits::getBuiltinType(v.traits); 1289 if(bt == BUILTIN_none || bt == BUILTIN_any || bt == BUILTIN_object) 1290 { 1291 emitCoerceToNumeric(imm30); 1292 retType = OBJECT_TYPE; 1293 already_coerced = true; 1294 } 1295 else if(bt == BUILTIN_float || bt == BUILTIN_float4) 1296 retType = v.traits; 1297 else 1298 retType = NUMBER_TYPE; 1299 } 1300 #endif // VMCFG_FLOAT 1301 if(!already_coerced) 1302 emitCoerce(retType, imm30); 1303 coder->write(state, pc, opcode, retType); 1304 break; 1305 }
Some Facts
• On the released Flash Player, • Flag VMCFG_FLOAT won't be set. • Flag already_coerced won’t be set (setting to
false)
• Therefore, the previous source code will look like this..
1279 case OP_inclocal: 1280 case OP_declocal: 1281 { 1282 Traits* retType = NUMBER_TYPE; 1283 bool already_coerced = false; 1284 #ifdef VMCFG_FLOAT 1285 if(pool->hasFloatSupport()) 1286 { 1287 FrameValue& v = checkLocal(imm30); 1288 BuiltinType bt = Traits::getBuiltinType(v.traits); 1289 if(bt == BUILTIN_none || bt == BUILTIN_any || bt == BUILTIN_object) 1290 { 1291 emitCoerceToNumeric(imm30); 1292 retType = OBJECT_TYPE; 1293 already_coerced = true; 1294 } 1295 else if(bt == BUILTIN_float || bt == BUILTIN_float4) 1296 retType = v.traits; 1297 else 1298 retType = NUMBER_TYPE; 1299 } 1300 #endif // VMCFG_FLOAT 1301 if(!already_coerced) 1302 emitCoerce(retType, imm30); 1303 coder->write(state, pc, opcode, retType); 1304 break; 1305 }
Won’t be executed!
Will be executed!
The Problem
• emitCoerce(retType, imm30) (line 1302) uses imm30 directly without bound checking. • imm30 is actually the parameter value of opcode
declocal/inclocal • When emitCoerce can use arbitrary imm30
values, various code execution situations will arise.
• In fact, there is a typical checkLocal() function, which is designed to perform the bound checking. 1287 FrameValue& v = checkLocal(imm30);
• However, it’s disabled by the VMCFG_FLOAT macro.
1279 case OP_inclocal: 1280 case OP_declocal: 1281 { 1282 Traits* retType = NUMBER_TYPE; 1283 bool already_coerced = false; 1284 #ifdef VMCFG_FLOAT 1285 if(pool->hasFloatSupport()) 1286 { 1287 FrameValue& v = checkLocal(imm30); 1288 BuiltinType bt = Traits::getBuiltinType(v.traits); 1289 if(bt == BUILTIN_none || bt == BUILTIN_any || bt == BUILTIN_object) 1290 { 1291 emitCoerceToNumeric(imm30); 1292 retType = OBJECT_TYPE; 1293 already_coerced = true; 1294 } 1295 else if(bt == BUILTIN_float || bt == BUILTIN_float4) 1296 retType = v.traits; 1297 else 1298 retType = NUMBER_TYPE; 1299 } 1300 #endif // VMCFG_FLOAT 1301 if(!already_coerced) 1302 emitCoerce(retType, imm30); 1303 coder->write(state, pc, opcode, retType); 1304 break; 1305 }
Won’t be executed!
Will be executed!
Thoughts
• The vulnerability is so obvious right now, it exists in the core verification process of AVM2.
• Any Flash version (Win8, Chrome) is affected.
• It’s *so easy* to trigger: • Just give a large value for any declocal or
inclocal opcode.
• So the question is: Why was this simple vuln just discovered? Isn’t a good question? • You know, so many researchers are fuzzing
Flash every day. • Plus thousands of Google fuzzing machines*..
* http://googleonlinesecurity.blogspot.in/2011/08/fuzzing-at-scale.html
Digging in the Revisions
• A reasonable answer could be that this vuln was introduced not soon.
• The Tamarin-redux source code also records every historical change of the AVM2 implementation.
• Let’s find out!
checkLocal(imm30) was being moved from the beginning of the branch to the macro block, which won’t be executed! This move actually introduced the vuln!
Change 9e138314d408
• "author Virgil Palanciuc <[email protected]> Wed Nov 09 18:44:25 2011 +0200 (at Wed Nov 09
18:44:25 2011 +0200)“
• The vulnerability was introduced in Tamarin on November 9, 2011.
• Real tests show that the vuln was introduced from Flash Player 11.3.300.257, which was released on June 8, 2012. • 11.3.300.257 is the 1st publicly-released 11.3
version.
Some Interesting Points
• 7 months later, Adobe compiled Tamarin source code on its released Flash Player.
• Adobe will rebuild Tamarin source code for released Flash Player from each secondary-major version. • 11.3.300.257 is the 1st version number of 11.3 • Needs to be confirmed though..
• Therefore, ppl may monitor and review Tamarin
source code to find vulns. And wait for the next secondary-major version to be released to obtain real Flash vulns.
Agenda
Flash JIT and Mitigations
Flash ActionScript 3 Architecture
3
2
4 Case Study: Digging Vulnerability Root Cause with Tamarin Source Code
5 Thoughts for Future Flash Security
A Review of Flash Threats 1
Current Flash Security Landscape
• Killing Flash vulnerabilities: • Enterprise-level fuzzings are performed every day
(Google/Adobe/MS guys). • MS/Google have their own integrated Flash Player
(Win8/PepperFlash) so they are actively helping improve Flash security.
• Mitigating Flash exploits: • JIT Harden (discussed previously). • Sandboxing Flash (PepperFlash on Chrome).
• Sandboxing is useful for mitigating Flash JIT attacks as each Flash content runs as standalone process.
Future – Bug Hunting
• We will continue to see bugs from formats like: • Font/pic/video • AMF (Action Message Format)
• AVM2-based vulns have already declined (good thing, as they are highly dangerous).
• Vulnerabilities in legacy code (eg: AVM1)
AS3 Native API
• Also known as “public class”
AS3 Native API
• Vulns in the implementation of Flash ActionScript 3 Native APIs.
• File-format fuzzing won’t find such bugs as they sit at the script level. • Just like you find bugs in IE DHTML.
• Could be a big place to produce vulns, a lot of
APIs need to test/review. • hmm, they are not open-sourced.
AS3 Native API
• Actually, we have seen an increase number of Native API bugs this year, just some examples: • CVE-2012-0768, Matrix3D, Tavis Ormandy, Google • CVE-2012-0769, BitmapData, Fermin J. Serna, Google • CVE-2012-0773, NetStream, anonymous via ZDI • CVE-2012-2036, Haifei Li, Microsoft • CVE-2012-5054, Matrix3D, N/A • Plus many more were killed by Google researchers’
fuzzing effort on Flash
• Fuzzing in Native APIs • Tavis Ormandy ported the idea of browser
reference fuzzing on Flash years ago • Full API coverage & improvement make it really
powerful
Reference Fuzzing!
• Credit to Tavis Ormandy’s ReferenceFuzzer.
Future – Exploitation
• JIT Harden is strong, but not strong enough.
• The custom heap management(s) of Flash Player could be helpful for specific advanced exploitation. • No harden there, so weak.
• It’s always good to review the deep features in the
AVM2 implementation • The features could be used for advanced
exploitation. • Highlighted at CanSecWest 2011 for AS3 type
confusion bugs.
McAfee/RIM Confidential
Questions?
Thanks to XiaoBo Chen, Bing Sun, Dan Sommer, Jun Xie and Chong Xu of McAfee Labs