ASafety - AntiSecurity Un projet qui vous tiendra @coeur...

Analyse détaillée d'un SWF infecté

Questions, réponses, sujets divers, news et informations

Sujets en relation avec cet article

ASBot
 

Analyse détaillée d'un SWF infecté

Message non lude x[@♥] » Ven 13 Aoû 2010 08:43

Episode 4: Attack of the killer videos

Pour continuer dans, maintenant, la quadrilogie de Sergei Shevchenko, voici son dernier article sur l'analyse complète d'une corruption de mémoire via un SWF. Vraiment jolie et bien expliqué.

Image

"Have you broken the computer again? It won't play this video of the new iPhone!" It's been a long day and I don't really feel like troubleshooting, but when she gets into this sort of mood, the administrator had better jump to it. And at home, the administrator is me.

Somehow I have my doubts that the origin of this problem is to be found on our PC. Maybe it's the video that's broken. In the source code of the still open web site, there's a <Object> tag containing a link to an SWF file – a video in the Shockwave Flash format which has come to dominate the internet. The URL looks more than a little strange – smelling a rat I download it onto my computer for a closer look.

At 846 bytes, it's pretty small for an SWF file – you certainly can't fit anything meaningful into that. Although it's a multimedia file, as ever I start by taking a quick look with a hex editor. Any strings, especially where you'd expect to see just incomprehensible raw data, can provide useful clues.



I hit the jackpot – what's a reference to Windows library urlmon.dll doing in a Flash file? This, together with the URL and a file name 'c:\6123t.exe', both of which the hex editor also unmasks, tells pretty much the whole story – or at least it does once you have some experience of analysing malware.

My tiredness is gone; I'm determined to get to the bottom of this. From previous experiments with Flash, I recall getting good mileage out of SWFTools. It doesn't let me down. The command

Code: Tout sélectionner
swfdump -D -d -u exploit.swf


tells me right away that we're looking at a file in Flash 9 format – the current version is version 10. Not that that's necessarily particularly significant; Flash is backwards-compatible and version 9 is still in widespread use. This is followed by tags containing the actual content. Further down, I see that the reference to the library is part of a block designated DEFINEBITSJPEG. JPEG? as if!

My attention is drawn to the next two data blocks:

Code: Tout sélectionner
[056] 40 SCENEDESCRIPTION
  => 99 b4 8e a0 08 20 20 20 20 20 20 20 20 20 20 20
  => 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
  => 20 20 20 20 20 20 20 43
[056] 12 SCENEDESCRIPTION
  => 01 00 e5 9c ba e6 99 af 20 31 00 00


A SCENEDESCRIPTION consisting of a load of 0x20 characters? The data type 0x56 – decimal 86 – doesn't ring any bells, so I pull up a description of the SWF file formatPDF which Adobe has kindly made publicly available. Type 86 stands for DefineSceneAndFrameLabelData and contains "Scene and frame label data for a MovieClip". So we have administrative information for a Flash clip consisting primarily of 0x20 characters. Like, sure. I'm onto something – let's take a closer look.

According to the specification, the first two bytes of the data block represent the RECORDHEADER. Reading the definition of this data type makes my hair stand on end. Why these cheapskates want to save a couple of admin bits for chunks of data that have long been measured in megabytes is a mystery to me. The upper 10 bits contain the tag type – here it should be 0x56 – and the remaining 6 bits its length.

Because additionally you have to consider the little endian byte order of Intel's architecture, which means that high value bytes are at the back, I have to write it down.



According to this, the RECORDHEADERs yield the data blocks A8 15 and 8C 15; in each case the 0x56 tag type given by swfdump and a length of 40 and 12 respectively. So far, so good. This is followed by the number of scenes as an EncodedU32 data type

What on earth were they thinking of? The specification reads like something from the last millennium. EncodedU32 contains an unsigned 32 bit integer which, depending on its size, is encoded using a variable number of between one to five bytes – "to save space", as Adobe's spec kindly explains.

No wonder Flash security vulnerabilities seem to be never-ending. Instead of working with normal data types such as unsigned int, they have to try to save a couple of bytes. But complexity is famously the enemy of security – and this just screams 'trouble'. Just imagine if the designer of formats for .exe files or CPU commands had used this kind of data type. We'd be drowning in security vulnerabilities.

It's also slow, as each time an EncodedU32 value is accessed, instead of a simple read operation, the decoder routine has to be run. This skimping on bits becomes even more incomprehensible when you think that SWF files can be compressed – a much more efficient way of saving space.

But I'm starting to rant – back to the supposed iPhone video's SceneCount. If the highest bit of a byte is set, the next byte has to be added in. A glance at the hex dump tells me that the first four data blocks after the RECORDHEADER all have the highest byte set. So I have to correctly add together the maximum five bytes. Adobe helpfully provides a reference implementation for unpacking EncodedU32 value in C. Rather than shovelling bits about by hand, I quickly run it through the compiler.



Checking out the second, shorter data block with GetEncodedU32.exe yields a perfectly plausible SceneCount of 1. But for the first data block, it coughs up a value of 0x84039a19 for \xa6\xe1\x8a\xa0\x08. More than 2 billion scenes? That's impossible. My hunch was right. Someone's pulling a fast one.

It doesn't take much searching before I come across Mark Dowd's pioneering Leveraging the ActionScript Virtual MachinePDF paper. It uses exactly this problem as an example. I can remember the excitement in the security community when this exploit was published, but I can't quite remember what it was all about. "Can I use the computer?" comes a voice from behind me. "Just a minute! I just need to finish up. I'm almost done."

Back to Dowd's Flash exploit. Adobe's Flash implementation uses SceneCount to reserve memory. To prevent any mischief, it carries out some verification before doing so. But in doing so, Adobe uses a signed "greater than" comparison. And because the highest bit – the 'sign bit' – of the EncodedU32 value 0x84039a19 is set, this yields a negative value.

As a result, the check doesn't do what it's supposed to and the Flash interpreter tries to reserve memory with the value from SceneCount – which of course fails. The program, however, does not realise this and uses the null pointer, intended to indicate an error, anyway. Boom!

But it's not quite as simple as all that. For a long time it was thought that this kind of bug would simply cause the program to crash and could not be exploited to execute injected code in a controlled manner. Mark Dowd used this example to show that it is indeed possible. Highly simplified, it works like this: a little later, the Flash interpreter writes a value which can be selected by the attacker to the address 0+SceneCount. By using a suitable value for SceneCount coupled with the malformed Action Script byte stream, the attacker can overwrite an address pointer for a jump or call instruction such that his injected code is activated.

Normal stability tests will rarely detect this kind of security problem. The developer is in a similar position to that of an engineer calculating the load-bearing capacity of a bridge. The engineer determines that the bridge should easily be able to take one hundred people, but neglects to consider that 100 marching soldiers, will march over the bridge in step and hit the bridge's resonant frequency. The vibration is steadily amplified until the bridge collapses. Resonance disasters like this did in fact cause the collapse of two bridges in France and England in the 19th century, with significant loss of life.

In fact software developers have it even harder – they have to assume that the bad guys will deliberately jump up-and-down, adjusting their rhythm until they find the critical frequency. Then they'll go on doing it until the bridge collapses – or, to return to reality, until their manipulated movie clip causes a remote code execution.

Talking of code reminds me of the DEFINEBITSJPEG tag, which contains the reference to urlmon.dll, the URL and the strange file name.

I've arrived at a theory – the SceneCount exploit aims to get the program to jump to the middle of the JPEG image and execute the code concealed there.

Crikey! It's a quarter to two already – but I'll get no peace until I get to the bottom of this. So if this is code, a disassembler should be able to interpret and display it as such. I extract the 336 bytes of the data block into a file and fire up IDA Pro. This should work even with the free version installed on this computer.

On opening the file, IDA starts by complaining that it has been unable to find a valid PE header. It is consequently missing the entry point defined in the header which tells it where the actual code starts, so that it doesn't know where to start disassembling. I tell it myself, place the cursor on the first data byte – the 0xAA – and press 'C'.



Bingo – we've hit shellcode. The chances of getting something so obviously meaningful when disassembling pure data is pretty slim. There's a bit of garbage at the start, but then there's a short NOP slide. The exploit's author either needed to fill a few bytes to reach a specific block limit or he wasn't quite sure exactly where his circuitous jump would land.

What follows is unmistakeable – FS:30 code for determining the base address of kernel32.dll (see also The image of death). The leading XOR and the attempt to access ecx+30h prevent it from being detected by simple signatures which are triggered by any reference to FS:30h. The code then works its way through the kernel32.dll export table to determine the relative virtual addresses (RVAs) of various functions recorded there.

In doing so, the author makes use of a popular ruse – rather than searching for the name of a function in plain text, he generates hash values from the names in the export table and compares these with a stored hash value. If the two are the same, he has found one of the functions he's looking for.

This hash comparison is, first and foremost, more compact than a string comparison. Space can be at a premium in shellcode – it's not uncommon for the properties of a security vulnerability to limit the number of bytes available for exploit code. Secondly, it also avoids filling the shellcode with tell-tale strings, thus reducing the risk of discovery.

The shellcode in our Flash clip sniffs out kernel32.dll->LoadLibrary(), kernel32.dll->WinExec() and urlmon.dll->URLDownloadToFile() and then continues on its dastardly way, probably downloading and installing spyware or a bot from the web.

On this occasion it has failed, as the exploit only works on older versions of Flash containing this security vulnerability. I check about:plugins in Firefox to reassure myself that I'm running the latest Flash plug-in. Naturally there was nothing to see in the purported video. But as I turn round to explain it all to her, I realise that she went to bed hours ago.


Un véritable bijoux! J'ai particulièrement apprécié l'annalogie avec le phénomène de résonnance pour les jump & call.

Je rajoute aussi le lsien du PDF dont il parle, un PDF sur les corruptions de mémoire des SWF notamment. Écrit par IBM, une référence!

Article ici!

PDF de IBM ici!

:hat:
Temp...
Avatar de l’utilisateur
x[@♥]
 
Messages: 1115
Inscription: Lun 21 Sep 2009 15:21
Localisation: Sur la root

Retourner vers Discussions



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité

cron